Skip to content

[OPS-01] Database Backup/Restore Automation + Point-in-Time Recovery (PITR) #343

Description

@grantfox-oss

Problem

Current docker-compose.yml only mounts a PostgreSQL volume (postgres_data). No automated backups, no PITR, no restore drills documented.

Risks

Scenario Impact Current Mitigation
Disk failure / volume corruption Total data loss None
Accidental DROP TABLE / bad migration Hours of downtime Manual pg_dump if remembered
Ransomware / TRUNCATE Irrecoverable None
Need to clone prod → staging Manual, error-prone None

Requirements

1. Automated Backups (PITR-ready)

  • Tool: pgBackRest or wal-g (recommended: pgBackRest — supports S3/GCS/Azure, parallel, compression, encryption)
  • Schedule:
    • Full backup: daily 02:00 UTC
    • Incremental: every 6h
    • WAL archiving: continuous (streaming replication slot)
  • Retention: 30 daily fulls + 7 weekly + 12 monthly
  • Storage: S3-compatible (MinIO for dev, AWS S3/GCS for prod) with lifecycle policy
  • Encryption: AES-256 at rest (pgBackRest --repo1-cipher-type=aes-256-cbc)

2. Point-in-Time Recovery (PITR)

  • Restore to any second within retention window
  • Target: RPO < 5 min (WAL archiving), RTO < 30 min (restore parallelism)
  • Documented pgbackrest restore --type=time --target=... procedure

3. Restore Automation (CI/CD + Runbook)

  • Staging refresh job: Weekly, restores latest backup to staging-db, runs migrations, validates schema checksum
  • Disaster drill: Quarterly, restore to fresh cluster, verify app comes up, document timing
  • Runbook: docs/DISASTER_RECOVERY.md with:
    • Step-by-step restore commands
    • Contact tree (on-call, infra, security)
    • RTO/RPO targets
    • Post-restore validation checklist

4. Monitoring & Alerting

  • Backup success/failure → alert (PagerDuty/Slack)
  • WAL lag > 5 min → alert
  • Backup age > 26h → alert (missing daily)
  • Restore drill overdue → alert

Implementation Plan

Phase Task Owner Est.
1 Add pgbackrest sidecar to docker-compose.yml (dev) + Helm chart (prod) Infra 1d
2 Configure S3 repo, encryption, retention Infra 0.5d
3 Implement WAL archiving (replication slot) Infra 0.5d
4 Write restore script + staging refresh job (GitHub Actions) Infra 1d
5 Document runbook (docs/DISASTER_RECOVERY.md) Infra/Backend 0.5d
6 First disaster drill (schedule, execute, document) Team 2h
7 Add alerts (Prometheus rules / pgBackRest webhook) Infra 0.5d

Acceptance Criteria

  • pgbackrest --stanza=micopay backup succeeds in CI
  • pgbackrest --stanza=micopay restore --type=time --target="2026-07-27 12:00:00" restores to fresh DB in < 30 min
  • Staging DB auto-refreshed weekly from backup (green check in Actions)
  • docs/DISASTER_RECOVERY.md exists and is accurate
  • Alerts fire on backup failure / WAL lag / stale backup
  • Quarterly drill scheduled in team calendar

References

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions