Archive was growing unbounded (~97 GB / 6k segments). Now runs pg_archivecleanup against the newest .backup marker and deletes full_* directories beyond FULL_RETENTION=5. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
69 lines
2.1 KiB
YAML
69 lines
2.1 KiB
YAML
|
|
services:
|
|
postgres-db:
|
|
image: postgres:18
|
|
container_name: postgres-db
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_USER: ${POSTGRES_USER}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
POSTGRES_DB: ${POSTGRES_DB}
|
|
ports:
|
|
- "${PGPORT}:5432"
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql
|
|
- /data/backup/postgres/wal:/backup/wal
|
|
- ./init-replication-hba.sh:/docker-entrypoint-initdb.d/init-replication-hba.sh:ro
|
|
command:
|
|
- postgres
|
|
- -c
|
|
- wal_level=replica
|
|
- -c
|
|
- archive_mode=on
|
|
- -c
|
|
- archive_command=test -f /backup/wal/%f || cp %p /backup/wal/%f
|
|
- -c
|
|
- archive_timeout=600
|
|
|
|
postgres-backup:
|
|
image: postgres:18
|
|
container_name: postgres-backup
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- postgres-db
|
|
environment:
|
|
POSTGRES_USER: ${POSTGRES_USER}
|
|
PGPASSWORD: ${POSTGRES_PASSWORD}
|
|
volumes:
|
|
- /data/backup/postgres:/backup
|
|
entrypoint: ["/bin/bash", "-c"]
|
|
command:
|
|
- |
|
|
mkdir -p /backup/wal /backup/full
|
|
chown 999:999 /backup/wal
|
|
FULL_RETENTION=5
|
|
while true; do
|
|
STAMP=$$(date +%Y-%m-%d_%H-%M-%S)
|
|
DEST="/backup/full/full_$$STAMP"
|
|
echo "Starting full backup: full_$$STAMP"
|
|
if pg_basebackup -h postgres-db -U "$$POSTGRES_USER" -D "$$DEST" -Fp -Xs -P; then
|
|
echo "Full backup complete: full_$$STAMP"
|
|
LATEST_BACKUP_MARKER=$$(ls /backup/wal/*.backup 2>/dev/null | sort | tail -n1)
|
|
if [ -n "$$LATEST_BACKUP_MARKER" ]; then
|
|
echo "Cleaning WAL older than $$(basename "$$LATEST_BACKUP_MARKER")"
|
|
pg_archivecleanup /backup/wal "$$(basename "$$LATEST_BACKUP_MARKER")"
|
|
fi
|
|
ls -1dt /backup/full/full_* | tail -n +$$((FULL_RETENTION + 1)) | while read -r old; do
|
|
echo "Removing old full backup: $$old"
|
|
rm -rf "$$old"
|
|
done
|
|
else
|
|
echo "Full backup FAILED for full_$$STAMP - skipping cleanup"
|
|
rm -rf "$$DEST"
|
|
fi
|
|
sleep 604800
|
|
done
|
|
|
|
volumes:
|
|
postgres_data:
|