I am trying to configure replication between two Postgresql docker containers. All tutorials out there - which are based on regular VM, not containers - states that a backup from the Master has to be done in the Replica / StandBy, through a command like this:
pg_basebackup -h 192.168.0.108 -U replicator -p 5432 -D $PGDATA -Fp -Xs -P -R
Unfortunately, this throws an error:
pg_basebackup: error: directory "/var/lib/postgresql/data" exists but is not empty
I cannot delete the content of this folder because the Postgresql service will crash and I will be kicked out of the container.
So, how can I do this given that I cannot stop the Postgresql service because of the containerized application?
CodePudding user response:
These instructions following the percona docs for configuration postgres replication.
Create a network for the postgres servers:
docker network create pgnet
Start the primary database server:
docker run -d \
--network pgnet \
-v primary_data:/var/lib/postgresql/data \
--name pg_primary \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=exampledb \
docker.io/postgres:14
Create a replication user and configure pg_hba.conf to allow
replication access:
docker exec pg_primary \
psql -U postgres -c \
"CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'secret'"
docker exec pg_primary \
sh -c 'echo host replication replicator 0.0.0.0/0 md5 >> $PGDATA/pg_hba.conf'
docker exec pg_primary \
psql -U postgres -c 'select pg_reload_conf()'
Prepare the pgdata directory for the replica server. We do this by running the pg_basebackup command in an ephemeral container:
docker run -it --rm \
--network pgnet \
-v replica_data:/var/lib/postgresql/data \
--name pg_replica_init \
docker.io/postgres:14 \
sh -c 'pg_basebackup -h pg_primary -U replicator -p 5432 -D $PGDATA -Fp -Xs -P -R -W'
(The -W in the above command forces pg_basebackup to prompt for a
password. There are other ways you could provide the password; the
postgres docs have details.)
Start the replica:
docker run -d \
--network pgnet \
-v replica_data:/var/lib/postgresql/data \
--name pg_replica \
docker.io/postgres:14
Verify that replication is working. Create a table in the primary:
docker exec pg_primary \
psql -U postgres exampledb -c 'create table example_table (id int, name text)'
See that it shows up in the replica:
docker exec pg_replica \
psql -U postgres exampledb -c '\d'
You should see as output:
List of relations
Schema | Name | Type | Owner
-------- --------------- ------- ----------
public | example_table | table | postgres
(1 row)
