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>
33 lines
1 KiB
Desktop File
33 lines
1 KiB
Desktop File
[Unit]
|
|
Description=Server-wide backup (pg_dumpall + restic to NAS + B2)
|
|
Documentation=file:///srv/ops/repos/ops-dashboard/docs/runbooks/server-backup.md
|
|
After=network-online.target docker.service
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
EnvironmentFile=/etc/restic-backup.env
|
|
ExecStart=/srv/backups/scripts/server-backup.sh
|
|
TimeoutStartSec=4h
|
|
RuntimeMaxSec=6h
|
|
Nice=10
|
|
IOSchedulingClass=best-effort
|
|
IOSchedulingPriority=7
|
|
# Sandboxing — backup needs root for /etc + docker exec, but limit the rest.
|
|
ProtectSystem=strict
|
|
ReadWritePaths=/var/backups /srv/backups /run /tmp
|
|
ProtectHome=read-only
|
|
NoNewPrivileges=yes
|
|
PrivateTmp=yes
|
|
ProtectKernelTunables=yes
|
|
ProtectKernelModules=yes
|
|
ProtectControlGroups=yes
|
|
StandardOutput=journal
|
|
StandardError=journal
|
|
SyslogIdentifier=server-backup
|
|
|
|
# Exit code semantics from server-backup.sh:
|
|
# 0 = success (all phases ok)
|
|
# 75 = partial_failure (some non-critical phase failed/degraded)
|
|
# 1 = failed (a critical dump phase failed or both restic repos failed)
|
|
SuccessExitStatus=75
|