Setting Up a Replica for Backups for PostgreSQL in Docker
2. Configuration
-
Primary Postgres Configuration:
Now, you'll likely want this at the bottom of your
postgresql.conf
to make sure it's ready to replicate:hot_standby = on archive_mode = off wal_level = replica max_wal_senders = 3 wal_keep_size = 1024
It'll need to be restarted for these changes to take effect, which would be safest done now before copying the data:
docker compose down db && docker compose up db -d
-
Preparing Replica Data:
Postgres replication involves streaming updates as they're made to the database, so to start we'll need to create a duplicate of the current database to use for the replica.
You can create a copy of your entire database like this, just substitute the container name and user as required:
docker exec -it synapse-db-1 pg_basebackup -h /sockets -U synapse -D /tmp/pgreplica
The data is initially written to /tmp/ inside the container as it's safest for permissions. We can then move it to /var/lib/postgresql/data/ so we can more easily access it from the host OS:
docker exec -it synapse-db-1 mv /tmp/pgreplica /var/lib/postgresql/data/
You can hopefully now reach the data and move it to a new directory for your replica, updating the ownership to match your existing Postgres data directory:
mv ./pgsql/pgreplica ./ chown -R 70:1000 ./pgreplica
-
Replica Postgres Configuration:
Now for the replica's
postgresql.conf
, add this to the bottom to tell it that it's a secondary and scale back its resource usage as it won't be actively serving clients:port = 5433 hot_standby = on checkpoint_timeout = 30min shared_buffers = 512MB effective_cache_size = 1GB maintenance_work_mem = 128MB work_mem = 4MB max_wal_size = 2GB max_parallel_workers_per_gather = 1 max_parallel_workers = 1 max_parallel_maintenance_workers = 1
-
Primary Postgres Replication
This will instruct the primary to allow replication:
# Enable replication for the user docker exec -it your_primary_container_name psql -U synapse -c "ALTER USER synapse WITH REPLICATION;" # Create a replication slot docker exec -it your_primary_container_name psql -U synapse -c "SELECT * FROM pg_create_physical_replication_slot('replica_slot_name');"