feat: secure offsite backups
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
if [[ $# -ne 1 ]]; then echo "Usage: ./scripts/verify-backup.sh data/backups/YYYYMMDD-HHMMSS" >&2; exit 2; fi
|
||||
root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
backup_dir="$(cd "$1" && pwd)"
|
||||
[[ "$backup_dir" == "$root_dir"/* ]] || { echo "Backup must be inside the project directory" >&2; exit 2; }
|
||||
[[ -f "$backup_dir/hub.db" && -f "$backup_dir/uploads.tar.gz" && -f "$backup_dir/SHA256SUMS" ]] || { echo "Backup is incomplete" >&2; exit 2; }
|
||||
(cd "$backup_dir" && sha256sum -c SHA256SUMS)
|
||||
tar -tzf "$backup_dir/uploads.tar.gz" >/dev/null
|
||||
container_path="/app/${backup_dir#"$root_dir"/}/hub.db"
|
||||
docker compose -f "$root_dir/docker-compose.yml" exec -T -e BACKUP_PATH="$container_path" web node -e '
|
||||
const Database = require("better-sqlite3"); const db = new Database(process.env.BACKUP_PATH, { readonly: true });
|
||||
const row = db.prepare("PRAGMA integrity_check").get(); db.close(); if (row.integrity_check !== "ok") { console.error("SQLite integrity check failed"); process.exit(1); }
|
||||
'
|
||||
printf 'Verified backup: %s\n' "$backup_dir"
|
||||
Reference in New Issue
Block a user