Ops-dashboard/deploy/server-backup/restic-backup.env.example
Madhura68 ab87c0fada 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>
2026-05-15 13:03:00 +02:00

44 lines
2.3 KiB
Text

# 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