49 lines
1.5 KiB
Bash
Executable File
49 lines
1.5 KiB
Bash
Executable File
#!/bin/sh
|
|
# Dumps the database once at start, every day at BACKUP_TIME (HH:MM, container time zone), and whenever
|
|
# the api asks for one through /requests (it does so before every database upgrade).
|
|
set -eu
|
|
: "${BACKUP_TIME:=02:30}"
|
|
: "${BACKUP_KEEP_DAYS:=30}"
|
|
mkdir -p /backups /requests
|
|
chmod 1777 /requests
|
|
rm -f /tmp/first-backup-done
|
|
|
|
dump() {
|
|
file="/backups/budget_$(date +%Y%m%d_%H%M%S)${1:-}.sql.gz"
|
|
if pg_dump --no-owner --clean --if-exists | gzip > "$file.tmp"; then
|
|
mv "$file.tmp" "$file"
|
|
echo "$(date -Iseconds) backup written: $file"
|
|
find /backups -name 'budget_*.sql.gz' -mtime +"$BACKUP_KEEP_DAYS" -delete
|
|
return 0
|
|
fi
|
|
rm -f "$file.tmp"
|
|
echo "$(date -Iseconds) backup FAILED" >&2
|
|
return 1
|
|
}
|
|
|
|
answer_requests() {
|
|
for request in /requests/*.request; do
|
|
[ -e "$request" ] || continue
|
|
id=$(basename "$request" .request)
|
|
echo "$(date -Iseconds) backup requested: $(cat "$request" 2>/dev/null)"
|
|
if dump _before_upgrade; then echo ok > "/requests/$id.done"; else echo failed > "/requests/$id.done"; fi
|
|
rm -f "$request"
|
|
done
|
|
# answers nobody picked up
|
|
find /requests -name '*.done' -mmin +60 -delete 2>/dev/null || true
|
|
}
|
|
|
|
until pg_isready -q; do sleep 2; done
|
|
dump || true
|
|
touch /tmp/first-backup-done
|
|
while true; do
|
|
now=$(date +%s)
|
|
next=$(date -d "$(date +%Y-%m-%d) $BACKUP_TIME" +%s 2>/dev/null || date -D '%Y-%m-%d %H:%M' -d "$(date +%Y-%m-%d) $BACKUP_TIME" +%s)
|
|
[ "$next" -le "$now" ] && next=$((next + 86400))
|
|
while [ "$(date +%s)" -lt "$next" ]; do
|
|
answer_requests
|
|
sleep 5
|
|
done
|
|
dump || true
|
|
done
|