feat(infra): add pgBackRest for PostgreSQL Point-in-Time Recovery

Replace simple pg_dumpall with pgBackRest PITR backup system.
This enables recovery to any second, not just the last daily dump.

Configuration:
- docker/postgres/postgresql.conf: WAL archiving + performance tuning
  (shared_buffers=512MB, effective_cache_size=2GB for 16GB Mac Mini)
- docker/postgres/pgbackrest.conf: stanza config + retention policy

Docker (docker-compose.macmini.yml):
- postgres: mount custom config, enable WAL archiving
- postgres-backup: new pgBackRest container
  - Storage: /Volumes/ManaData/backups/pgbackrest
  - Retention: 4 full + 14 differential (~4 weeks)
  - Compression: Zstandard (zst)

Backup Schedule:
- 03:00 daily: Full backup
- Every 6h: Differential (changes since last full)
- Every hour: Incremental (changes since last backup)
- Continuous: WAL archiving (every 60s)

Documentation (docs/POSTGRES_BACKUP.md):
- Complete restore procedures (full, PITR, single DB)
- First-time setup instructions
- Monitoring and alerting integration

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-03-24 11:18:33 +01:00
parent 979564540a
commit 39526918a3
4 changed files with 251 additions and 0 deletions

View file

@ -0,0 +1,22 @@
[global]
# Repository location (inside pgbackrest container, mapped to host SSD)
repo1-path=/var/lib/pgbackrest
repo1-retention-full=4
repo1-retention-diff=14
# Compression
compress-type=zst
compress-level=3
# Parallelism
process-max=2
# Logging
log-level-console=info
log-level-file=detail
[mana]
pg1-path=/var/lib/postgresql/data
pg1-host=postgres
pg1-port=5432
pg1-user=postgres

View file

@ -0,0 +1,23 @@
# PostgreSQL Configuration for WAL Archiving + pgBackRest
# Append to default postgresql.conf
# WAL Archiving (required for Point-in-Time Recovery)
wal_level = replica
archive_mode = on
archive_command = 'pgbackrest --stanza=mana archive-push %p'
archive_timeout = 60
# WAL Settings (tuned for 16GB Mac Mini)
max_wal_senders = 3
max_wal_size = 1GB
min_wal_size = 80MB
# Performance (tuned for 16GB RAM, shared with other services)
shared_buffers = 512MB
effective_cache_size = 2GB
work_mem = 16MB
maintenance_work_mem = 128MB
# Logging
log_min_duration_statement = 1000
log_checkpoints = on