diff --git a/Dockerfile b/Dockerfile index e17409a..b6fe61d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,16 @@ -FROM postgres:9.6 -MAINTAINER Daniel Dent (https://www.danieldent.com) +FROM postgres:15.0 + +RUN apt-get update -y +RUN apt-get install -y iputils-ping + ENV PG_MAX_WAL_SENDERS 8 -ENV PG_WAL_KEEP_SEGMENTS 8 +ENV PG_WAL_KEEP_SIZE 128 + COPY setup-replication.sh /docker-entrypoint-initdb.d/ -COPY docker-entrypoint.sh /docker-entrypoint.sh -RUN chmod +x /docker-entrypoint-initdb.d/setup-replication.sh /docker-entrypoint.sh +COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh +COPY standby.signal /tmp/standby.signal + +RUN chmod +x /docker-entrypoint-initdb.d/setup-replication.sh /usr/local/bin/docker-entrypoint.sh + +## debug +# ENTRYPOINT ["tail", "-f", "/dev/null"] \ No newline at end of file diff --git a/README.md b/README.md index 09a348e..3e728f5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Postgres 9.6 Dockerized w/ Replication +# Postgres 15.0 Dockerized w/ Replication Master/Slave Postgres Replication in 30 seconds. @@ -14,6 +14,3 @@ Master/Slave Postgres Replication in 30 seconds. * No additional replication user is setup - the postgres admin user is used. This means the superuser credentials must be identical on the master and all slaves. * setup-replication.sh is only executed when a container's data volume is first initialized. * REPLICATE_FROM environment variable is only used during container initialization - if the master changes after the database has been initialized, you'll need to manually adjust the recovery.conf file in the slave containers' data volume. - * Configuration: - * PG_MAX_WAL_SENDERS 8 - Maximum number of slaves - * PG_WAL_KEEP_SEGMENTS 32 - See http://www.postgresql.org/docs/9.6/static/runtime-config-replication.html diff --git a/docker-compose.yml b/docker-compose.yml index 81a66da..858a719 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,32 +1,33 @@ - -version: '2' +version: "3.8" services: pg-master: - build: '.' - image: 'danieldent/postgres-replication' - restart: 'always' + build: . + restart: always + ports: + - "5432:5432" environment: - POSTGRES_USER: 'postgres' - POSTGRES_PASSWORD: 'postgres' - PGDATA: '/var/lib/postgresql/data/pgdata' + - POSTGRES_DB=test + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=postgres + - PGDATA=/var/lib/postgresql/data/pgdata + #- REPLICATE_FROM=pg-slave #only after pg-slave get promoted volumes: - - '/var/lib/postgresql/data' - expose: - - '5432' + - /var/lib/postgresql/data + # #Promote to master `select pg_promote(true,60);` pg-slave: - build: '.' - image: 'danieldent/postgres-replication' - restart: 'always' + build: . + restart: always + ports: + - "2432:5432" environment: - POSTGRES_USER: 'postgres' - POSTGRES_PASSWORD: 'postgres' - PGDATA: '/var/lib/postgresql/data/pgdata' - REPLICATE_FROM: 'pg-master' + - POSTGRES_DB=test + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=postgres + - PGDATA=/var/lib/postgresql/data/pgdata + - REPLICATE_FROM=pg-master + depends_on: + - "pg-master" volumes: - - '/var/lib/postgresql/data' - expose: - - '5432' - links: - - 'pg-master' + - /var/lib/postgresql/data diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index f290efb..b8cd750 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -34,18 +34,18 @@ if [ "$1" = 'postgres' ]; then # look specifically for PG_VERSION, as it is expected in the DB dir if [ ! -s "$PGDATA/PG_VERSION" ]; then if [ "x$REPLICATE_FROM" == "x" ]; then - eval "gosu postgres initdb $POSTGRES_INITDB_ARGS" + eval "gosu postgres initdb $POSTGRES_INITDB_ARGS" else - until ping -c 1 -W 1 ${REPLICATE_FROM} - do - echo "Waiting for master to ping..." - sleep 1s - done - until gosu postgres pg_basebackup -h ${REPLICATE_FROM} -D ${PGDATA} -U ${POSTGRES_USER} -vP -w - do - echo "Waiting for master to connect..." - sleep 1s - done + until ping -c 1 -W 1 ${REPLICATE_FROM} + do + echo "Waiting for master to ping..." + sleep 1s + done + until gosu postgres pg_basebackup -h ${REPLICATE_FROM} -D ${PGDATA} -U ${POSTGRES_USER} -vP -w + do + echo "Waiting for master to connect..." + sleep 1s + done fi # check password first so we can output the warning before postgres @@ -73,39 +73,39 @@ if [ "$1" = 'postgres' ]; then authMethod=trust fi - if [ "x$REPLICATE_FROM" == "x" ]; then - { echo; echo "host replication all 0.0.0.0/0 $authMethod"; } | gosu postgres tee -a "$PGDATA/pg_hba.conf" > /dev/null { echo; echo "host all all 0.0.0.0/0 $authMethod"; } | gosu postgres tee -a "$PGDATA/pg_hba.conf" > /dev/null - # internal start of server in order to allow set-up using psql-client - # does not listen on external TCP/IP and waits until start finishes - gosu postgres pg_ctl -D "$PGDATA" \ - -o "-c listen_addresses='localhost'" \ - -w start - - : ${POSTGRES_USER:=postgres} - : ${POSTGRES_DB:=$POSTGRES_USER} - export POSTGRES_USER POSTGRES_DB - - psql=( psql -v ON_ERROR_STOP=1 ) + if [ "x$REPLICATE_FROM" == "x" ]; then - if [ "$POSTGRES_DB" != 'postgres' ]; then + # internal start of server in order to allow set-up using psql-client + # does not listen on external TCP/IP and waits until start finishes + gosu postgres pg_ctl -D "$PGDATA" \ + -o "-c listen_addresses='localhost'" \ + -w start + + : ${POSTGRES_USER:=postgres} + : ${POSTGRES_DB:=$POSTGRES_USER} + export POSTGRES_USER POSTGRES_DB + + psql=( psql -v ON_ERROR_STOP=1 ) + + if [ "$POSTGRES_DB" != 'postgres' ]; then + "${psql[@]}" --username postgres <<-EOSQL + CREATE DATABASE "$POSTGRES_DB" ; + EOSQL + echo + fi + + if [ "$POSTGRES_USER" = 'postgres' ]; then + op='ALTER' + else + op='CREATE' + fi "${psql[@]}" --username postgres <<-EOSQL - CREATE DATABASE "$POSTGRES_DB" ; + $op USER "$POSTGRES_USER" WITH SUPERUSER $pass ; EOSQL echo - fi - - if [ "$POSTGRES_USER" = 'postgres' ]; then - op='ALTER' - else - op='CREATE' - fi - "${psql[@]}" --username postgres <<-EOSQL - $op USER "$POSTGRES_USER" WITH SUPERUSER $pass ; - EOSQL - echo fi @@ -122,9 +122,9 @@ if [ "$1" = 'postgres' ]; then echo done - if [ "x$REPLICATE_FROM" == "x" ]; then - gosu postgres pg_ctl -D "$PGDATA" -m fast -w stop - fi + if [ "x$REPLICATE_FROM" == "x" ]; then + gosu postgres pg_ctl -D "$PGDATA" -m fast -w stop + fi echo echo 'PostgreSQL init process complete; ready for start up.' diff --git a/setup-replication.sh b/setup-replication.sh index 460c548..a81ac33 100755 --- a/setup-replication.sh +++ b/setup-replication.sh @@ -3,20 +3,23 @@ if [ "x$REPLICATE_FROM" == "x" ]; then cat >> ${PGDATA}/postgresql.conf < ${PGDATA}/recovery.conf < ${PGDATA}/postgresql.conf <