Found by running deploy/hub/backup.sh on the production VM:
- With core.autocrlf=true, `git archive` on the Windows release machine
shipped the .sh files with CRLF and `sh` aborted on line 4
("set: Illegal option -"): backup, restore and seed never ran.
.gitattributes now forces *.sh to LF.
- Docker creates the bind-mounted backups/ directory as root, so the
host-side retention `rm` would fail once the 15th dump existed.
Retention now runs inside the postgres container.
tests/test_deploy_scripts.py covers both.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
16 lines
840 B
Bash
16 lines
840 B
Bash
#!/usr/bin/env sh
|
|
# PostgreSQL backup of the GTI Fiscal Hub (custom format, restorable with restore.sh). Run from deploy/hub.
|
|
# ./backup.sh -> ./backups/gti_fiscal_YYYYmmdd_HHMMSS.dump (last 14 kept)
|
|
set -eu
|
|
COMPOSE="docker compose -f docker-compose.prod.yml --env-file .env"
|
|
DIR="${BACKUP_DIR:-./backups}"
|
|
mkdir -p "$DIR"
|
|
STAMP="$(date +%Y%m%d_%H%M%S)"
|
|
FILE="gti_fiscal_${STAMP}.dump"
|
|
$COMPOSE exec -T postgres pg_dump -U gti -d gti_fiscal -Fc -f "/backups/${FILE}"
|
|
[ -s "$DIR/$FILE" ] || { echo "backup empty or missing: $DIR/$FILE" >&2; exit 1; }
|
|
# Retention runs inside the container: Docker creates the bind-mounted
|
|
# backup directory as root, so a host-side rm would fail from the 15th dump.
|
|
$COMPOSE exec -T postgres sh -c 'ls -1t /backups/gti_fiscal_*.dump | tail -n +15 | xargs -r rm -f'
|
|
echo "backup ok: $DIR/$FILE"
|