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_buffers
inpostgresql.conf
if needed)
git clone https://github.com/bekaku/postgres-replication.git
cd postgres-replication
docker-compose up -d
This 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 pg_primary
docker logs -f pg_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 pg_primary psql -U postgres -d appdb
- Check replication status on the primary:
SELECT * FROM pg_stat_replication;
- Configuration files are mounted from
primary/postgresql.conf
andreplica/postgresql.conf
. - To adjust memory, WAL, logging, or autovacuum:
- Edit the respective
postgresql.conf
file. - Restart the container to apply settings:
docker-compose restart primary
docker-compose restart replica
- Some settings (like logging or autovacuum) can be reloaded without a full restart:
docker exec -it pg_primary pg_ctl reload
docker exec -it pg_replica pg_ctl reload
- Logs are written to
/var/log/postgresql
inside the container. - You can mount this directory to the host in
docker-compose.yml
if needed:
volumes:
- pg_primary_logs:/var/log/postgresql
- pg_replica_logs:/var/log/postgresql
To clean the environment and start fresh:
docker-compose down -v
docker-compose up -d
This removes named volumes and reinitializes the primary and replica.
-
hot_standby = on
is 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_USER
andREPL_PASSWORD
) are consistent between primary and replica. -
You can scale replicas by copying the replica service in
docker-compose.yml
and 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.