Schulwirken in 10 Minuten einrichten
Schulwirken läuft als Docker-Container auf jedem Linux-Server. Du brauchst keine .NET-Kenntnisse - nur Docker und einen Lizenzkey. Wie die App bedient wird, steht in der Hilfe.
Voraussetzungen
- Linux-Server (Ubuntu 22.04 oder neuer empfohlen)
- Docker ≥ 24 und Docker Compose ≥ 2
- Rund 1,5 GB freier Speicher für das App-Image (es enthält LibreOffice für die Vorschau von Word-, PowerPoint- und Excel-Dateien)
- Einen gültigen Schulwirken-Lizenzkey (hier kaufen)
- Eine Domain, die auf deinen Server zeigt
- Einen SMTP-Zugang für den E-Mail-Versand (Einladungen)
Installation
Arbeitsverzeichnis anlegen
mkdir schulwirken && cd schulwirken
docker-compose.yml anlegen
Erstelle eine Datei docker-compose.yml mit folgendem Inhalt:
services:
app:
image: ghcr.io/daniel-kinas/schulwirken-web-selfhosted:latest
container_name: schulwirken-app
restart: unless-stopped
ports:
- "127.0.0.1:8080:8080"
environment:
- App__LicenseKey=${LICENSE_KEY}
- App__BaseUrl=${BASE_URL}
- App__SchoolName=${SCHOOL_NAME:-Meine Schule}
- App__AdminEmail=${ADMIN_EMAIL:-admin@schulwirken.local}
- App__AdminPassword=${ADMIN_PASSWORD:-}
- ConnectionStrings__Default=Server=db;Database=schulwirken;User=root;Password=${DB_PASSWORD}
- Jwt__Key=${JWT_KEY}
- Email__Host=${EMAIL_HOST}
- Email__Port=${EMAIL_PORT:-587}
- Email__Username=${EMAIL_USERNAME}
- Email__Password=${EMAIL_PASSWORD}
- Email__FromAddress=${EMAIL_FROM_ADDRESS}
- Email__FromName=${EMAIL_FROM_NAME:-Schulwirken}
- Push__PublicKey=${PUSH_PUBLIC_KEY}
- Push__PrivateKey=${PUSH_PRIVATE_KEY}
- Push__Subject=${PUSH_SUBJECT:-mailto:admin@example.com}
volumes:
- schulwirken_uploads:/app/wwwroot/uniformen
- schulwirken_logs:/app/logs
depends_on:
db:
condition: service_healthy
db:
image: mysql:8.4
container_name: schulwirken-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
MYSQL_DATABASE: schulwirken
volumes:
- mysql_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-p${DB_PASSWORD}"]
interval: 10s
timeout: 5s
retries: 10
volumes:
mysql_data:
schulwirken_uploads:
schulwirken_logs:
Konfiguration
Lege eine .env-Datei im selben Verzeichnis wie die docker-compose.yml an:
# Lizenzkey (erhalten nach Kauf)
LICENSE_KEY=XXXX-XXXX-XXXX-XXXX
# Deine Domain (mit https://)
BASE_URL=https://schule.meinedomain.de
# Datenbankpasswort (sicheres Passwort wählen)
DB_PASSWORD=sicheres-passwort-hier
# JWT-Schlüssel (mindestens 32 zufällige Zeichen)
JWT_KEY=ersetze-mit-mind-32-zeichen-langem-key
# ── Erststart: Admin-Konto & Schulname ────────────────────
# Nur beim ersten Start verwendet. Danach kann das Passwort
# unter “Mein Profil” geändert werden.
SCHOOL_NAME=Grundschule Musterstadt
ADMIN_EMAIL=schulleitung@muster.de
# Empfohlen: eigenes Passwort setzen. Wenn leer, wird beim
# ersten Start ein Passwort generiert und in initial-admin.txt
# im Container-Arbeitsverzeichnis gespeichert.
ADMIN_PASSWORD=sicheres-admin-passwort
# ── E-Mail (für Einladungen an Nutzer) ──────────────────
EMAIL_HOST=smtp.meinprovider.de
EMAIL_PORT=587
EMAIL_USERNAME=noreply@meinedomain.de
EMAIL_PASSWORD=email-passwort
EMAIL_FROM_ADDRESS=noreply@meinedomain.de
EMAIL_FROM_NAME=Schulwirken
# ── Push-Benachrichtigungen (Chat, optional) ─────────────────
# VAPID-Schlüsselpaar für Browser-/Handy-Push bei neuen
# Chat-Nachrichten. Leer lassen = Push deaktiviert (Chat
# funktioniert trotzdem). Erzeugen siehe Hinweis unten.
PUSH_PUBLIC_KEY=
PUSH_PRIVATE_KEY=
PUSH_SUBJECT=mailto:schulleitung@muster.de
Den JWT-Schlüssel kannst du so generieren:
openssl rand -base64 32
E-Mail-Pflicht: Schulwirken versendet Einladungslinks per E-Mail, wenn du neue Nutzer hinzufügst. Ohne gültige SMTP-Konfiguration können keine Nutzer eingeladen werden.
Push-Benachrichtigungen (optional)
Damit Nutzer bei neuen Chat-Nachrichten eine Browser- bzw. Handy-Benachrichtigung erhalten - auch bei geschlossenem Tab - brauchst du ein VAPID-Schlüsselpaar. Erzeuge es einmalig, z. B. mit Node:
npx web-push generate-vapid-keys
Trage den Public Key in PUSH_PUBLIC_KEY und den
Private Key in PUSH_PRIVATE_KEY ein. PUSH_SUBJECT
ist eine Kontakt-Adresse im Format mailto:deine@adresse.de.
Hinweise: Push funktioniert nur über https:// (deine
BASE_URL sollte also TLS nutzen). Lässt du die Schlüssel leer,
ist Push einfach deaktiviert - der Chat selbst bleibt voll funktionsfähig.
Den privaten Schlüssel niemals weitergeben. Unabhängig davon verschickt
Schulwirken bei länger ungelesenen Chat-Nachrichten (ab 4 Stunden) eine
Erinnerungs-E-Mail - dafür genügt die SMTP-Konfiguration oben.
Lizenzkey aktivieren
Schulwirken prüft beim Start automatisch deinen Lizenzkey gegen
license.schulwirken.de. Der Key wird an deine Domain gebunden -
du musst nichts weiter tun.
Läuft die Lizenz ab, wechselt die App in den Lesezugriff-Modus. Du kannst die Lizenz jederzeit unter Preise verlängern.
Bezahlung auf Rechnung: Schulwirken wird per Rechnung mit Überweisung bezahlt (14 Tage Zahlungsziel). Keine Kreditkarte nötig. Die Aktivierung erfolgt nach Zahlungseingang. Vor Ablauf erinnert dich Schulwirken automatisch per Mail (30 / 14 / 0 Tage).
App starten
docker compose up -d
Beim ersten Start wird die Datenbank automatisch angelegt und alle Migrationen eingespielt. Das dauert einige Sekunden.
Logs ansehen:
docker compose logs -f app
Die App läuft auf Port 8080.
Erster Login
Nach dem Start erreichst du Schulwirken unter deiner konfigurierten
BASE_URL (oder zunächst über http://server-ip:8080).
Beim ersten Start wird automatisch ein Admin-Konto angelegt.
Hast du ADMIN_PASSWORD in der .env gesetzt, verwendest du dieses direkt.
Ohne ADMIN_PASSWORD wird ein Zufalls-Passwort generiert und in der Datei
initial-admin.txt im Arbeitsverzeichnis des Containers gespeichert:
docker compose exec app cat initial-admin.txt
Bitte lösche die Datei nach dem ersten Login:
docker compose exec app rm initial-admin.txt
Das Passwort kann anschließend jederzeit unter Mein Profil geändert werden.
Weitere Nutzer lädst du danach unter Verwaltung → Benutzer ein. Welche Rolle was darf, steht unter Benutzer & Rollen.
Updates einspielen
Schulwirken-Updates werden als neue Docker-Images veröffentlicht. Einspielen:
docker compose pull
docker compose up -d
Datenbank-Migrationen laufen beim App-Start automatisch.
Deine Daten bleiben im benannten Volume mysql_data erhalten.
Reverse Proxy (HTTPS)
Schulwirken lauscht auf Port 8080. Stelle einen Reverse Proxy davor,
der HTTPS terminiert.
Nginx
server {
listen 443 ssl;
server_name schule.meinedomain.de;
ssl_certificate /etc/letsencrypt/live/schule.meinedomain.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/schule.meinedomain.de/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}
Backup
Datenbank
# Backup erstellen
docker compose exec db mysqldump -u root -p"$DB_PASSWORD" schulwirken \
> backup_$(date +%Y%m%d).sql
# Backup einspielen
docker compose exec -T db mysql -u root -p"$DB_PASSWORD" schulwirken \
< backup_20250101.sql
Hochgeladene Dateien (Schulkleidungs-Katalog)
Bilder aus dem Schulkleidungs-Katalog werden im Docker-Volume schulwirken_uploads
gespeichert und überleben Neustarts und Updates. Für ein vollständiges Backup
solltest du dieses Volume zusätzlich sichern:
# Uploads-Volume sichern
docker run --rm \
-v schulwirken_uploads:/data \
-v "$(pwd)":/backup \
busybox tar czf /backup/uploads_$(date +%Y%m%d).tar.gz -C /data .
# Uploads-Volume wiederherstellen
docker run --rm \
-v schulwirken_uploads:/data \
-v "$(pwd)":/backup \
busybox tar xzf /backup/uploads_20250101.tar.gz -C /data
Dokumente-Ablage (Add-on)
Hochgeladene Dokumente liegen, wenn das Add-on gebucht ist, im eigenen Docker-Volume
schulwirken_documents - getrennt vom Uploads-Volume, damit ein
Restore des einen nicht versehentlich das andere überschreibt:
# Dokumente-Volume sichern
docker run --rm \
-v schulwirken_documents:/data \
-v "$(pwd)":/backup \
busybox tar czf /backup/dokumente_$(date +%Y%m%d).tar.gz -C /data .
# Dokumente-Volume wiederherstellen
docker run --rm \
-v schulwirken_documents:/data \
-v "$(pwd)":/backup \
busybox tar xzf /backup/dokumente_20250101.tar.gz -C /data
Troubleshooting
Die App startet nicht
docker compose logs app. Häufige Ursachen:
falscher DB_PASSWORD, MySQL noch nicht bereit (kurz warten und erneut starten),
oder ungültiger JWT_KEY.
Wo finde ich die Anwendungs-Logs?
docker compose logs -f app.
Das vollständige Log mit allen Meldungen schreibt die App als rollende Tagesdateien nach
/app/logs im Container.
Dieses Verzeichnis liegt im Docker-Volume schulwirken_logs und
überdauert Neustarts und Updates. Auf den Host kopieren z. B. mit
docker compose cp app:/app/logs ./logs. Alte Dateien werden automatisch nach
31 Tagen aufgeräumt (anpassbar über Logging__RetainedFileCountLimit).
Einladungs-E-Mails kommen nicht an
.env: Host, Port (meist 587 für STARTTLS),
Benutzername und Passwort. Viele Provider erfordern App-Passwörter statt des normalen Passworts.
Logs: docker compose logs app | grep -i mail.
Lizenz ungültig / Lesezugriff-Modus
LICENSE_KEY und BASE_URL in der .env
korrekt sind. Der Server muss ausgehende HTTPS-Verbindungen zu
license.schulwirken.de erlauben.
Port 8080 ist bereits belegt
docker-compose.yml den Host-Port:
- "127.0.0.1:8081:8080" und passe deinen Reverse Proxy entsprechend an.
Fragen zur Bedienung (Passwort vergessen, Eltern sehen etwas nicht) beantwortet die Hilfe.
Weitere Fragen? Schreib uns an hallo@schulwirken.de.