diff --git a/infra/files/backups/backup-keep.sh b/infra/files/backups/backup-keep.sh new file mode 100755 index 0000000..64dd7ea --- /dev/null +++ b/infra/files/backups/backup-keep.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Online backup of keep.db: SQLite .backup as the keep user (the only one with read on /var/lib/keep/keep.db), +# then rclone push as the deploy user (the only one with the B2 credentials). +# The DB is age-encrypted at rest, so mode 644 on the backup file is fine. + +set -euo pipefail + +DEST=/var/backups/keep +install -d -o keep -g keep -m 0755 "$DEST" + +TS=$(date -u +%Y-%m-%d_%H-%M-%S) +FILE="$DEST/keep_backup_$TS.db" + +runuser -u keep -- sqlite3 /var/lib/keep/keep.db ".backup '$FILE'" +chmod 644 "$FILE" + +runuser -u deploy -- /usr/bin/rclone copy "$FILE" b2:lyrics-api-backups/keep/daily/ --transfers 4 +if [ "$(date -u +%u)" = "7" ]; then + runuser -u deploy -- /usr/bin/rclone copy "$FILE" b2:lyrics-api-backups/keep/weekly/ --transfers 4 +fi + +# Local retention: 7 days +find "$DEST" -name 'keep_backup_*.db' -mtime +7 -delete diff --git a/infra/files/backups/keep-backup.cron b/infra/files/backups/keep-backup.cron new file mode 100644 index 0000000..fc470e7 --- /dev/null +++ b/infra/files/backups/keep-backup.cron @@ -0,0 +1,5 @@ +# /etc/cron.d/keep-backup +# Daily keep.db backup at 03:45 UTC (after cache.db backup window). Runs as root because the script +# needs to switch to keep (read DB) and deploy (push to B2) without password prompts. +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +45 3 * * * root /usr/local/bin/backup-keep.sh diff --git a/infra/phases/01-packages.sh b/infra/phases/01-packages.sh index 2e8ea8b..6d2042d 100755 --- a/infra/phases/01-packages.sh +++ b/infra/phases/01-packages.sh @@ -6,7 +6,7 @@ DEBIAN_FRONTEND=noninteractive apt-get update DEBIAN_FRONTEND=noninteractive apt-get install -y \ curl wget ca-certificates gnupg lsb-release \ ufw fail2ban \ - rclone jq git \ + rclone jq git sqlite3 \ apt-transport-https debian-archive-keyring echo "OK: base packages installed" diff --git a/infra/phases/08-backups.sh b/infra/phases/08-backups.sh index e387669..92771ce 100755 --- a/infra/phases/08-backups.sh +++ b/infra/phases/08-backups.sh @@ -8,6 +8,14 @@ install -m 755 -o root -g root \ install -m 755 -o root -g root \ "$INFRA_DIR/files/backups/upload-backup.sh" \ /usr/local/bin/upload-backup.sh +install -m 755 -o root -g root \ + "$INFRA_DIR/files/backups/backup-keep.sh" \ + /usr/local/bin/backup-keep.sh + +# System cron for keep.db backup (runs as root, drops to keep + deploy via runuser) +install -m 644 -o root -g root \ + "$INFRA_DIR/files/backups/keep-backup.cron" \ + /etc/cron.d/keep-backup # rclone config for deploy user (mode 600) install -d -o deploy -g deploy -m 700 /home/deploy/.config