Schliesst den offenen Punkt: die Datenschutzerklärung nannte "bis zu 30 Tage", real fehlte ein Backup. - Neuer backup-Container (postgres:16-alpine) in docker-compose.yml und deploy/portainer-stack.yml: täglich pg_dump (custom/komprimiert) + tar der MinIO-Dateien, Prune > 30 Tage, im Volume backups_data - Konfigurierbar: BACKUP_RETENTION_DAYS, BACKUP_INTERVAL_HOURS (.env.example ergänzt) - scripts/restore.sh + docs/BACKUP.md (Einrichtung, Off-Site-Hinweis, Restore DB+Dateien, Restore-Test-Tabelle) - TOM-Doku aktualisiert (Backup vorhanden) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3.0 KiB
Backup & Restore — Lageplan
Automatisches Backup als eigener Container (backup). Sichert täglich:
- Datenbank (PostgreSQL) →
db_<zeitstempel>.dump(pg_dump, custom/komprimiert) - Hochgeladene Dateien (MinIO: Pläne, Logos, Symbole) →
files_<zeitstempel>.tar.gz
Aufbewahrung: 30 Tage (ältere werden automatisch gelöscht) — passt zur Datenschutzerklärung.
Einstellbar über BACKUP_RETENTION_DAYS und BACKUP_INTERVAL_HOURS (siehe .env.example).
Die Backups liegen im Docker-Volume backups_data (Pfad im Container: /backups).
Einrichtung
Der backup-Service ist in docker-compose.yml und deploy/portainer-stack.yml enthalten.
Nach dem nächsten Stack-Update (Portainer: Stack neu deployen) läuft er automatisch.
Prüfen, dass er läuft und sichert:
docker logs lageplan-backup # oder: docker compose logs backup
docker compose exec backup ls -lh /backups
Beim ersten Start wird sofort ein Backup erstellt, danach alle 24 h.
Empfehlung: Backups aus dem Container heraus auf den NAS legen (Off-Site)
Standardmässig liegen die Backups in einem Docker-Volume. Damit sie ausserhalb von Docker
(z. B. auf einer NAS-Freigabe, die du separat sicherst) landen, im Stack den backup-Service auf
einen Host-Pfad umstellen:
volumes:
- /volume1/backups/lageplan:/backups # statt backups_data:/backups
- minio_data:/minio:ro
So kannst du die Dateien einfach kopieren/auf ein anderes Medium spiegeln. Wichtig: Ein Backup auf demselben Gerät wie die Daten schützt nicht vor Geräteausfall/Diebstahl — kopiere die Backups regelmässig an einen zweiten Ort.
Wiederherstellen (Restore)
Destruktiv. Vorher die Web-App stoppen (
docker stop lageplan-web) und sicherstellen, dass niemand arbeitet.
1) Datenbank
# Verfügbare Dumps anzeigen
docker compose exec backup ls -lh /backups
# Wiederherstellen (Dateiname einsetzen)
docker compose exec backup pg_restore --clean --if-exists --no-owner \
-h db -U <POSTGRES_USER> -d <POSTGRES_DB> /backups/db_2026-07-23_030000.dump
2) Dateien (Uploads/MinIO)
Da /minio im backup-Container schreibgeschützt ist, den Tarball in einen Container mit
Schreibzugriff auf das MinIO-Volume entpacken:
docker run --rm -v minio_data:/data -v backups_data:/backups alpine \
sh -c "tar xzf /backups/files_2026-07-23_030000.tar.gz -C /data"
Danach Web-App wieder starten: docker start lageplan-web.
Restore-Test (mindestens 1× durchführen und hier notieren)
Ein Backup ist erst dann ein Backup, wenn ein Restore nachweislich funktioniert. Empfehlung: halbjährlich auf einer Testumgebung durchspielen.
| Datum | Getestet von | Ergebnis | Bemerkung |
|---|---|---|---|
Was ist NICHT im Backup?
- Zahlungsdaten liegen bei Stripe (nicht in der App).
- E-Mails liegen beim SMTP-Anbieter.
- Secrets (
NEXTAUTH_SECRET, MinIO-Keys) — separat sicher aufbewahren (Passwort-Manager), sie stehen nicht in den Backups.