From 5a18cacb2e3552d05756fb47470743079e07af3d Mon Sep 17 00:00:00 2001 From: Toutsu Date: Tue, 12 May 2026 14:04:53 +0300 Subject: [PATCH] fix: address review feedback for backup infrastructure - compose.yaml: rewrite db-backup to use heredoc script instead of inline cron command, fixing date escaping and adding temp-file pipeline for reliable error detection - compose.yaml: fix pipefail issue by writing pg_dump to tmp file before compression and rotation - restore.sh: pass PGPASSWORD explicitly via docker compose exec -e - restore.sh: use ". .env" with set -a/+a instead of fragile xargs export Co-Authored-By: Claude Opus 4.7 --- compose.yaml | 12 +++++++++++- scripts/restore.sh | 11 ++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/compose.yaml b/compose.yaml index bb12187..c232406 100644 --- a/compose.yaml +++ b/compose.yaml @@ -35,7 +35,17 @@ services: entrypoint: ["sh", "-c"] command: - | - echo "0 3 * * * pg_dump -h db -U gmrelay -d gmrelay_db | gzip > /backups/gmrelay_db_\$$(date +\%Y\%m\%d_\%H\%M\%S).sql.gz && find /backups -name 'gmrelay_db_*.sql.gz' -type f -mtime +\$${BACKUP_RETENTION_DAYS} -delete" | crontab - + cat > /usr/local/bin/backup.sh << 'EOF' + #!/bin/sh + set -e + TMPFILE="/tmp/backup_$$.sql" + pg_dump -h db -U gmrelay -d gmrelay_db > "$TMPFILE" + gzip "$TMPFILE" + mv "$TMPFILE.gz" "/backups/gmrelay_db_$(date +%Y%m%d_%H%M%S).sql.gz" + find /backups -name 'gmrelay_db_*.sql.gz' -type f -mtime +${BACKUP_RETENTION_DAYS} -delete + EOF + chmod +x /usr/local/bin/backup.sh + echo "0 3 * * * /usr/local/bin/backup.sh" | crontab - crond -f bot: diff --git a/scripts/restore.sh b/scripts/restore.sh index b771cb1..a32dbd2 100644 --- a/scripts/restore.sh +++ b/scripts/restore.sh @@ -11,7 +11,10 @@ PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" # Check required env if [ -z "${POSTGRES_PASSWORD:-}" ]; then if [ -f "${PROJECT_ROOT}/.env" ]; then - export $(grep -v '^#' "${PROJECT_ROOT}/.env" | xargs) 2>/dev/null || true + # shellcheck source=/dev/null + set -a + . "${PROJECT_ROOT}/.env" + set +a fi fi @@ -57,12 +60,14 @@ echo "" echo "Restoring database from ${BACKUP_FILE}..." # Restore using docker compose exec to leverage the running postgres container -docker compose -f "${PROJECT_ROOT}/compose.yaml" exec -T db psql \ +COMPOSE_ARGS="-f ${PROJECT_ROOT}/compose.yaml" + +docker compose ${COMPOSE_ARGS} exec -T -e PGPASSWORD="${POSTGRES_PASSWORD}" db psql \ -U gmrelay \ -d gmrelay_db \ -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;" 2>/dev/null || true -gunzip -c "${BACKUP_FILE}" | docker compose -f "${PROJECT_ROOT}/compose.yaml" exec -T db psql \ +gunzip -c "${BACKUP_FILE}" | docker compose ${COMPOSE_ARGS} exec -T -e PGPASSWORD="${POSTGRES_PASSWORD}" db psql \ -U gmrelay \ -d gmrelay_db