This repository contains a production-ready PostgreSQL 18 replication setup using Docker Compose with primary and replica nodes. It includes:
- Streaming replication
- Separate configuration files for primary and replica
- Custom tuning for performance, WAL, autovacuum, logging, and memory
- Easy-to-use initialization scripts
- Docker >= 24.x
- Docker Compose >= 2.x
- At least 2GB RAM for the database (adjust
shared_buffersinpostgresql.confif needed)
git clone https://github.com/bekaku/postgres-replication.git
cd postgres-replicationdocker-compose up -dThis will:
-
Start the primary container with PostgreSQL 18.
-
Initialize the replication user using init-primary.sh.
-
Start the replica container, which will:
-
Wait for the primary to be ready
-
Initialize via pg_basebackup if the data directory is empty
-
Start PostgreSQL in hot-standby mode
docker logs -f postgres_primary
docker logs -f postgres_replica_1
docker logs -f postgres_replica_...- On the replica, you should see:
[Replica] Waiting for primary at...
[Replica] Empty data directory, running base backup...
[Replica] Starting PostgreSQL...- Connect to the primary:
docker exec -it postgres_primary psql -U postgres -d appdb- Check replication status on the primary:
SELECT * FROM pg_stat_replication;- Configuration files are mounted from
primary/postgresql.confandreplica/postgresql.conf. - To adjust memory, WAL, logging, or autovacuum:
- Edit the respective
postgresql.conffile. - Restart the container to apply settings:
docker-compose restart postgres_primary
docker-compose restart postgres_replica_1
docker-compose restart postgres_replica_...- Some settings (like logging or autovacuum) can be reloaded without a full restart:
docker exec -it postgres_primary pg_ctl reload
docker exec -it postgres_replica_1 pg_ctl reload- Logs are written to
/var/log/postgresqlinside the container. - You can mount this directory to the host in
docker-compose.ymlif needed:
volumes:
- ./log/postgres_primary:/var/log/postgresql
- ./log/postgres_replica_1:/var/log/postgresqlTo clean the environment and start fresh:
docker-compose down -v
docker-compose up -dThis removes named volumes and reinitializes the primary and replica.
-
hot_standby = onis required only on the replica. -
Primary-only settings (
max_wal_senders,wal_keep_size) can safely be copied to the replica; Postgres ignores them there. -
Ensure replication user credentials (
REPL_USERandREPL_PASSWORD) are consistent between primary and replica. -
You can scale replicas by copying the replica service in
docker-compose.ymland giving each a unique container name and port.
- Use Docker secrets for passwords instead of plain environment variables.
- Add health checks to monitor replication lag.
- Configure persistent host volumes for logs and data for better durability.
- Enable monitoring with pg_stat_statements or Prometheus exporters.