#!/bin/sh # Backup of database, photos and .env into one archive. # # ./scripts/backup.sh [target-dir] default target: ./backups # KEEP=30 ./scripts/backup.sh keep the newest 30 archives (default 14) # # Cron example (daily 03:30): # 30 3 * * * cd /opt/kochbuch && ./scripts/backup.sh /mnt/nas/kochbuch >> backups/backup.log 2>&1 set -eu cd "$(dirname "$0")/.." TARGET=${1:-./backups} KEEP=${KEEP:-14} STAMP=$(date +%Y%m%d-%H%M%S) umask 077 mkdir -p "$TARGET" WORK=$(mktemp -d) trap 'rm -rf "$WORK"' EXIT echo "[$(date)] Sichere Datenbank …" docker compose exec -T db sh -c 'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" --format=custom' > "$WORK/db.dump" echo "[$(date)] Sichere Fotos …" docker compose exec -T app tar -C /data -czf - media > "$WORK/media.tar.gz" # .env contains the secrets needed to bring the backup up on a new server. cp .env "$WORK/env.backup" ARCHIVE="$TARGET/kochbuch-$STAMP.tar.gz" tar -C "$WORK" -czf "$ARCHIVE" db.dump media.tar.gz env.backup echo "[$(date)] Fertig: $ARCHIVE ($(du -h "$ARCHIVE" | cut -f1))" # Retention: delete everything but the newest $KEEP archives. ls -1t "$TARGET"/kochbuch-*.tar.gz 2>/dev/null | tail -n +"$((KEEP + 1))" | while read -r old; do rm -f -- "$old" echo "Altes Backup gelöscht: $old" done