Backup and restore
WAL-G ships Postgres WAL and base backups to R2. The operator command is manage.sh backup on the VPS. Retention is BACKUP_RETAIN_FULL and related backup variables. Names only: BACKUP_R2_*, BACKUP_WALG_*. Values stay in the secret manager.
Auth admin ops can list backups. That path uses the same R2 credentials server-side. The admin UI must not receive the secret.
Restore
- Stop writers (services and the relay) so they do not append to a database you are replacing.
- Restore with the WAL-G procedure in
infra/docker/BACKUP.mdonto the target instance. - Start Postgres, then PgBouncer, then the relay, then services.
- Expect outbox rows that were published before the backup and not yet marked, or the reverse, depending on the restore point. Consumers dedupe on
event_id. Check dead letters before you announce recovery. - Run
verify.
Test a restore on a non-production VM on a schedule. A backup that has never been restored is a hope.
Media objects in R2 are not inside the Postgres backup. A database restore does not roll back uploaded images. Reconciliation in media-service reports the mismatch; it does not delete production objects by itself.