app.bettersight.io/scripts/backup-pocketbase.sh

32 lines
1.1 KiB
Bash
Executable File

#!/bin/bash
#
# Daily PocketBase point-in-time backup — CLAUDE.md §18 "Layer 2 —
# Daily zip backup". Belt-and-braces alongside Litestream's real-time
# WAL streaming (Layer 1): this is the fallback if the Litestream
# stream itself is ever corrupted, so it deliberately does NOT depend
# on Litestream being healthy.
#
# Installed on the Hetzner VPS at /usr/local/bin/backup-pocketbase.sh,
# triggered by the crontab entry in bettersight-backup.cron.
#
# Requires: rclone configured with a remote named "hetzner-s3" pointing
# at the Hetzner Object Storage bucket (see .env.example's
# HETZNER_S3_* vars for the credentials that remote should use).
set -euo pipefail
DATE=$(date +%Y%m%d)
BACKUP_NAME="backup_${DATE}.zip"
docker exec pocketbase /pb/pocketbase backup \
--dir /pb/backups --name "${BACKUP_NAME}"
rclone copy /pb/backups/ \
hetzner-s3:bettersight-backups/ \
--max-age 7d
# 7-day retention on Hetzner Object Storage (via --max-age above) plus
# a tighter 2-day local retention on the VPS itself — the local copy
# only needs to survive long enough for the rclone upload to succeed.
find /pb/backups -name "*.zip" -mtime +2 -delete