Das dokumentierte Backup lief real nie (stock postgres-Image ohne Cron, backup.sh nirgends eingebunden) -> bei Volume-/Disk-Verlust drohte Totalverlust. - Neuer service "backup" (docker-compose.yml): postgres:16-alpine als Sidecar, taeglicher pg_dump um BACKUP_HOUR (Default 03:00 Europe/Berlin) - backup-loop.sh: abhaengigkeitsfreier Tages-Scheduler (umgeht busybox-cron- Environment-Eigenheiten) - backup.sh korrigiert: laeuft remote gegen PGHOST mit PGPASSWORD; -Fc statt "-Fc | gzip" (war doppelt komprimiert und als .sql.gz nicht restore-bar) -> .dump - BACKUP_HOUR/BACKUP_RETENTION_DAYS konfigurierbar (.env.example) - operations.md: Backup-/Restore-Anleitung an Ist-Zustand angepasst Verifiziert: pg_dump erstellt + pg_restore in frische DB, Daten intakt. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
32 lines
1.2 KiB
Bash
Executable File
32 lines
1.2 KiB
Bash
Executable File
#!/bin/sh
|
|
# pg_dump des Cockpit-Postgres nach /backups. Custom-Format (-Fc): bereits
|
|
# komprimiert UND erlaubt selektives pg_restore — daher KEIN zusätzliches gzip.
|
|
#
|
|
# Läuft im Backup-Sidecar (docker-compose.yml service "backup") gegen den
|
|
# postgres-Service (PGHOST). Einmal pro Tag getriggert von backup-loop.sh.
|
|
# Manuell ausführbar: `docker compose exec backup /usr/local/bin/backup.sh`.
|
|
|
|
set -eu
|
|
|
|
PGHOST="${PGHOST:-postgres}"
|
|
PGUSER="${POSTGRES_USER:-cockpit}"
|
|
PGDATABASE="${POSTGRES_DB:-cockpit}"
|
|
RETENTION_DAYS="${BACKUP_RETENTION_DAYS:-14}"
|
|
DATE=$(date +%Y%m%d-%H%M%S)
|
|
OUT="/backups/cockpit-${DATE}.dump"
|
|
mkdir -p /backups
|
|
|
|
export PGPASSWORD="${POSTGRES_PASSWORD:-}"
|
|
pg_dump -h "$PGHOST" -U "$PGUSER" -d "$PGDATABASE" -Fc -f "$OUT"
|
|
echo "Backup geschrieben: $OUT ($(du -h "$OUT" | cut -f1))"
|
|
|
|
# Retention: Dumps älter als N Tage löschen.
|
|
find /backups -type f -name 'cockpit-*.dump' -mtime "+${RETENTION_DAYS}" -delete
|
|
|
|
# Heartbeat an die API (nur Observability/Logging — macht selbst kein Backup).
|
|
API_URL="${API_URL:-http://api:3000}"
|
|
if [ -n "${CRON_BEARER_TOKEN:-}" ]; then
|
|
wget -q --header="Authorization: Bearer ${CRON_BEARER_TOKEN}" \
|
|
-O- "${API_URL}/internal/cron/pg-dump-backup" || true
|
|
fi
|