#!/bin/bash # Nightly Gitea backup (alpha.jayfield.org side of the alpha -> vlda-01 # backup strategy, see SYNC-PLAN.md "Ongoing backup" section). # # Uses `gitea dump` rather than a raw copy of /srv/gitea/data, since the # DB is a live SQLite file - dumping gives one consistent archive instead # of risking a torn mid-write copy. vlda-01 pulls the result on its own # schedule; this script only produces and prunes local archives. set -u BACKUP_DIR=/srv/gitea/data/backups KEEP=14 FILE="gitea-dump-$(date +%Y%m%d-%H%M%S).zip" if ! docker exec -u git gitea gitea dump -f "/data/backups/${FILE}" --skip-index -q; then echo "$(date -Is) ERROR: gitea dump failed, see above" >&2 exit 1 fi # vlda-01 verifies integrity before deleting its remote (alpha-side) copy cd "$BACKUP_DIR" || exit 1 sha256sum "$FILE" > "${FILE}.sha256" # the giteabackup SFTP account (see sshd Match Group sftp) needs read # access to pull these - default ACL inheritance alone isn't enough, the # file's own restrictive mask neutralizes the inherited grant, so set it # explicitly on every new file (both the dump and its checksum) setfacl -m u:giteabackup:r "${BACKUP_DIR}/${FILE}" setfacl -m u:giteabackup:r "${BACKUP_DIR}/${FILE}.sha256" # prune to the last $KEEP archives (safety net only - in normal operation # vlda-01 deletes each dump right after a verified pull, well before this # would ever trigger; this just bounds disk use if it's offline a while) ls -1t gitea-dump-*.zip 2>/dev/null | tail -n +$((KEEP + 1)) | while read -r old; do rm -f "$old" "${old}.sha256" done echo "$(date -Is) backup complete: ${FILE} ($(du -h "${BACKUP_DIR}/${FILE}" 2>/dev/null | cut -f1)), $(ls -1 gitea-dump-*.zip 2>/dev/null | wc -l) archive(s) retained"