#!/bin/sh # GerbilManager Backup-Skript (Container-Welt) # Laeuft als Cron-Job im backup-Sidecar-Container. # Volumes: /data/photos (read-only), /backups (read-write) # Umgebungsvariablen: PGPASSWORD, POSTGRES_HOST, POSTGRES_USER, POSTGRES_DB, BACKUP_KEEP_DAYS set -e TIMESTAMP=$(date +%Y-%m-%d_%H-%M) BACKUP_DIR="/backups/$TIMESTAMP" DB_DUMP="$BACKUP_DIR/gerbilmanager_${TIMESTAMP}.sql" PHOTO_ARCHIVE="$BACKUP_DIR/photos_${TIMESTAMP}.tar.gz" KEEP_DAYS="${BACKUP_KEEP_DAYS:-7}" HOST="${POSTGRES_HOST:-db}" USER="${POSTGRES_USER:-postgres}" DB="${POSTGRES_DB:-gerbilmanager}" log() { echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1"; } log "=== Backup gestartet ($TIMESTAMP) ===" mkdir -p "$BACKUP_DIR" # --- Datenbank-Dump --- log "Erstelle pg_dump fuer $DB@$HOST..." if ! pg_dump -h "$HOST" -U "$USER" -d "$DB" --clean --if-exists --format=plain \ > "$DB_DUMP" 2>/tmp/pg_err; then log "FEHLER bei pg_dump: $(cat /tmp/pg_err)" exit 1 fi DUMP_SIZE=$(du -k "$DB_DUMP" | cut -f1) log "Dump erstellt: $DB_DUMP (${DUMP_SIZE} KB)" # Validierung: mindestens CREATE TABLE muss vorhanden sein if ! grep -q "CREATE TABLE" "$DB_DUMP" 2>/dev/null; then log "WARNUNG: Dump sieht ungueltig aus -- bitte $DB_DUMP pruefen" fi # --- Fotos archivieren --- if [ -d /data/photos ] && [ "$(ls -A /data/photos 2>/dev/null)" ]; then PHOTO_COUNT=$(find /data/photos -type f | wc -l) log "Archiviere $PHOTO_COUNT Fotos..." tar czf "$PHOTO_ARCHIVE" -C /data photos/ 2>/tmp/tar_err || { log "WARNUNG: Foto-Archiv fehlgeschlagen: $(cat /tmp/tar_err)" } PHOTO_SIZE=$(du -k "$PHOTO_ARCHIVE" 2>/dev/null | cut -f1) log "Foto-Archiv erstellt: $PHOTO_ARCHIVE (${PHOTO_SIZE} KB)" else log "Keine Fotos gefunden -- Foto-Backup uebersprungen" fi # --- Rotation: alte Backups loeschen --- log "Rotiere Backups (behalte $KEEP_DAYS Tage)..." find /backups -maxdepth 1 -type d -name '????-??-??_??-??' \ -mtime "+$KEEP_DAYS" -exec rm -rf {} + 2>/dev/null || true REMAINING=$(find /backups -maxdepth 1 -type d -name '????-??-??_??-??' | wc -l) log "Backup abgeschlossen. Vorhandene Sicherungen: $REMAINING" log "=== Ende ==="