feat(server-backup): restic dual-repo backup (NAS + B2) with dashboard UI
Adds a server-wide backup capability beyond the existing ops_dashboard pg_dump flow: - Daily systemd timer (03:30) runs pg_dumpall + Forgejo dump, then restic to a local NAS repo and an offsite Backblaze B2 repo with Object Lock. Phase-based script with single-instance flock, structured statusfile, systemd hardening, and live-datadir excludes (Postgres / Forgejo) so the dumps stay authoritative. - Ops-agent gets nine new read-only/trigger commands (snapshots, stats, status, logs, plus two triggers) backed by sudoers-whitelisted wrapper scripts that source /etc/restic-backup.env so the agent never sees the restic password or B2 keys. - Two new flows (server_backup_full, server_backup_restore_test) drive the dashboard's "Backup now" and "Restore test" buttons. - /settings/backups gains a Server backup section with overall + per-phase status, NAS / B2 snapshot tables, restore-size / raw-data / dedup-ratio stats, and the last restore-test result. The existing pg_dump section is preserved unchanged. - Runbook docs/runbooks/server-backup.md follows the tailscale-setup pattern (plan + addendum) and covers B2 Object Lock + scoped keys, Forgejo subplan with isolated restore-test stack, the off-server maintenance flow for B2 prune, and the integrity-check schedule. Code-only change — installation on scrum4me-srv follows the runbook. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
27cba872a8
commit
ab87c0fada
23 changed files with 2625 additions and 170 deletions
44
deploy/server-backup/restic-backup.env.example
Normal file
44
deploy/server-backup/restic-backup.env.example
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# Copy to /etc/restic-backup.env on the host. Permissions: 0600 root:root.
|
||||
# RESTIC_PASSWORD lives in /etc/restic-backup.password (mode 0400 root:root)
|
||||
# — the backup script sets RESTIC_PASSWORD_FILE from there, so the password
|
||||
# never appears in the process listing or this env file.
|
||||
|
||||
# ── Restic repositories ────────────────────────────────────────────────────
|
||||
# Local NAS path (must be mounted before the timer fires; see runbook).
|
||||
RESTIC_REPO_NAS=/mnt/backup-server/restic/scrum4me-srv
|
||||
|
||||
# Backblaze B2 repo, format: b2:<bucket-name>:<prefix>
|
||||
# Bucket must have Object Lock (Governance) with default retention >= 30 days.
|
||||
RESTIC_REPO_B2=b2:scrum4me-srv-backup:scrum4me-srv
|
||||
|
||||
# ── Backblaze B2 server key ────────────────────────────────────────────────
|
||||
# Capabilities REQUIRED: listBuckets, listFiles, readFiles, writeFiles
|
||||
# Capabilities FORBIDDEN: deleteFiles, deleteKeys, bypassGovernance
|
||||
# Create with:
|
||||
# b2 application-key create \
|
||||
# --bucket scrum4me-srv-backup \
|
||||
# --name-prefix scrum4me-srv \
|
||||
# server-backup-key \
|
||||
# listBuckets,listFiles,readFiles,writeFiles
|
||||
B2_ACCOUNT_ID=REPLACE_WITH_B2_KEY_ID
|
||||
B2_ACCOUNT_KEY=REPLACE_WITH_B2_APPLICATION_KEY
|
||||
|
||||
# ── Forgejo backup target (optional — set to skip if Forgejo not deployed) ─
|
||||
# Container name as it appears in `docker ps`. Set to "" or comment out to
|
||||
# skip the Forgejo phases entirely.
|
||||
FORGEJO_CONTAINER=forgejo
|
||||
# Path to app.ini INSIDE the Forgejo container (used by `forgejo dump -c`).
|
||||
FORGEJO_CONFIG=/data/gitea/conf/app.ini
|
||||
# Postgres database name for Forgejo (empty = use SQLite, skip forgejo_db_dump).
|
||||
FORGEJO_DB_NAME=forgejo
|
||||
# Postgres container + role for Forgejo's DB (defaults match scrum4me stack).
|
||||
FORGEJO_DB_CONTAINER=scrum4me-postgres
|
||||
FORGEJO_DB_USER=scrum4me
|
||||
|
||||
# ── Scrum4Me Postgres (required for postgres_dump phase) ───────────────────
|
||||
PG_CONTAINER=scrum4me-postgres
|
||||
PG_DUMPALL_USER=scrum4me
|
||||
|
||||
# ── Optional bandwidth limit for restic B2 upload (KiB/s; 0 = unlimited) ──
|
||||
# Translated by the script into `restic --limit-upload "$BACKUP_LIMIT_UPLOAD_KIB"`.
|
||||
# BACKUP_LIMIT_UPLOAD_KIB=5000
|
||||
Loading…
Add table
Add a link
Reference in a new issue