bollwerk/backup/backup.sh
Jens Reinemann db2fc5dea1 fix: busybox crond statt dcron, pg17-Tokens aus Checksum filtern (#87)
- Dockerfile: dcron -> busybox crond (kein setpgid-Fehler im Container)
  Crontab in /var/spool/cron/crontabs/root
- backup.sh: grep-Filter fuer PostgreSQL 17 Security-Tokens
  (\restrict / \unrestrict) die sich bei jedem Dump aendern
2026-05-17 11:14:47 +02:00

59 lines
1.9 KiB
Bash

#!/bin/sh
set -e
BACKUP_DIR="${BACKUP_DIR:-/backups}"
DB_HOST="${POSTGRES_HOST:-db}"
DB_NAME="${POSTGRES_DB:-krisenvorrat}"
DB_USER="${POSTGRES_USER:-krisenvorrat}"
MAX_SIZE_BYTES=$((1 * 1024 * 1024 * 1024)) # 1 GB
mkdir -p "$BACKUP_DIR"
TIMESTAMP=$(date -u +"%Y-%m-%d_%H%M")
BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${TIMESTAMP}.sql.gz"
CHECKSUM_FILE="${BACKUP_DIR}/.last_checksum"
echo "[$(date -u)] Starting backup of database '${DB_NAME}' on host '${DB_HOST}'..."
# Dump to temp file for checksum comparison
TEMP_DUMP=$(mktemp)
export PGPASSWORD="${POSTGRES_PASSWORD:-}"
pg_dump -h "$DB_HOST" -U "$DB_USER" "$DB_NAME" > "$TEMP_DUMP"
# Compute MD5 of dump content, excluding lines that change every run:
# - pg_dump comment lines (timestamps, version info)
# - PostgreSQL 17 security tokens (\restrict / \unrestrict with random token)
CURRENT_CHECKSUM=$(grep -Ev '^(--|\\restrict|\\unrestrict)' "$TEMP_DUMP" | md5sum | cut -d' ' -f1)
LAST_CHECKSUM=""
if [ -f "$CHECKSUM_FILE" ]; then
LAST_CHECKSUM=$(cat "$CHECKSUM_FILE")
fi
if [ "$CURRENT_CHECKSUM" = "$LAST_CHECKSUM" ]; then
echo "[$(date -u)] No changes since last backup. Skipping."
rm -f "$TEMP_DUMP"
exit 0
fi
# Compress and save
gzip -c "$TEMP_DUMP" > "$BACKUP_FILE"
rm -f "$TEMP_DUMP"
printf '%s' "$CURRENT_CHECKSUM" > "$CHECKSUM_FILE"
echo "[$(date -u)] Backup saved: ${BACKUP_FILE}"
# Rotate: remove oldest .sql.gz until total backup dir size <= 1 GB
while true; do
TOTAL=$(du -sb "$BACKUP_DIR" | cut -f1)
if [ "$TOTAL" -le "$MAX_SIZE_BYTES" ]; then
break
fi
OLDEST=$(ls -tr "${BACKUP_DIR}"/*.sql.gz 2>/dev/null | head -1)
if [ -z "$OLDEST" ]; then
echo "[$(date -u)] Warning: Cannot reduce backup dir below 1 GB, no more files to delete."
break
fi
echo "[$(date -u)] Rotation: removing ${OLDEST} (dir total: ${TOTAL} bytes)"
rm -f "$OLDEST"
done
echo "[$(date -u)] Backup complete."