#!/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