feat(ops): Automatisches Backup (DB + Dateien, 30 Tage) (v1.8.11)

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>
This commit is contained in:
Pepe Ziberi
2026-07-23 22:39:03 +02:00
parent e5811f03fb
commit 15dd78c848
7 changed files with 226 additions and 3 deletions

44
scripts/restore.sh Normal file
View File

@@ -0,0 +1,44 @@
#!/bin/sh
# =============================================================
# Lageplan Restore-Helfer
# =============================================================
# Stellt einen Datenbank-Dump (und optional die Dateien) wieder her.
# ACHTUNG: Der DB-Restore ist DESTRUKTIV bestehende Daten werden ersetzt.
# Vorher die Web-App stoppen und sicherstellen, dass niemand arbeitet.
#
# Verwendung (auf dem Server, im Verzeichnis mit der docker-compose.yml):
#
# 1) Verfügbare Backups anzeigen:
# docker compose exec backup ls -lh /backups
#
# 2) Datenbank wiederherstellen (Dateiname aus Schritt 1):
# docker compose exec backup sh /scripts/restore.sh db_2026-07-23_030000.dump
# (funktioniert nur, wenn dieses Verzeichnis in den backup-Container gemountet ist;
# sonst den Befehl aus dem Abschnitt "Ohne Skript" in docs/BACKUP.md nutzen.)
#
# 3) Dateien (Uploads) wiederherstellen: siehe docs/BACKUP.md
# =============================================================
set -eu
DUMP="${1:-}"
BACKUP_DIR="${BACKUP_DIR:-/backups}"
PGHOST="${PGHOST:-db}"
PGUSER="${PGUSER:-lageplan}"
PGDATABASE="${PGDATABASE:-lageplan}"
if [ -z "$DUMP" ]; then
echo "Verwendung: restore.sh <db_dumpfile>"
echo "Verfuegbare Dumps in $BACKUP_DIR:"
ls -1 "$BACKUP_DIR"/db_*.dump 2>/dev/null || echo " (keine gefunden)"
exit 1
fi
FILE="$BACKUP_DIR/$DUMP"
[ -f "$FILE" ] || { echo "Nicht gefunden: $FILE"; exit 1; }
echo "!! DESTRUKTIV: Stelle '$DUMP' in Datenbank '$PGDATABASE' auf Host '$PGHOST' wieder her."
echo " Bestehende Daten werden ersetzt. Abbruch mit Ctrl+C, weiter mit Enter."
read -r _
pg_restore --clean --if-exists --no-owner -h "$PGHOST" -U "$PGUSER" -d "$PGDATABASE" "$FILE"
echo "[restore] Datenbank wiederhergestellt aus $DUMP"