This repository uses a three-part PostgreSQL setup in docker-compose.yml:
postgres-primaryruns the writable primary.postgres-replicafollows the primary through streaming replication.pgpoolsits in front of both nodes and provides read balancing plus automatic failover.
The application services connect to pgpool through DATABASE_URL, while the API also receives direct primary and replica URLs for lag monitoring.
The API exports:
db_replication_lag_msdb_replication_wal_lag_bytesdb_replication_health
Prometheus alerts fire when lag exceeds 100 ms or replication health drops to an unhealthy state.
Automatic failover should handle the common case. If an operator needs to step in:
- Confirm the primary is unhealthy and the replica is current enough to take over.
- Promote the replica inside the replica container.
- Restart
pgpoolso new connections route to the promoted node. - Update any direct connection strings that still point at the old primary.
- Verify writes succeed through
DATABASE_URLand that replication lag returns to normal.
Example commands:
docker compose exec postgres-replica repmgr standby promote
docker compose restart pgpoolThe API periodically compares the primary WAL position with the replica replay position and warns if the lag target is exceeded. This gives a second signal beyond connection health, which helps catch cases where the replica is alive but no longer close enough to the primary.