./data war ein Bind-Mount relativ zum Git-Checkout - bei Dokploy wird das Repo pro Deploy frisch geklont, ein per CLI angelegter Nutzer war nach einem reinen Routing-Redeploy spurlos verschwunden. Betraf nicht nur Nutzer, sondern denselben Api:DataPath für Ereignis-Log/Snapshots/ Anhänge - also jeden Server-Datenbestand bei jedem Redeploy. - docker-compose.yml: Named Volume "api-data" statt Bind-Mount, lebt unabhängig vom Checkout im Docker-Daemon. - backup.sh: auf volume-basiertes Backup umgeschrieben (Alpine- Hilfscontainer statt direktem Host-Pfad). - docker/README.md, TODO.md 10.2.4: Vorfall dokumentiert. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
4.4 KiB
LehrerApp.Api – Deployment per Docker
Starten
cd docker
JWT_SECRET=<zufälliger-langer-string> docker compose up -d
Alle Server-Daten (Ereignis-Logs, Snapshots, Anhänge, Nutzer) liegen im Named Volume api-data –
bei Neustarts/Updates bleibt es erhalten. Bewusst kein Bind-Mount auf einen Host-Pfad: bei
Git-basierten Deployments (z. B. Dokploy) wird das Checkout-Verzeichnis bei jedem Redeploy neu
geklont, ein dort liegendes ./data wäre dabei jedes Mal leer (siehe TODO.md 10.2.4 für den
Vorfall, der das aufgedeckt hat).
Nutzer anlegen
Es gibt keine offene Registrierung (/api/auth/register). Neue Nutzer werden per CLI im
laufenden Container angelegt:
docker compose exec api dotnet LehrerApp.Api.dll create-user <benutzername>
Fragt interaktiv nach einem Passwort (mind. 12 Zeichen). Alternativ nicht-interaktiv, z. B. aus einem Skript:
docker compose exec api dotnet LehrerApp.Api.dll create-user <benutzername> --password "<passwort>"
Der Befehl beendet sich danach sofort wieder, ohne den API-Dienst zu starten – für den
eigentlichen Serverbetrieb läuft docker compose up unverändert weiter.
Passwort zurücksetzen
Analog zu create-user, aber für einen bereits existierenden Nutzer (schlägt fehl, wenn der
Nutzer nicht existiert – zum Anlegen create-user verwenden):
docker compose exec api dotnet LehrerApp.Api.dll set-password <benutzername>
docker compose exec api dotnet LehrerApp.Api.dll set-password <benutzername> --password "<passwort>"
Backup
backup.sh sichert das Named Volume api-data (Ereignis-Logs, Snapshots, Anhänge, Nutzer) über
einen kurzlebigen Alpine-Container als komprimiertes Tar-Archiv unter docker/backups/ und räumt
Archive älter als 30 Tage automatisch auf:
./docker/backup.sh
Der volle Docker-Volume-Name ist <compose-projektname>_api-data. Lokal (cd docker && docker compose up) ist das docker_api-data (Default im Skript), bei Dokploy der App-Slug, z. B.
lehrerapp-syncserver-xyz_api-data – im Zweifel prüfen mit docker volume ls | grep api-data
und per Umgebungsvariable übergeben:
LEHRERAPP_DATA_VOLUME=lehrerapp-syncserver-xyz_api-data ./docker/backup.sh
Für regelmäßige Sicherung z. B. per Cron, einmal täglich nachts:
0 3 * * * LEHRERAPP_DATA_VOLUME=... /pfad/zu/docker/backup.sh >> /pfad/zu/docker/backup.log 2>&1
Rate Limiting
/api/auth/login ist auf 5 Versuche pro Minute begrenzt (Brute-Force-Schutz). Alle übrigen
Endpunkte sind zusätzlich global auf 120 Anfragen pro Minute je IP begrenzt. Anhänge sind auf
15 MB Anfragegröße gedeckelt (Kestrel MaxRequestBodySize), einzelne Dateien clientseitig
zusätzlich auf 10 MB (IAttachmentStorage.MaxSizeBytes).
Deployment über Dokploy
Kein manuelles Bauen/Hochladen nötig – Dokploy zieht das Repo direkt per Git und baut das Image
selbst aus docker/Dockerfile.api.
- Neue Compose-Application anlegen, Quelle „Git" (Custom Git Provider), Repo-URL
https://git.science-teaching.de/admin/LehrerApp.git, Branchmain. Bei privatem Repo einen SSH-Deploy-Key in Dokploy hinterlegen und im Git-Server eintragen. - Compose Path:
docker/docker-compose.yml. Der Build-Context (context: ..) und das Dockerfile sind darin bereits korrekt referenziert – Dokploy checkt das ganze Repo aus, das passt ohne Anpassung. - Umgebungsvariable
JWT_SECRETim Dokploy-UI unter „Environment" setzen (nicht als.enveinchecken) – wird als${JWT_SECRET}in die Compose-Datei injiziert, wie beim lokalen Start. - Domain/Port: Domain auf Container-Port
5000mappen, HTTPS über Dokploys eingebauten Reverse-Proxy aktivieren. - Auto-Deploy: Webhook-URL aus Dokploy als Push-Hook im Git-Server eintragen (falls
unterstützt, z. B. Gitea) – dann löst jeder
git pushautomatisch ein Rebuild aus. - Nutzer anlegen nach dem ersten Deploy: über Dokploys Terminal/Exec-Tab am laufenden
Container
dotnet LehrerApp.Api.dll create-user <name>ausführen (siehe oben).
Wichtig: die Daten liegen im Named Volume api-data, nicht in einem Bind-Mount – Dokploy
klont das Repo bei jedem Redeploy neu, ein Bind-Mount relativ zum Checkout wäre dabei jedes Mal
leer gewesen (das ist real passiert, siehe TODO.md 10.2.4). Named Volumes übersteht Dokploys
docker compose up --build --remove-orphans dagegen unverändert.