├── 10 ├── Dockerfile └── entrypoint.sh ├── 11 ├── Dockerfile └── entrypoint.sh ├── .gitignore ├── .dockerignore ├── LICENSE ├── 9.3 ├── Dockerfile └── entrypoint.sh ├── 9.4 ├── Dockerfile └── entrypoint.sh ├── 9.5 ├── Dockerfile └── entrypoint.sh ├── 9.6 ├── Dockerfile └── entrypoint.sh ├── tests ├── 11.sh ├── 10.sh ├── 95.sh ├── 96.sh ├── 94.sh └── 93.sh └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | LICENSE 3 | README.md 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 RomeOz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /10/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:xenial 2 | MAINTAINER romeOz 3 | 4 | ENV OS_LOCALE="en_US.UTF-8" \ 5 | DEBIAN_FRONTEND=noninteractive 6 | RUN apt-get update && apt-get install -y locales && locale-gen ${OS_LOCALE} 7 | ENV LANG=${OS_LOCALE} \ 8 | LANGUAGE=${OS_LOCALE} \ 9 | LC_ALL=${OS_LOCALE} \ 10 | PG_VERSION=10 \ 11 | PG_USER=postgres \ 12 | PG_HOME=/var/lib/postgresql \ 13 | PG_RUN_DIR=/run/postgresql \ 14 | PG_LOG_DIR=/var/log/postgresql 15 | 16 | ENV PG_CONF_DIR="/etc/postgresql/${PG_VERSION}/main" \ 17 | PG_BIN_DIR="/usr/lib/postgresql/${PG_VERSION}/bin" \ 18 | PG_DATA_DIR="${PG_HOME}/${PG_VERSION}/main" 19 | 20 | RUN dpkg-reconfigure locales && apt-get install -y wget sudo \ 21 | && wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \ 22 | && echo 'deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main' > /etc/apt/sources.list.d/pgdg.list \ 23 | && apt-get update && apt-get install -y postgresql-${PG_VERSION} postgresql-client-${PG_VERSION} postgresql-contrib-${PG_VERSION} lbzip2 \ 24 | # Cleaning 25 | && apt-get purge -y --auto-remove wget \ 26 | && rm -rf ${PG_HOME} \ 27 | && rm -rf /var/lib/apt/lists/* \ 28 | && touch /tmp/.EMPTY_DB 29 | 30 | COPY entrypoint.sh /sbin/entrypoint.sh 31 | RUN chmod 755 /sbin/entrypoint.sh 32 | 33 | EXPOSE 5432/tcp 34 | VOLUME ["${PG_HOME}", "${PG_RUN_DIR}"] 35 | CMD ["/sbin/entrypoint.sh"] 36 | -------------------------------------------------------------------------------- /9.3/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:xenial 2 | MAINTAINER romeOz 3 | 4 | ENV OS_LOCALE="en_US.UTF-8" \ 5 | DEBIAN_FRONTEND=noninteractive 6 | RUN apt-get update && apt-get install -y locales && locale-gen ${OS_LOCALE} 7 | ENV LANG=${OS_LOCALE} \ 8 | LANGUAGE=${OS_LOCALE} \ 9 | LC_ALL=${OS_LOCALE} \ 10 | PG_VERSION=9.3 \ 11 | PG_USER=postgres \ 12 | PG_HOME=/var/lib/postgresql \ 13 | PG_RUN_DIR=/run/postgresql \ 14 | PG_LOG_DIR=/var/log/postgresql 15 | 16 | ENV PG_CONF_DIR="/etc/postgresql/${PG_VERSION}/main" \ 17 | PG_BIN_DIR="/usr/lib/postgresql/${PG_VERSION}/bin" \ 18 | PG_DATA_DIR="${PG_HOME}/${PG_VERSION}/main" 19 | 20 | RUN dpkg-reconfigure locales && apt-get install -y wget sudo \ 21 | && wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \ 22 | && echo 'deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main' > /etc/apt/sources.list.d/pgdg.list \ 23 | && apt-get update && apt-get install -y postgresql-${PG_VERSION} postgresql-client-${PG_VERSION} postgresql-contrib-${PG_VERSION} lbzip2 \ 24 | # Cleaning 25 | && apt-get purge -y --auto-remove wget \ 26 | && rm -rf ${PG_HOME} \ 27 | && rm -rf /var/lib/apt/lists/* \ 28 | && touch /tmp/.EMPTY_DB 29 | 30 | COPY entrypoint.sh /sbin/entrypoint.sh 31 | RUN chmod 755 /sbin/entrypoint.sh 32 | 33 | EXPOSE 5432/tcp 34 | VOLUME ["${PG_HOME}", "${PG_RUN_DIR}"] 35 | CMD ["/sbin/entrypoint.sh"] 36 | -------------------------------------------------------------------------------- /9.4/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:xenial 2 | MAINTAINER romeOz 3 | 4 | ENV OS_LOCALE="en_US.UTF-8" \ 5 | DEBIAN_FRONTEND=noninteractive 6 | RUN apt-get update && apt-get install -y locales && locale-gen ${OS_LOCALE} 7 | ENV LANG=${OS_LOCALE} \ 8 | LANGUAGE=${OS_LOCALE} \ 9 | LC_ALL=${OS_LOCALE} \ 10 | PG_VERSION=9.4 \ 11 | PG_USER=postgres \ 12 | PG_HOME=/var/lib/postgresql \ 13 | PG_RUN_DIR=/run/postgresql \ 14 | PG_LOG_DIR=/var/log/postgresql 15 | 16 | ENV PG_CONF_DIR="/etc/postgresql/${PG_VERSION}/main" \ 17 | PG_BIN_DIR="/usr/lib/postgresql/${PG_VERSION}/bin" \ 18 | PG_DATA_DIR="${PG_HOME}/${PG_VERSION}/main" 19 | 20 | RUN dpkg-reconfigure locales && apt-get install -y wget sudo \ 21 | && wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \ 22 | && echo 'deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main' > /etc/apt/sources.list.d/pgdg.list \ 23 | && apt-get update && apt-get install -y postgresql-${PG_VERSION} postgresql-client-${PG_VERSION} postgresql-contrib-${PG_VERSION} lbzip2 \ 24 | # Cleaning 25 | && apt-get purge -y --auto-remove wget \ 26 | && rm -rf ${PG_HOME} \ 27 | && rm -rf /var/lib/apt/lists/* \ 28 | && touch /tmp/.EMPTY_DB 29 | 30 | COPY entrypoint.sh /sbin/entrypoint.sh 31 | RUN chmod 755 /sbin/entrypoint.sh 32 | 33 | EXPOSE 5432/tcp 34 | VOLUME ["${PG_HOME}", "${PG_RUN_DIR}"] 35 | CMD ["/sbin/entrypoint.sh"] 36 | -------------------------------------------------------------------------------- /9.5/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:xenial 2 | MAINTAINER romeOz 3 | 4 | ENV OS_LOCALE="en_US.UTF-8" \ 5 | DEBIAN_FRONTEND=noninteractive 6 | RUN apt-get update && apt-get install -y locales && locale-gen ${OS_LOCALE} 7 | ENV LANG=${OS_LOCALE} \ 8 | LANGUAGE=${OS_LOCALE} \ 9 | LC_ALL=${OS_LOCALE} \ 10 | PG_VERSION=9.5 \ 11 | PG_USER=postgres \ 12 | PG_HOME=/var/lib/postgresql \ 13 | PG_RUN_DIR=/run/postgresql \ 14 | PG_LOG_DIR=/var/log/postgresql 15 | 16 | ENV PG_CONF_DIR="/etc/postgresql/${PG_VERSION}/main" \ 17 | PG_BIN_DIR="/usr/lib/postgresql/${PG_VERSION}/bin" \ 18 | PG_DATA_DIR="${PG_HOME}/${PG_VERSION}/main" 19 | 20 | RUN dpkg-reconfigure locales && apt-get install -y wget sudo \ 21 | && wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \ 22 | && echo 'deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main' > /etc/apt/sources.list.d/pgdg.list \ 23 | && apt-get update && apt-get install -y postgresql-${PG_VERSION} postgresql-client-${PG_VERSION} postgresql-contrib-${PG_VERSION} lbzip2 \ 24 | # Cleaning 25 | && apt-get purge -y --auto-remove wget \ 26 | && rm -rf ${PG_HOME} \ 27 | && rm -rf /var/lib/apt/lists/* \ 28 | && touch /tmp/.EMPTY_DB 29 | 30 | COPY entrypoint.sh /sbin/entrypoint.sh 31 | RUN chmod 755 /sbin/entrypoint.sh 32 | 33 | EXPOSE 5432/tcp 34 | VOLUME ["${PG_HOME}", "${PG_RUN_DIR}"] 35 | CMD ["/sbin/entrypoint.sh"] 36 | -------------------------------------------------------------------------------- /9.6/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:xenial 2 | MAINTAINER romeOz 3 | 4 | ENV OS_LOCALE="en_US.UTF-8" \ 5 | DEBIAN_FRONTEND=noninteractive 6 | RUN apt-get update && apt-get install -y locales && locale-gen ${OS_LOCALE} 7 | ENV LANG=${OS_LOCALE} \ 8 | LANGUAGE=${OS_LOCALE} \ 9 | LC_ALL=${OS_LOCALE} \ 10 | PG_VERSION=9.6 \ 11 | PG_USER=postgres \ 12 | PG_HOME=/var/lib/postgresql \ 13 | PG_RUN_DIR=/run/postgresql \ 14 | PG_LOG_DIR=/var/log/postgresql 15 | 16 | ENV PG_CONF_DIR="/etc/postgresql/${PG_VERSION}/main" \ 17 | PG_BIN_DIR="/usr/lib/postgresql/${PG_VERSION}/bin" \ 18 | PG_DATA_DIR="${PG_HOME}/${PG_VERSION}/main" 19 | 20 | RUN dpkg-reconfigure locales && apt-get install -y wget sudo \ 21 | && wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \ 22 | && echo 'deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main' > /etc/apt/sources.list.d/pgdg.list \ 23 | && apt-get update && apt-get install -y postgresql-${PG_VERSION} postgresql-client-${PG_VERSION} postgresql-contrib-${PG_VERSION} lbzip2 \ 24 | # Cleaning 25 | && apt-get purge -y --auto-remove wget \ 26 | && rm -rf ${PG_HOME} \ 27 | && rm -rf /var/lib/apt/lists/* \ 28 | && touch /tmp/.EMPTY_DB 29 | 30 | COPY entrypoint.sh /sbin/entrypoint.sh 31 | RUN chmod 755 /sbin/entrypoint.sh 32 | 33 | EXPOSE 5432/tcp 34 | VOLUME ["${PG_HOME}", "${PG_RUN_DIR}"] 35 | CMD ["/sbin/entrypoint.sh"] 36 | -------------------------------------------------------------------------------- /11/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:bionic 2 | MAINTAINER romeOz 3 | 4 | ENV OS_LOCALE="en_US.UTF-8" \ 5 | DEBIAN_FRONTEND=noninteractive 6 | RUN apt-get update && apt-get install -y locales && locale-gen ${OS_LOCALE} 7 | ENV LANG=${OS_LOCALE} \ 8 | LANGUAGE=${OS_LOCALE} \ 9 | LC_ALL=${OS_LOCALE} \ 10 | PG_VERSION=11 \ 11 | PG_USER=postgres \ 12 | PG_HOME=/var/lib/postgresql \ 13 | PG_RUN_DIR=/run/postgresql \ 14 | PG_LOG_DIR=/var/log/postgresql 15 | 16 | ENV PG_CONF_DIR="/etc/postgresql/${PG_VERSION}/main" \ 17 | PG_BIN_DIR="/usr/lib/postgresql/${PG_VERSION}/bin" \ 18 | PG_DATA_DIR="${PG_HOME}/${PG_VERSION}/main" 19 | 20 | RUN dpkg-reconfigure locales && apt-get install -y wget sudo gnupg \ 21 | && wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \ 22 | && echo 'deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main' > /etc/apt/sources.list.d/pgdg.list \ 23 | && apt-get update && apt-get install -y postgresql-${PG_VERSION} postgresql-client-${PG_VERSION} postgresql-contrib-${PG_VERSION} lbzip2 \ 24 | # Cleaning 25 | && apt-get purge -y --auto-remove wget gnupg \ 26 | && rm -rf ${PG_HOME} \ 27 | && rm -rf /var/lib/apt/lists/* \ 28 | && touch /tmp/.EMPTY_DB 29 | 30 | COPY entrypoint.sh /sbin/entrypoint.sh 31 | RUN chmod 755 /sbin/entrypoint.sh 32 | 33 | EXPOSE 5432/tcp 34 | VOLUME ["${PG_HOME}", "${PG_RUN_DIR}"] 35 | CMD ["/sbin/entrypoint.sh"] -------------------------------------------------------------------------------- /tests/11.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | echo "-- Building PostgreSQL 11 image" 6 | docker build -t psg-11 ../11/ 7 | docker network create pg_test 8 | DIR_VOLUME=$(pwd)/vol11 9 | mkdir -p ${DIR_VOLUME}/backup 10 | 11 | echo 12 | echo "-- Testing PostgreSQL 11 is running" 13 | docker run --name base_1 -d --net pg_test psg-11; sleep 5 14 | docker run --name base_2 -d --net pg_test psg-11; sleep 10 15 | docker exec -it base_2 bash -c 'pg_isready -h base_1 -p 5432 | grep -c "accepting"' 16 | echo 17 | echo "-- Clear" 18 | docker rm -f -v base_1 base_2; sleep 5 19 | 20 | echo 21 | echo "-- Testing backup/checking on PostgreSQL 11" 22 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-11; sleep 10 23 | echo "-- Backup" 24 | docker run -it --rm --net pg_test -e 'PG_MODE=backup' -e 'REPLICATION_HOST=base_1' -e 'REPLICATION_PORT=5432' -v ${DIR_VOLUME}/backup:/tmp/backup psg-11 | grep -wc 'backup completed'; sleep 10 25 | echo "-- Check" 26 | docker run -it --rm -e 'PG_CHECK=default' -e 'DB_NAME=db_1' -v ${DIR_VOLUME}/backup:/tmp/backup psg-11 | tail -n 1 | grep -c 'Success'; sleep 5 27 | docker run -it --rm -e 'PG_CHECK=/tmp/backup/backup.last.tar.bz2' -e 'DB_NAME=test_1' -v ${DIR_VOLUME}/backup:/tmp/backup psg-11 | tail -n 1 | grep -c 'Success'; sleep 5 28 | docker run -it --rm -e 'PG_CHECK=default' -e 'DB_NAME=db' -v ${DIR_VOLUME}/backup:/tmp/backup psg-11 | tail -n 1 | grep -c 'Fail'; sleep 5 29 | echo 30 | echo "-- Clear" 31 | docker rm -f -v base_1; sleep 5 32 | sudo rm -rf ${DIR_VOLUME} 33 | 34 | 35 | echo 36 | echo 37 | echo "-- Testing master/slave on PostgreSQL 11" 38 | echo 39 | echo "-- Create master" 40 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-11; sleep 10 41 | docker exec -it base_1 sudo -u postgres psql test_1 -c "CREATE TABLE foo (id SERIAL, name VARCHAR); INSERT INTO foo (name) VALUES ('Petr');" 42 | echo 43 | echo "-- Create slave" 44 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' -e 'REPLICATION_USER=replica' -e 'REPLICATION_PASS=replica' psg-11; sleep 10 45 | docker run --name base_3 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-11; sleep 10 46 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Tom');"; sleep 5 47 | docker exec -it base_3 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Tom"' 48 | echo 49 | echo "-- Backup" 50 | mkdir -p ${DIR_VOLUME}/backup 51 | docker run -it --rm --net pg_test -e 'PG_MODE=backup' -e 'REPLICATION_HOST=base_1' -e 'REPLICATION_PORT=5432' -v ${DIR_VOLUME}/backup:/tmp/backup psg-11 | grep -wc 'backup completed'; sleep 10 52 | echo 53 | echo "-- Restore slave from backup-master" 54 | docker run --name base_4 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-11; sleep 10 55 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Bob');"; sleep 5 56 | docker exec -it base_3 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Bob"' 57 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 58 | echo 59 | echo "-- Clear" 60 | docker rm -f -v base_1 base_2 base_3 base_4; sleep 5 61 | 62 | echo 63 | echo "-- Restore master from backup-master" 64 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-11; sleep 10 65 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-11; sleep 10 66 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Jack');"; sleep 5 67 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Jack"' 68 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 69 | 70 | echo 71 | echo "-- Clear" 72 | docker rm -f -v base_1 base_2; sleep 5 73 | sudo rm -rf ${DIR_VOLUME} 74 | 75 | echo 76 | echo "-- Create master" 77 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-11; sleep 10 78 | docker exec -it base_1 sudo -u postgres psql test_1 -c "CREATE TABLE foo (id SERIAL, name VARCHAR); INSERT INTO foo (name) VALUES ('Petr');" 79 | echo 80 | echo "-- Create slave" 81 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-11; sleep 10 82 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Chip');"; sleep 5 83 | echo 84 | echo "-- Create slave with WAL" 85 | docker run --name base_3 -d --net pg_test -e 'PG_MODE=slave_wal' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-11; sleep 10 86 | 87 | echo 88 | echo "-- Backup" 89 | mkdir -p ${DIR_VOLUME}/backup 90 | docker run -it --rm --net pg_test -e 'PG_MODE=backup' -e 'REPLICATION_HOST=base_3' -e 'REPLICATION_PORT=5432' -v ${DIR_VOLUME}/backup:/tmp/backup psg-11 | grep -wc 'backup completed'; sleep 10 91 | echo 92 | echo "-- Restore slave from backup-slave" 93 | docker run --name base_4 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-11; sleep 10 94 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Jack');"; sleep 5 95 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Chip"' 96 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Jack"' 97 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 98 | echo 99 | echo "-- Clear" 100 | docker rm -f -v base_1 base_2 base_3 base_4; sleep 5 101 | 102 | echo 103 | echo "-- Restore master from backup-slave" 104 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-11; sleep 10 105 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-11; sleep 10 106 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Tom');"; sleep 5 107 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Tom"' 108 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Chip"' 109 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 110 | 111 | echo 112 | echo "-- Clear" 113 | docker rm -f -v base_1 base_2; sleep 5 114 | sudo rm -rf ${DIR_VOLUME} 115 | 116 | echo 117 | echo 118 | echo "-- Testing failover master on PostgreSQL 11" 119 | echo 120 | echo "-- Create master" 121 | mkdir -p ${DIR_VOLUME}/backup 122 | docker run --name master -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-11; sleep 10 123 | echo 124 | echo "-- Create slaves" 125 | docker run --name slave_1 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-11; sleep 10 126 | docker run --name slave_2 -d --net pg_test -e 'PG_MODE=slave_wal' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-11; sleep 10 127 | docker exec -it master sudo -u postgres psql test_1 -c "CREATE TABLE foo (id SERIAL, name VARCHAR); INSERT INTO foo (name) VALUES ('Petr');"; sleep 5 128 | echo 129 | echo "-- Remove master" 130 | docker rm -f -v master; sleep 5 131 | 132 | echo 133 | echo "-- Apply trigger" 134 | docker exec -it slave_2 touch /tmp/postgresql.trigger; sleep 10 135 | docker exec -it slave_2 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Bob');"; sleep 5 136 | 137 | echo 138 | echo "-- Restore master" 139 | docker run --name master -d --net pg_test -e 'PG_MODE=master_restore' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=slave_2' psg-11; sleep 10 140 | 141 | echo 142 | echo "-- Remove slaves" 143 | docker rm -f -v slave_1 slave_2; sleep 5 144 | 145 | echo 146 | echo "-- Create slaves" 147 | docker run --name slave_1 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-11; sleep 10 148 | docker run --name slave_2 -d --net pg_test -e 'PG_MODE=slave_wal' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-11; sleep 10 149 | docker exec -it master sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Linda');"; sleep 5 150 | 151 | echo 152 | echo "-- Cheking data" 153 | docker exec -it slave_1 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Linda"' 154 | docker exec -it slave_1 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 155 | docker exec -it slave_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Bob"' 156 | docker exec -it slave_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 157 | 158 | echo 159 | echo "-- Clear" 160 | docker rm -f -v slave_1 slave_2 master; sleep 5 161 | docker rmi psg-11 162 | docker network rm pg_test 163 | sudo rm -rf ${DIR_VOLUME} 164 | 165 | echo 166 | echo "-- Done" -------------------------------------------------------------------------------- /tests/10.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | echo "-- Building PostgreSQL 10 image" 6 | docker build -t psg-10 ../10/ 7 | docker network create pg_test 8 | DIR_VOLUME=$(pwd)/vol10 9 | mkdir -p ${DIR_VOLUME}/backup 10 | 11 | echo 12 | echo "-- Testing PostgreSQL 10 is running" 13 | docker run --name base_1 -d --net pg_test psg-10; sleep 5 14 | docker run --name base_2 -d --net pg_test psg-10; sleep 10 15 | docker exec -it base_2 bash -c 'pg_isready -h base_1 -p 5432 | grep -c "accepting"' 16 | echo 17 | echo "-- Clear" 18 | docker rm -f -v base_1 base_2; sleep 5 19 | 20 | echo 21 | echo "-- Testing backup/checking on PostgreSQL 10" 22 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-10; sleep 10 23 | echo "-- Backup" 24 | docker run -it --rm --net pg_test -e 'PG_MODE=backup' -e 'REPLICATION_HOST=base_1' -e 'REPLICATION_PORT=5432' -v ${DIR_VOLUME}/backup:/tmp/backup psg-10 | grep -wc 'backup completed'; sleep 10 25 | echo "-- Check" 26 | docker run -it --rm -e 'PG_CHECK=default' -e 'DB_NAME=db_1' -v ${DIR_VOLUME}/backup:/tmp/backup psg-10 | tail -n 1 | grep -c 'Success'; sleep 5 27 | docker run -it --rm -e 'PG_CHECK=/tmp/backup/backup.last.tar.bz2' -e 'DB_NAME=test_1' -v ${DIR_VOLUME}/backup:/tmp/backup psg-10 | tail -n 1 | grep -c 'Success'; sleep 5 28 | docker run -it --rm -e 'PG_CHECK=default' -e 'DB_NAME=db' -v ${DIR_VOLUME}/backup:/tmp/backup psg-10 | tail -n 1 | grep -c 'Fail'; sleep 5 29 | echo 30 | echo "-- Clear" 31 | docker rm -f -v base_1; sleep 5 32 | sudo rm -rf ${DIR_VOLUME} 33 | 34 | 35 | echo 36 | echo 37 | echo "-- Testing master/slave on PostgreSQL 10" 38 | echo 39 | echo "-- Create master" 40 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-10; sleep 10 41 | docker exec -it base_1 sudo -u postgres psql test_1 -c "CREATE TABLE foo (id SERIAL, name VARCHAR); INSERT INTO foo (name) VALUES ('Petr');" 42 | echo 43 | echo "-- Create slave" 44 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' -e 'REPLICATION_USER=replica' -e 'REPLICATION_PASS=replica' psg-10; sleep 10 45 | docker run --name base_3 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-10; sleep 10 46 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Tom');"; sleep 5 47 | docker exec -it base_3 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Tom"' 48 | echo 49 | echo "-- Backup" 50 | mkdir -p ${DIR_VOLUME}/backup 51 | docker run -it --rm --net pg_test -e 'PG_MODE=backup' -e 'REPLICATION_HOST=base_1' -e 'REPLICATION_PORT=5432' -v ${DIR_VOLUME}/backup:/tmp/backup psg-10 | grep -wc 'backup completed'; sleep 10 52 | echo 53 | echo "-- Restore slave from backup-master" 54 | docker run --name base_4 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-10; sleep 10 55 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Bob');"; sleep 5 56 | docker exec -it base_3 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Bob"' 57 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 58 | echo 59 | echo "-- Clear" 60 | docker rm -f -v base_1 base_2 base_3 base_4; sleep 5 61 | 62 | echo 63 | echo "-- Restore master from backup-master" 64 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-10; sleep 10 65 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-10; sleep 10 66 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Jack');"; sleep 5 67 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Jack"' 68 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 69 | 70 | echo 71 | echo "-- Clear" 72 | docker rm -f -v base_1 base_2; sleep 5 73 | sudo rm -rf ${DIR_VOLUME} 74 | 75 | echo 76 | echo "-- Create master" 77 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-10; sleep 10 78 | docker exec -it base_1 sudo -u postgres psql test_1 -c "CREATE TABLE foo (id SERIAL, name VARCHAR); INSERT INTO foo (name) VALUES ('Petr');" 79 | echo 80 | echo "-- Create slave" 81 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-10; sleep 10 82 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Chip');"; sleep 5 83 | echo 84 | echo "-- Create slave with WAL" 85 | docker run --name base_3 -d --net pg_test -e 'PG_MODE=slave_wal' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-10; sleep 10 86 | 87 | echo 88 | echo "-- Backup" 89 | mkdir -p ${DIR_VOLUME}/backup 90 | docker run -it --rm --net pg_test -e 'PG_MODE=backup' -e 'REPLICATION_HOST=base_3' -e 'REPLICATION_PORT=5432' -v ${DIR_VOLUME}/backup:/tmp/backup psg-10 | grep -wc 'backup completed'; sleep 10 91 | echo 92 | echo "-- Restore slave from backup-slave" 93 | docker run --name base_4 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-10; sleep 10 94 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Jack');"; sleep 5 95 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Chip"' 96 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Jack"' 97 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 98 | echo 99 | echo "-- Clear" 100 | docker rm -f -v base_1 base_2 base_3 base_4; sleep 5 101 | 102 | echo 103 | echo "-- Restore master from backup-slave" 104 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-10; sleep 10 105 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-10; sleep 10 106 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Tom');"; sleep 5 107 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Tom"' 108 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Chip"' 109 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 110 | 111 | echo 112 | echo "-- Clear" 113 | docker rm -f -v base_1 base_2; sleep 5 114 | sudo rm -rf ${DIR_VOLUME} 115 | 116 | echo 117 | echo 118 | echo "-- Testing failover master on PostgreSQL 10" 119 | echo 120 | echo "-- Create master" 121 | mkdir -p ${DIR_VOLUME}/backup 122 | docker run --name master -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-10; sleep 10 123 | echo 124 | echo "-- Create slaves" 125 | docker run --name slave_1 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-10; sleep 10 126 | docker run --name slave_2 -d --net pg_test -e 'PG_MODE=slave_wal' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-10; sleep 10 127 | docker exec -it master sudo -u postgres psql test_1 -c "CREATE TABLE foo (id SERIAL, name VARCHAR); INSERT INTO foo (name) VALUES ('Petr');"; sleep 5 128 | echo 129 | echo "-- Remove master" 130 | docker rm -f -v master; sleep 5 131 | 132 | echo 133 | echo "-- Apply trigger" 134 | docker exec -it slave_2 touch /tmp/postgresql.trigger; sleep 10 135 | docker exec -it slave_2 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Bob');"; sleep 5 136 | 137 | echo 138 | echo "-- Restore master" 139 | docker run --name master -d --net pg_test -e 'PG_MODE=master_restore' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=slave_2' psg-10; sleep 10 140 | 141 | echo 142 | echo "-- Remove slaves" 143 | docker rm -f -v slave_1 slave_2; sleep 5 144 | 145 | echo 146 | echo "-- Create slaves" 147 | docker run --name slave_1 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-10; sleep 10 148 | docker run --name slave_2 -d --net pg_test -e 'PG_MODE=slave_wal' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-10; sleep 10 149 | docker exec -it master sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Linda');"; sleep 5 150 | 151 | echo 152 | echo "-- Cheking data" 153 | docker exec -it slave_1 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Linda"' 154 | docker exec -it slave_1 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 155 | docker exec -it slave_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Bob"' 156 | docker exec -it slave_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 157 | 158 | echo 159 | echo "-- Clear" 160 | docker rm -f -v slave_1 slave_2 master; sleep 5 161 | docker rmi psg-10 162 | docker network rm pg_test 163 | sudo rm -rf ${DIR_VOLUME} 164 | 165 | echo 166 | echo "-- Done" 167 | -------------------------------------------------------------------------------- /tests/95.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | echo "-- Building PostgreSQL 9.5 image" 6 | docker build -t psg-9.5 ../9.5/ 7 | docker network create pg_test 8 | DIR_VOLUME=$(pwd)/vol95 9 | mkdir -p ${DIR_VOLUME}/backup 10 | 11 | echo 12 | echo "-- Testing PostgreSQL 9.5 is running" 13 | docker run --name base_1 -d --net pg_test psg-9.5; sleep 5 14 | docker run --name base_2 -d --net pg_test psg-9.5; sleep 10 15 | docker exec -it base_2 bash -c 'pg_isready -h base_1 -p 5432 | grep -c "accepting"' 16 | echo 17 | echo "-- Clear" 18 | docker rm -f -v base_1 base_2; sleep 5 19 | 20 | echo 21 | echo "-- Testing backup/checking on PostgreSQL 9.5" 22 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-9.5; sleep 10 23 | echo "-- Backup" 24 | docker run -it --rm --net pg_test -e 'PG_MODE=backup' -e 'REPLICATION_HOST=base_1' -e 'REPLICATION_PORT=5432' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.5 | grep -wc 'backup completed'; sleep 10 25 | echo "-- Check" 26 | docker run -it --rm -e 'PG_CHECK=default' -e 'DB_NAME=db_1' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.5 | tail -n 1 | grep -c 'Success'; sleep 5 27 | docker run -it --rm -e 'PG_CHECK=/tmp/backup/backup.last.tar.bz2' -e 'DB_NAME=test_1' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.5 | tail -n 1 | grep -c 'Success'; sleep 5 28 | docker run -it --rm -e 'PG_CHECK=default' -e 'DB_NAME=db' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.5 | tail -n 1 | grep -c 'Fail'; sleep 5 29 | echo 30 | echo "-- Clear" 31 | docker rm -f -v base_1; sleep 5 32 | sudo rm -rf ${DIR_VOLUME} 33 | 34 | 35 | echo 36 | echo 37 | echo "-- Testing master/slave on PostgreSQL 9.5" 38 | echo 39 | echo "-- Create master" 40 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-9.5; sleep 10 41 | docker exec -it base_1 sudo -u postgres psql test_1 -c "CREATE TABLE foo (id SERIAL, name VARCHAR); INSERT INTO foo (name) VALUES ('Petr');" 42 | echo 43 | echo "-- Create slave" 44 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' -e 'REPLICATION_USER=replica' -e 'REPLICATION_PASS=replica' psg-9.5; sleep 10 45 | docker run --name base_3 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.5; sleep 10 46 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Tom');"; sleep 5 47 | docker exec -it base_3 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Tom"' 48 | echo 49 | echo "-- Backup" 50 | mkdir -p ${DIR_VOLUME}/backup 51 | docker run -it --rm --net pg_test -e 'PG_MODE=backup' -e 'REPLICATION_HOST=base_1' -e 'REPLICATION_PORT=5432' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.5 | grep -wc 'backup completed'; sleep 10 52 | echo 53 | echo "-- Restore slave from backup-master" 54 | docker run --name base_4 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.5; sleep 10 55 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Bob');"; sleep 5 56 | docker exec -it base_3 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Bob"' 57 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 58 | echo 59 | echo "-- Clear" 60 | docker rm -f -v base_1 base_2 base_3 base_4; sleep 5 61 | 62 | echo 63 | echo "-- Restore master from backup-master" 64 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.5; sleep 10 65 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.5; sleep 10 66 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Jack');"; sleep 5 67 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Jack"' 68 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 69 | 70 | echo 71 | echo "-- Clear" 72 | docker rm -f -v base_1 base_2; sleep 5 73 | sudo rm -rf ${DIR_VOLUME} 74 | 75 | echo 76 | echo "-- Create master" 77 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-9.5; sleep 10 78 | docker exec -it base_1 sudo -u postgres psql test_1 -c "CREATE TABLE foo (id SERIAL, name VARCHAR); INSERT INTO foo (name) VALUES ('Petr');" 79 | echo 80 | echo "-- Create slave" 81 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.5; sleep 10 82 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Chip');"; sleep 5 83 | echo 84 | echo "-- Create slave with WAL" 85 | docker run --name base_3 -d --net pg_test -e 'PG_MODE=slave_wal' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.5; sleep 10 86 | 87 | echo 88 | echo "-- Backup" 89 | mkdir -p ${DIR_VOLUME}/backup 90 | docker run -it --rm --net pg_test -e 'PG_MODE=backup' -e 'REPLICATION_HOST=base_3' -e 'REPLICATION_PORT=5432' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.5 | grep -wc 'backup completed'; sleep 10 91 | echo 92 | echo "-- Restore slave from backup-slave" 93 | docker run --name base_4 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.5; sleep 10 94 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Jack');"; sleep 5 95 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Chip"' 96 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Jack"' 97 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 98 | echo 99 | echo "-- Clear" 100 | docker rm -f -v base_1 base_2 base_3 base_4; sleep 5 101 | 102 | echo 103 | echo "-- Restore master from backup-slave" 104 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.5; sleep 10 105 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.5; sleep 10 106 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Tom');"; sleep 5 107 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Tom"' 108 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Chip"' 109 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 110 | 111 | echo 112 | echo "-- Clear" 113 | docker rm -f -v base_1 base_2; sleep 5 114 | sudo rm -rf ${DIR_VOLUME} 115 | 116 | echo 117 | echo 118 | echo "-- Testing failover master on PostgreSQL 9.5" 119 | echo 120 | echo "-- Create master" 121 | mkdir -p ${DIR_VOLUME}/backup 122 | docker run --name master -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-9.5; sleep 10 123 | echo 124 | echo "-- Create slaves" 125 | docker run --name slave_1 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-9.5; sleep 10 126 | docker run --name slave_2 -d --net pg_test -e 'PG_MODE=slave_wal' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-9.5; sleep 10 127 | docker exec -it master sudo -u postgres psql test_1 -c "CREATE TABLE foo (id SERIAL, name VARCHAR); INSERT INTO foo (name) VALUES ('Petr');"; sleep 5 128 | echo 129 | echo "-- Remove master" 130 | docker rm -f -v master; sleep 5 131 | 132 | echo 133 | echo "-- Apply trigger" 134 | docker exec -it slave_2 touch /tmp/postgresql.trigger; sleep 10 135 | docker exec -it slave_2 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Bob');"; sleep 5 136 | 137 | echo 138 | echo "-- Restore master" 139 | docker run --name master -d --net pg_test -e 'PG_MODE=master_restore' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=slave_2' psg-9.5; sleep 10 140 | 141 | echo 142 | echo "-- Remove slaves" 143 | docker rm -f -v slave_1 slave_2; sleep 5 144 | 145 | echo 146 | echo "-- Create slaves" 147 | docker run --name slave_1 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-9.5; sleep 10 148 | docker run --name slave_2 -d --net pg_test -e 'PG_MODE=slave_wal' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-9.5; sleep 10 149 | docker exec -it master sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Linda');"; sleep 5 150 | 151 | echo 152 | echo "-- Cheking data" 153 | docker exec -it slave_1 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Linda"' 154 | docker exec -it slave_1 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 155 | docker exec -it slave_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Bob"' 156 | docker exec -it slave_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 157 | 158 | echo 159 | echo "-- Clear" 160 | docker rm -f -v slave_1 slave_2 master; sleep 5 161 | docker rmi psg-9.5 162 | docker network rm pg_test 163 | sudo rm -rf ${DIR_VOLUME} 164 | 165 | echo 166 | echo "-- Done" 167 | -------------------------------------------------------------------------------- /tests/96.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | echo "-- Building PostgreSQL 9.6 image" 6 | docker build -t psg-9.6 ../9.6/ 7 | docker network create pg_test 8 | DIR_VOLUME=$(pwd)/vol96 9 | mkdir -p ${DIR_VOLUME}/backup 10 | 11 | echo 12 | echo "-- Testing PostgreSQL 9.6 is running" 13 | docker run --name base_1 -d --net pg_test psg-9.6; sleep 5 14 | docker run --name base_2 -d --net pg_test psg-9.6; sleep 10 15 | docker exec -it base_2 bash -c 'pg_isready -h base_1 -p 5432 | grep -c "accepting"' 16 | echo 17 | echo "-- Clear" 18 | docker rm -f -v base_1 base_2; sleep 5 19 | 20 | echo 21 | echo "-- Testing backup/checking on PostgreSQL 9.6" 22 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-9.6; sleep 10 23 | echo "-- Backup" 24 | docker run -it --rm --net pg_test -e 'PG_MODE=backup' -e 'REPLICATION_HOST=base_1' -e 'REPLICATION_PORT=5432' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.6 | grep -wc 'backup completed'; sleep 10 25 | echo "-- Check" 26 | docker run -it --rm -e 'PG_CHECK=default' -e 'DB_NAME=db_1' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.6 | tail -n 1 | grep -c 'Success'; sleep 5 27 | docker run -it --rm -e 'PG_CHECK=/tmp/backup/backup.last.tar.bz2' -e 'DB_NAME=test_1' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.6 | tail -n 1 | grep -c 'Success'; sleep 5 28 | docker run -it --rm -e 'PG_CHECK=default' -e 'DB_NAME=db' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.6 | tail -n 1 | grep -c 'Fail'; sleep 5 29 | echo 30 | echo "-- Clear" 31 | docker rm -f -v base_1; sleep 5 32 | sudo rm -rf ${DIR_VOLUME} 33 | 34 | 35 | echo 36 | echo 37 | echo "-- Testing master/slave on PostgreSQL 9.6" 38 | echo 39 | echo "-- Create master" 40 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-9.6; sleep 10 41 | docker exec -it base_1 sudo -u postgres psql test_1 -c "CREATE TABLE foo (id SERIAL, name VARCHAR); INSERT INTO foo (name) VALUES ('Petr');" 42 | echo 43 | echo "-- Create slave" 44 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' -e 'REPLICATION_USER=replica' -e 'REPLICATION_PASS=replica' psg-9.6; sleep 10 45 | docker run --name base_3 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.6; sleep 10 46 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Tom');"; sleep 5 47 | docker exec -it base_3 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Tom"' 48 | echo 49 | echo "-- Backup" 50 | mkdir -p ${DIR_VOLUME}/backup 51 | docker run -it --rm --net pg_test -e 'PG_MODE=backup' -e 'REPLICATION_HOST=base_1' -e 'REPLICATION_PORT=5432' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.6 | grep -wc 'backup completed'; sleep 10 52 | echo 53 | echo "-- Restore slave from backup-master" 54 | docker run --name base_4 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.6; sleep 10 55 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Bob');"; sleep 5 56 | docker exec -it base_3 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Bob"' 57 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 58 | echo 59 | echo "-- Clear" 60 | docker rm -f -v base_1 base_2 base_3 base_4; sleep 5 61 | 62 | echo 63 | echo "-- Restore master from backup-master" 64 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.6; sleep 10 65 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.6; sleep 10 66 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Jack');"; sleep 5 67 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Jack"' 68 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 69 | 70 | echo 71 | echo "-- Clear" 72 | docker rm -f -v base_1 base_2; sleep 5 73 | sudo rm -rf ${DIR_VOLUME} 74 | 75 | echo 76 | echo "-- Create master" 77 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-9.6; sleep 10 78 | docker exec -it base_1 sudo -u postgres psql test_1 -c "CREATE TABLE foo (id SERIAL, name VARCHAR); INSERT INTO foo (name) VALUES ('Petr');" 79 | echo 80 | echo "-- Create slave" 81 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.6; sleep 10 82 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Chip');"; sleep 5 83 | echo 84 | echo "-- Create slave with WAL" 85 | docker run --name base_3 -d --net pg_test -e 'PG_MODE=slave_wal' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.6; sleep 10 86 | 87 | echo 88 | echo "-- Backup" 89 | mkdir -p ${DIR_VOLUME}/backup 90 | docker run -it --rm --net pg_test -e 'PG_MODE=backup' -e 'REPLICATION_HOST=base_3' -e 'REPLICATION_PORT=5432' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.6 | grep -wc 'backup completed'; sleep 10 91 | echo 92 | echo "-- Restore slave from backup-slave" 93 | docker run --name base_4 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.6; sleep 10 94 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Jack');"; sleep 5 95 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Chip"' 96 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Jack"' 97 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 98 | echo 99 | echo "-- Clear" 100 | docker rm -f -v base_1 base_2 base_3 base_4; sleep 5 101 | 102 | echo 103 | echo "-- Restore master from backup-slave" 104 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.6; sleep 10 105 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.6; sleep 10 106 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Tom');"; sleep 5 107 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Tom"' 108 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Chip"' 109 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 110 | 111 | echo 112 | echo "-- Clear" 113 | docker rm -f -v base_1 base_2; sleep 5 114 | sudo rm -rf ${DIR_VOLUME} 115 | 116 | echo 117 | echo 118 | echo "-- Testing failover master on PostgreSQL 9.6" 119 | echo 120 | echo "-- Create master" 121 | mkdir -p ${DIR_VOLUME}/backup 122 | docker run --name master -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-9.6; sleep 10 123 | echo 124 | echo "-- Create slaves" 125 | docker run --name slave_1 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-9.6; sleep 10 126 | docker run --name slave_2 -d --net pg_test -e 'PG_MODE=slave_wal' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-9.6; sleep 10 127 | docker exec -it master sudo -u postgres psql test_1 -c "CREATE TABLE foo (id SERIAL, name VARCHAR); INSERT INTO foo (name) VALUES ('Petr');"; sleep 5 128 | echo 129 | echo "-- Remove master" 130 | docker rm -f -v master; sleep 5 131 | 132 | echo 133 | echo "-- Apply trigger" 134 | docker exec -it slave_2 touch /tmp/postgresql.trigger; sleep 10 135 | docker exec -it slave_2 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Bob');"; sleep 5 136 | 137 | echo 138 | echo "-- Restore master" 139 | docker run --name master -d --net pg_test -e 'PG_MODE=master_restore' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=slave_2' psg-9.6; sleep 10 140 | 141 | echo 142 | echo "-- Remove slaves" 143 | docker rm -f -v slave_1 slave_2; sleep 5 144 | 145 | echo 146 | echo "-- Create slaves" 147 | docker run --name slave_1 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-9.6; sleep 10 148 | docker run --name slave_2 -d --net pg_test -e 'PG_MODE=slave_wal' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-9.6; sleep 10 149 | docker exec -it master sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Linda');"; sleep 5 150 | 151 | echo 152 | echo "-- Cheking data" 153 | docker exec -it slave_1 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Linda"' 154 | docker exec -it slave_1 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 155 | docker exec -it slave_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Bob"' 156 | docker exec -it slave_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 157 | 158 | echo 159 | echo "-- Clear" 160 | docker rm -f -v slave_1 slave_2 master; sleep 5 161 | docker rmi psg-9.6 162 | docker network rm pg_test 163 | sudo rm -rf ${DIR_VOLUME} 164 | 165 | echo 166 | echo "-- Done" 167 | -------------------------------------------------------------------------------- /tests/94.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | echo "-- Building PostgreSQL 9.4 image" 6 | docker build -t psg-9.4 ../9.4/ 7 | docker network create pg_test 8 | DIR_VOLUME=$(pwd)/vol94 9 | mkdir -p ${DIR_VOLUME}/backup 10 | 11 | echo 12 | echo "-- Testing PostgreSQL 9.4 is running" 13 | docker run --name base_1 -d --net pg_test psg-9.4; sleep 5 14 | docker run --name base_2 -d --net pg_test psg-9.4; sleep 10 15 | docker exec -it base_2 bash -c 'pg_isready -h base_1 -p 5432 | grep -c "accepting"' 16 | echo 17 | echo "-- Clear" 18 | docker rm -f -v base_1 base_2; sleep 5 19 | 20 | echo 21 | echo "-- Testing backup/checking on PostgreSQL 9.4" 22 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-9.4; sleep 10 23 | echo "-- Backup" 24 | docker run -it --rm --net pg_test -e 'PG_MODE=backup' -e 'REPLICATION_HOST=base_1' -e 'REPLICATION_PORT=5432' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.4 | grep -wc 'backup completed'; sleep 10 25 | echo "-- Check" 26 | docker run -it --rm -e 'PG_CHECK=default' -e 'DB_NAME=db_1' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.4 | tail -n 1 | grep -c 'Success'; sleep 5 27 | docker run -it --rm -e 'PG_CHECK=/tmp/backup/backup.last.tar.bz2' -e 'DB_NAME=test_1' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.4 | tail -n 1 | grep -c 'Success'; sleep 5 28 | docker run -it --rm -e 'PG_CHECK=default' -e 'DB_NAME=db' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.4 | tail -n 1 | grep -c 'Fail'; sleep 5 29 | echo 30 | echo "-- Clear" 31 | docker rm -f -v base_1; sleep 5 32 | sudo rm -rf ${DIR_VOLUME} 33 | 34 | 35 | echo 36 | echo 37 | echo "-- Testing master/slave on PostgreSQL 9.4" 38 | echo 39 | echo "-- Create master" 40 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-9.4; sleep 10 41 | docker exec -it base_1 sudo -u postgres psql test_1 -c "CREATE TABLE foo (id SERIAL, name VARCHAR); INSERT INTO foo (name) VALUES ('Petr');" 42 | echo 43 | echo "-- Create slave" 44 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' -e 'REPLICATION_USER=replica' -e 'REPLICATION_PASS=replica' psg-9.4; sleep 10 45 | docker run --name base_3 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.4; sleep 10 46 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Tom');"; sleep 5 47 | docker exec -it base_3 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Tom"' 48 | echo 49 | echo "-- Backup" 50 | mkdir -p ${DIR_VOLUME}/backup 51 | docker run -it --rm --net pg_test -e 'PG_MODE=backup' -e 'REPLICATION_HOST=base_1' -e 'REPLICATION_PORT=5432' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.4 | grep -wc 'backup completed'; sleep 10 52 | echo 53 | echo "-- Restore slave from backup-master" 54 | docker run --name base_4 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.4; sleep 10 55 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Bob');"; sleep 5 56 | docker exec -it base_3 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Bob"' 57 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 58 | echo 59 | echo "-- Clear" 60 | docker rm -f -v base_1 base_2 base_3 base_4; sleep 5 61 | 62 | echo 63 | echo "-- Restore master from backup-master" 64 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.4; sleep 10 65 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.4; sleep 10 66 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Jack');"; sleep 5 67 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Jack"' 68 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 69 | 70 | echo 71 | echo "-- Clear" 72 | docker rm -f -v base_1 base_2; sleep 5 73 | sudo sudo rm -rf ${DIR_VOLUME} 74 | 75 | echo 76 | echo "-- Create master" 77 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-9.4; sleep 10 78 | docker exec -it base_1 sudo -u postgres psql test_1 -c "CREATE TABLE foo (id SERIAL, name VARCHAR); INSERT INTO foo (name) VALUES ('Petr');" 79 | echo 80 | echo "-- Create slave" 81 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.4; sleep 10 82 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Chip');"; sleep 5 83 | echo 84 | echo "-- Create slave with WAL" 85 | docker run --name base_3 -d --net pg_test -e 'PG_MODE=slave_wal' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.4; sleep 10 86 | 87 | echo 88 | echo "-- Backup" 89 | mkdir -p ${DIR_VOLUME}/backup 90 | docker run -it --rm --net pg_test -e 'PG_MODE=backup' -e 'REPLICATION_HOST=base_3' -e 'REPLICATION_PORT=5432' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.4 | grep -wc 'backup completed'; sleep 10 91 | echo 92 | echo "-- Restore slave from backup-slave" 93 | docker run --name base_4 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.4; sleep 10 94 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Jack');"; sleep 5 95 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Chip"' 96 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Jack"' 97 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 98 | echo 99 | echo "-- Clear" 100 | docker rm -f -v base_1 base_2 base_3 base_4; sleep 5 101 | 102 | echo 103 | echo "-- Restore master from backup-slave" 104 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.4; sleep 10 105 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.4; sleep 10 106 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Tom');"; sleep 5 107 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Tom"' 108 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Chip"' 109 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 110 | 111 | echo 112 | echo "-- Clear" 113 | docker rm -f -v base_1 base_2; sleep 5 114 | sudo sudo rm -rf ${DIR_VOLUME} 115 | 116 | echo 117 | echo 118 | echo "-- Testing failover master on PostgreSQL 9.4" 119 | echo 120 | echo "-- Create master" 121 | mkdir -p ${DIR_VOLUME}/backup 122 | docker run --name master -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-9.4; sleep 10 123 | echo 124 | echo "-- Create slaves" 125 | docker run --name slave_1 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-9.4; sleep 10 126 | docker run --name slave_2 -d --net pg_test -e 'PG_MODE=slave_wal' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-9.4; sleep 10 127 | docker exec -it master sudo -u postgres psql test_1 -c "CREATE TABLE foo (id SERIAL, name VARCHAR); INSERT INTO foo (name) VALUES ('Petr');"; sleep 5 128 | echo 129 | echo "-- Remove master" 130 | docker rm -f -v master; sleep 5 131 | 132 | echo 133 | echo "-- Apply trigger" 134 | docker exec -it slave_2 touch /tmp/postgresql.trigger; sleep 10 135 | docker exec -it slave_2 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Bob');"; sleep 5 136 | 137 | echo 138 | echo "-- Restore master" 139 | docker run --name master -d --net pg_test -e 'PG_MODE=master_restore' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=slave_2' psg-9.4; sleep 10 140 | 141 | echo 142 | echo "-- Remove slaves" 143 | docker rm -f -v slave_1 slave_2; sleep 5 144 | 145 | echo 146 | echo "-- Create slaves" 147 | docker run --name slave_1 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-9.4; sleep 10 148 | docker run --name slave_2 -d --net pg_test -e 'PG_MODE=slave_wal' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-9.4; sleep 10 149 | docker exec -it master sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Linda');"; sleep 5 150 | 151 | echo 152 | echo "-- Cheking data" 153 | docker exec -it slave_1 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Linda"' 154 | docker exec -it slave_1 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 155 | docker exec -it slave_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Bob"' 156 | docker exec -it slave_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 157 | 158 | echo 159 | echo "-- Clear" 160 | docker rm -f -v slave_1 slave_2 master; sleep 5 161 | docker network rm pg_test 162 | docker rmi psg-9.4 163 | docker network rm pg_test 164 | sudo sudo rm -rf ${DIR_VOLUME} 165 | 166 | echo 167 | echo "-- Done" -------------------------------------------------------------------------------- /tests/93.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | echo 6 | echo 7 | echo "-- Building PostgreSQL 9.3 image" 8 | docker build -t psg-9.3 ../9.3/ 9 | docker network create pg_test 10 | DIR_VOLUME=$(pwd)/vol93 11 | mkdir -p ${DIR_VOLUME}/backup 12 | 13 | echo 14 | echo "-- Testing PostgreSQL 9.3 is running" 15 | docker run --name base_1 --net pg_test -d psg-9.3; sleep 5 16 | docker run --name base_2 --net pg_test -d psg-9.3; sleep 10 17 | docker exec -it base_2 bash -c 'pg_isready -h base_1 -p 5432 | grep -c "accepting"' 18 | echo 19 | echo "-- Clear" 20 | docker rm -f -v base_1 base_2; sleep 5 21 | 22 | echo 23 | echo "-- Testing backup/checking on PostgreSQL 9.3" 24 | docker run --name base_1 --net pg_test -d -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-9.3; sleep 10 25 | echo "-- Backup" 26 | docker run -it --rm --net pg_test -e 'PG_MODE=backup' -e 'REPLICATION_HOST=base_1' -e 'REPLICATION_PORT=5432' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.3 | grep -wc 'backup completed'; sleep 10 27 | echo "-- Check" 28 | docker run -it --rm -e 'PG_CHECK=default' -e 'DB_NAME=db_1' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.3 | tail -n 1 | grep -c 'Success'; sleep 5 29 | docker run -it --rm -e 'PG_CHECK=/tmp/backup/backup.last.tar.bz2' -e 'DB_NAME=test_1' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.3 | tail -n 1 | grep -c 'Success'; sleep 5 30 | docker run -it --rm -e 'PG_CHECK=default' -e 'DB_NAME=db' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.3 | tail -n 1 | grep -c 'Fail'; sleep 5 31 | echo 32 | echo "-- Clear" 33 | docker rm -f -v base_1; sleep 5 34 | sudo rm -rf ${DIR_VOLUME} 35 | 36 | 37 | echo 38 | echo 39 | echo "-- Testing master/slave on PostgreSQL 9.3" 40 | echo 41 | echo "-- Create master" 42 | docker run --name base_1 --net pg_test -d -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-9.3; sleep 10 43 | docker exec -it base_1 sudo -u postgres psql test_1 -c "CREATE TABLE foo (id SERIAL, name VARCHAR); INSERT INTO foo (name) VALUES ('Petr');" 44 | echo 45 | echo "-- Create slave" 46 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' -e 'REPLICATION_USER=replica' -e 'REPLICATION_PASS=replica' psg-9.3; sleep 10 47 | docker run --name base_3 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.3; sleep 10 48 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Tom');"; sleep 5 49 | docker exec -it base_3 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Tom"' 50 | echo 51 | echo "-- Backup" 52 | mkdir -p ${DIR_VOLUME}/backup 53 | docker run -it --rm --net pg_test -e 'PG_MODE=backup' -e 'REPLICATION_HOST=base_1' -e 'REPLICATION_PORT=5432' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.3 | grep -wc 'backup completed'; sleep 10 54 | echo 55 | echo "-- Restore slave from backup-master" 56 | docker run --name base_4 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.3; sleep 10 57 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Bob');"; sleep 5 58 | docker exec -it base_3 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Bob"' 59 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 60 | echo 61 | echo "-- Clear" 62 | docker rm -f -v base_1 base_2 base_3 base_4; sleep 5 63 | 64 | echo 65 | echo "-- Restore master from backup-master" 66 | docker run --name base_1 --net pg_test -d -e 'PG_MODE=master' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.3; sleep 10 67 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.3; sleep 10 68 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Jack');"; sleep 5 69 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Jack"' 70 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 71 | 72 | echo 73 | echo "-- Clear" 74 | docker rm -f -v base_1 base_2; sleep 5 75 | sudo rm -rf ${DIR_VOLUME} 76 | 77 | echo 78 | echo "-- Create master" 79 | docker run --name base_1 --net pg_test -d -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-9.3; sleep 10 80 | docker exec -it base_1 sudo -u postgres psql test_1 -c "CREATE TABLE foo (id SERIAL, name VARCHAR); INSERT INTO foo (name) VALUES ('Petr');" 81 | echo 82 | echo "-- Create slave" 83 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.3; sleep 10 84 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Chip');"; sleep 5 85 | echo 86 | echo "-- Create slave with WAL" 87 | docker run --name base_3 -d --net pg_test -e 'PG_MODE=slave_wal' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.3; sleep 10 88 | 89 | echo 90 | echo "-- Backup" 91 | mkdir -p ${DIR_VOLUME}/backup 92 | docker run -it --rm --net pg_test -e 'PG_MODE=backup' -e 'REPLICATION_HOST=base_3' -e 'REPLICATION_PORT=5432' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.3 | grep -wc 'backup completed'; sleep 10 93 | echo 94 | echo "-- Restore slave from backup-slave" 95 | docker run --name base_4 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.3; sleep 10 96 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Jack');"; sleep 5 97 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Chip"' 98 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Jack"' 99 | docker exec -it base_4 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 100 | echo 101 | echo "-- Clear" 102 | docker rm -f -v base_1 base_2 base_3 base_4; sleep 5 103 | 104 | echo 105 | echo "-- Restore master from backup-slave" 106 | docker run --name base_1 -d --net pg_test -e 'PG_MODE=master' -e 'PG_RESTORE=default' -v ${DIR_VOLUME}/backup:/tmp/backup psg-9.3; sleep 10 107 | docker run --name base_2 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=base_1' psg-9.3; sleep 10 108 | docker exec -it base_1 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Tom');"; sleep 5 109 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Tom"' 110 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Chip"' 111 | docker exec -it base_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 112 | 113 | echo 114 | echo "-- Clear" 115 | docker rm -f -v base_1 base_2; sleep 5 116 | sudo rm -rf ${DIR_VOLUME} 117 | 118 | echo 119 | echo 120 | echo "-- Testing failover master on PostgreSQL 9.3" 121 | echo 122 | echo "-- Create master" 123 | mkdir -p ${DIR_VOLUME}/backup 124 | docker run --name master -d --net pg_test -e 'PG_MODE=master' -e 'DB_NAME=db_1,test_1' psg-9.3; sleep 10 125 | echo 126 | echo "-- Create slaves" 127 | docker run --name slave_1 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-9.3; sleep 10 128 | docker run --name slave_2 -d --net pg_test -e 'PG_MODE=slave_wal' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-9.3; sleep 10 129 | docker exec -it master sudo -u postgres psql test_1 -c "CREATE TABLE foo (id SERIAL, name VARCHAR); INSERT INTO foo (name) VALUES ('Petr');"; sleep 5 130 | echo 131 | echo "-- Remove master" 132 | docker rm -f -v master; sleep 5 133 | 134 | echo 135 | echo "-- Apply trigger" 136 | docker exec -it slave_2 touch /tmp/postgresql.trigger; sleep 10 137 | docker exec -it slave_2 sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Bob');"; sleep 5 138 | 139 | echo 140 | echo "-- Restore master" 141 | docker run --name master -d --net pg_test -e 'PG_MODE=master_restore' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=slave_2' psg-9.3; sleep 10 142 | 143 | echo 144 | echo "-- Remove slaves" 145 | docker rm -f -v slave_1 slave_2; sleep 5 146 | 147 | echo 148 | echo "-- Create slaves" 149 | docker run --name slave_1 -d --net pg_test -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-9.3; sleep 10 150 | docker run --name slave_2 -d --net pg_test -e 'PG_MODE=slave_wal' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=master' psg-9.3; sleep 10 151 | docker exec -it master sudo -u postgres psql test_1 -c "INSERT INTO foo (name) VALUES ('Linda');"; sleep 5 152 | 153 | echo 154 | echo "-- Cheking data" 155 | docker exec -it slave_1 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Linda"' 156 | docker exec -it slave_1 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 157 | docker exec -it slave_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT * FROM foo;" | grep -c -w "Bob"' 158 | docker exec -it slave_2 bash -c 'sudo -u postgres psql test_1 -c "SELECT COUNT(*) FROM foo;" | grep -c -w "3"' 159 | 160 | echo 161 | echo "-- Clear" 162 | docker rm -f -v slave_1 slave_2 master; sleep 5 163 | docker network rm pg_test 164 | docker rmi psg-9.3 165 | docker network rm pg_test 166 | sudo rm -rf ${DIR_VOLUME} 167 | 168 | echo 169 | echo "-- Done" -------------------------------------------------------------------------------- /9.5/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | PG_VERSION=${PG_VERSION:-} 6 | PG_USER=${PG_USER:-} 7 | PG_HOME=${PG_HOME:-} 8 | PG_LOG_DIR=${PG_LOG_DIR:-} 9 | PG_DATA_DIR=${PG_DATA_DIR:-} 10 | PG_RUN_DIR=${PG_RUN_DIR:-} 11 | PG_CONF_DIR=${PG_CONF_DIR:-} 12 | PG_BIN_DIR=${PG_BIN_DIR:-} 13 | PG_TZ=${PG_TZ:-"UTC"} 14 | 15 | PG_BACKUP_DIR=${PG_BACKUP_DIR:-"/tmp/backup"} 16 | PG_BACKUP_FILENAME=${PG_BACKUP_FILENAME:-"backup.last.tar.bz2"} 17 | PG_ROTATE_BACKUP=${PG_ROTATE_BACKUP:-true} 18 | PG_CHECK=${PG_CHECK:-} 19 | PG_RESTORE=${PG_RESTORE:-} 20 | 21 | # set this env variable to true to enable a line in the 22 | # pg_hba.conf file to trust samenet. this can be used to connect 23 | # from other containers on the same host without authentication 24 | PG_TRUST_LOCALNET=${PG_TRUST_LOCALNET:-false} 25 | 26 | DB_NAME=${DB_NAME:-} 27 | DB_USER=${DB_USER:-} 28 | DB_PASS=${DB_PASS:-} 29 | DB_LOCALE=${DB_LOCALE:-"${OS_LOCALE}"} 30 | DB_UNACCENT=${DB_UNACCENT:false} 31 | 32 | # set this environment variable to master, slave or snapshot to use replication features. 33 | # "snapshot" will create a point in time backup of a master instance. 34 | PG_MODE=${PG_MODE:-} 35 | 36 | REPLICATION_USER=${REPLICATION_USER:-replica} 37 | REPLICATION_PASS=${REPLICATION_PASS:-replica} 38 | REPLICATION_HOST=${REPLICATION_HOST:-} 39 | REPLICATION_PORT=${REPLICATION_PORT:-5432} 40 | PG_WAL_SEGMENTS=${PG_WAL_SEGMENTS:-8} 41 | PG_MAX_WAL_SIZE=${PG_MAX_WAL_SIZE:-"1GB"} 42 | PG_MAX_WAL_SENDERS=${PG_MAX_WAL_SENDERS:-3} 43 | 44 | # set this env variable to "require" to enable encryption and "verify-full" for verification. 45 | PG_SSLMODE=${PG_SSLMODE:-disable} 46 | 47 | map_postgres_uid() { 48 | USERMAP_ORIG_UID=$(id -u ${PG_USER}) 49 | USERMAP_ORIG_GID=$(id -g ${PG_USER}) 50 | USERMAP_GID=${USERMAP_GID:-${USERMAP_UID:-$USERMAP_ORIG_GID}} 51 | USERMAP_UID=${USERMAP_UID:-$USERMAP_ORIG_UID} 52 | if [[ ${USERMAP_UID} != ${USERMAP_ORIG_UID} ]] || [[ ${USERMAP_GID} != ${USERMAP_ORIG_GID} ]]; then 53 | echo "Adapting uid and gid for ${PG_USER}:${PG_USER} to $USERMAP_UID:$USERMAP_GID" 54 | groupmod -g ${USERMAP_GID} ${PG_USER} 55 | sed -i -e "s/:${USERMAP_ORIG_UID}:${USERMAP_GID}:/:${USERMAP_UID}:${USERMAP_GID}:/" /etc/passwd 56 | fi 57 | } 58 | 59 | create_home_dir() { 60 | mkdir -p ${PG_HOME} 61 | chmod -R 0700 ${PG_HOME} 62 | chown -R ${PG_USER}:${PG_USER} ${PG_HOME} 63 | } 64 | 65 | create_data_dir() { 66 | mkdir -p ${PG_DATA_DIR} 67 | chmod -R 0700 ${PG_DATA_DIR} 68 | chown -R ${PG_USER}:${PG_USER} ${PG_DATA_DIR} 69 | } 70 | 71 | create_log_dir() { 72 | mkdir -p ${PG_LOG_DIR} 73 | chmod -R 1775 ${PG_LOG_DIR} 74 | chown -R root:${PG_USER} ${PG_LOG_DIR} 75 | } 76 | 77 | create_run_dir() { 78 | mkdir -p ${PG_RUN_DIR} ${PG_RUN_DIR}/${PG_VERSION}-main.pg_stat_tmp 79 | chmod -R 0755 ${PG_RUN_DIR} 80 | chmod g+s ${PG_RUN_DIR} 81 | chown -R ${PG_USER}:${PG_USER} ${PG_RUN_DIR} 82 | } 83 | 84 | create_backup_dir() { 85 | mkdir -p ${PG_BACKUP_DIR}/ 86 | chmod -R 0755 ${PG_BACKUP_DIR} 87 | chown -R root:${PG_USER} ${PG_BACKUP_DIR} 88 | } 89 | 90 | rotate_backup() 91 | { 92 | echo "Rotate backup..." 93 | 94 | if [[ ${PG_ROTATE_BACKUP} == true ]]; then 95 | 96 | WEEK=$(date +"%V") 97 | MONTH=$(date +"%b") 98 | let "INDEX = WEEK % 5" || true 99 | if [[ ${INDEX} == 0 ]]; then 100 | INDEX=4 101 | fi 102 | 103 | test -e ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 && rm ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 104 | mv ${PG_BACKUP_DIR}/backup.tar.bz2 ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 105 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2" 106 | 107 | test -e ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2 && rm ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2 108 | ln ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2 109 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2" 110 | 111 | test -e ${PG_BACKUP_DIR}/backup.last.tar.bz2 && rm ${PG_BACKUP_DIR}/backup.last.tar.bz2 112 | ln ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 ${PG_BACKUP_DIR}/backup.last.tar.bz2 113 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.last.tar.bz2" 114 | else 115 | mv ${PG_BACKUP_DIR}/backup.tar.bz2 ${PG_BACKUP_DIR}/backup.last.tar.bz2 116 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.last.tar.bz2" 117 | fi 118 | } 119 | 120 | import_backup() 121 | { 122 | FILE=$1 123 | if [[ ${FILE} == default ]]; then 124 | FILE="${PG_BACKUP_DIR}/${PG_BACKUP_FILENAME}" 125 | fi 126 | if [[ ! -f "${FILE}" ]]; then 127 | echo "Unknown backup: ${FILE}" 128 | exit 1 129 | fi 130 | create_data_dir 131 | sudo -Hu ${PG_USER} lbzip2 -dc -n 2 ${FILE} | tar -C ${PG_DATA_DIR} -x 132 | } 133 | 134 | remove_recovery_file() 135 | { 136 | if [[ -f "${PG_DATA_DIR}/recovery.conf" ]]; then 137 | echo "Remove file: '${PG_DATA_DIR}/recovery.conf'" 138 | rm ${PG_DATA_DIR}/recovery.conf 139 | fi 140 | } 141 | 142 | # Sets a locale 143 | locale-gen ${DB_LOCALE} && dpkg-reconfigure --frontend=noninteractive locales 144 | 145 | map_postgres_uid 146 | create_home_dir 147 | create_log_dir 148 | create_run_dir 149 | create_backup_dir 150 | 151 | # fix ownership of ${PG_CONF_DIR} (may be necessary if USERMAP_* was set) 152 | chown -R ${PG_USER}:${PG_USER} ${PG_CONF_DIR} 153 | 154 | if [[ ! -f /tmp/.CONFIGURE_1 ]]; then 155 | if [[ ${PG_SSLMODE} == disable ]]; then 156 | sed 's/ssl = true/#ssl = true/' -i ${PG_CONF_DIR}/postgresql.conf 157 | fi 158 | 159 | # Change DSM from `posix' to `sysv' if we are inside an lx-brand container 160 | if [[ $(uname -v) == "BrandZ virtual linux" ]]; then 161 | sed 's/\(dynamic_shared_memory_type = \)posix/\1sysv/' \ 162 | -i ${PG_CONF_DIR}/postgresql.conf 163 | fi 164 | 165 | # listen on all interfaces 166 | cat >> ${PG_CONF_DIR}/postgresql.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/postgresql.conf < ${PG_BACKUP_DIR}/backup.tar.bz2 230 | else 231 | echo "Used host: ${REPLICATION_HOST}" 232 | sudo -Hu ${PG_USER} \ 233 | PGPASSWORD=${REPLICATION_PASS} ${PG_BIN_DIR}/pg_basebackup \ 234 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -x -v -P --format=t ${EXTRA_OPTS} \ 235 | -D - | lbzip2 -n 2 -9 > ${PG_BACKUP_DIR}/backup.tar.bz2 236 | fi 237 | rotate_backup 238 | exit 0 239 | fi 240 | 241 | # Check backup 242 | if [[ -n ${PG_CHECK} ]]; then 243 | 244 | echo "Check backup..." 245 | if [[ -z ${DB_NAME} ]]; then 246 | echo "Unknown database. DB_NAME does not null" 247 | exit 1; 248 | fi 249 | 250 | if [[ ! -d ${PG_DATA_DIR} ]]; then 251 | import_backup ${PG_CHECK} 252 | fi 253 | remove_recovery_file 254 | CHECK=$(echo "SELECT datname FROM pg_database WHERE lower(datname) = lower('${DB_NAME}');" | \ 255 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 256 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf) 257 | 258 | if [[ $(echo ${CHECK} | grep -w ${DB_NAME} | wc -l) == 1 ]]; then 259 | echo "Success checking backup" 260 | else 261 | echo "Fail checking backup" 262 | exit 1 263 | fi 264 | 265 | exit 0 266 | fi 267 | 268 | # Restore from backup 269 | if [[ ! -d ${PG_DATA_DIR} && -n ${PG_RESTORE} ]]; then 270 | if [[ -n ${PG_RESTORE} ]]; then 271 | echo "Import backup..." 272 | import_backup ${PG_RESTORE} 273 | fi 274 | fi 275 | 276 | if [[ ! -d ${PG_DATA_DIR} && ${PG_MODE} == master_restore ]]; then 277 | sudo -Hu ${PG_USER} \ 278 | PGPASSWORD=${REPLICATION_PASS} ${PG_BIN_DIR}/pg_basebackup -D ${PG_DATA_DIR} \ 279 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -x -v -P 280 | fi 281 | 282 | # Create snapshot 283 | if [[ ! -d ${PG_DATA_DIR} && ${PG_MODE} == snapshot ]]; then 284 | echo "Snapshot database..." 285 | sudo -Hu ${PG_USER} \ 286 | PGPASSWORD=${REPLICATION_PASS} ${PG_BIN_DIR}/pg_basebackup -D ${PG_DATA_DIR} \ 287 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -X stream -v -P 288 | 289 | fi 290 | 291 | # Create slave 292 | if [[ ${PG_MODE} =~ ^slave && ! -f /tmp/.CONFIGURE_2 ]]; then 293 | echo "Replicating database..." 294 | if [[ ! -d ${PG_DATA_DIR} ]]; then 295 | # Setup streaming replication. 296 | sudo -Hu ${PG_USER} \ 297 | PGPASSWORD=${REPLICATION_PASS} ${PG_BIN_DIR}/pg_basebackup -D ${PG_DATA_DIR} \ 298 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -X stream -v -P 299 | fi 300 | echo "Setting up hot standby configuration..." 301 | cat >> ${PG_CONF_DIR}/postgresql.conf <> ${PG_DATA_DIR}/recovery.conf </dev/null | sort -r | head -n1 | cut -d'/' -f5) 317 | 318 | echo "Initializing database..." 319 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/initdb --pgdata=${PG_DATA_DIR} \ 320 | --username=${PG_USER} --encoding=unicode --auth=trust >/dev/null 321 | touch /tmp/.EMPTY_DB 322 | fi 323 | 324 | if [[ -n ${PG_OLD_VERSION} ]]; then 325 | echo "Migrating postgresql ${PG_OLD_VERSION} data..." 326 | PG_OLD_CONFDIR="/etc/postgresql/${PG_OLD_VERSION}/main" 327 | PG_OLD_BINDIR="/usr/lib/postgresql/${PG_OLD_VERSION}/bin" 328 | PG_OLD_DATADIR="${PG_HOME}/${PG_OLD_VERSION}/main" 329 | 330 | # backup ${PG_OLD_DATADIR} to avoid data loss 331 | PG_BKP_SUFFIX=$(date +%Y%m%d%H%M%S) 332 | echo "Backing up ${PG_OLD_DATADIR} to ${PG_OLD_DATADIR}.${PG_BKP_SUFFIX}..." 333 | cp -a ${PG_OLD_DATADIR} ${PG_OLD_DATADIR}.${PG_BKP_SUFFIX} 334 | 335 | echo "Installing postgresql-${PG_OLD_VERSION}..." 336 | apt-get update 337 | apt-get install postgresql-${PG_OLD_VERSION} postgresql-client-${PG_OLD_VERSION} 338 | rm -rf /var/lib/apt/lists/* 339 | 340 | # migrate ${PG_OLD_VERSION} data 341 | echo "Migration in progress. This could take a while, please be patient..." 342 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/pg_upgrade \ 343 | -b ${PG_OLD_BINDIR} -B ${PG_BIN_DIR} \ 344 | -d ${PG_OLD_DATADIR} -D ${PG_DATA_DIR} \ 345 | -o "-c config_file=${PG_OLD_CONFDIR}/postgresql.conf" \ 346 | -O "-c config_file=${PG_CONF_DIR}/postgresql.conf" >/dev/null 347 | fi 348 | 349 | # Create databases and users 350 | if [[ -f /tmp/.EMPTY_DB && ( -z ${PG_MODE} || ${PG_MODE} =~ ^master ) ]]; then 351 | 352 | if [[ ${PG_MODE} =~ ^master ]]; then 353 | remove_recovery_file 354 | echo "Creating user \"${REPLICATION_USER}\"..." 355 | echo "CREATE ROLE ${REPLICATION_USER} WITH REPLICATION LOGIN ENCRYPTED PASSWORD '${REPLICATION_PASS}';" | 356 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 357 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 358 | fi 359 | 360 | if [[ -n ${DB_USER} ]]; then 361 | if [[ -z ${DB_PASS} ]]; then 362 | echo "" 363 | echo "WARNING: " 364 | echo " Please specify a password for \"${DB_USER}\". Skipping user creation..." 365 | echo "" 366 | DB_USER= 367 | else 368 | echo "Creating user \"${DB_USER}\"..." 369 | echo "CREATE ROLE ${DB_USER} with LOGIN CREATEDB PASSWORD '${DB_PASS}';" | 370 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 371 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 372 | fi 373 | fi 374 | 375 | if [[ -n ${DB_NAME} ]]; then 376 | for db in $(awk -F',' '{for (i = 1 ; i <= NF ; i++) print $i}' <<< "${DB_NAME}"); do 377 | echo "Creating database \"${db}\"..." 378 | 379 | echo "CREATE DATABASE ${db} ENCODING = 'UTF8' LC_COLLATE = '${DB_LOCALE}' LC_CTYPE = '${DB_LOCALE}' TEMPLATE = template0;" | \ 380 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 381 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 382 | 383 | if [[ ${DB_UNACCENT} == true ]]; then 384 | echo "Installing unaccent extension..." 385 | echo "CREATE EXTENSION IF NOT EXISTS unaccent;" | \ 386 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single ${db} \ 387 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 388 | fi 389 | 390 | if [[ -n ${DB_USER} ]]; then 391 | echo "Granting access to database \"${db}\" for user \"${DB_USER}\"..." 392 | echo "GRANT ALL PRIVILEGES ON DATABASE ${db} to ${DB_USER};" | 393 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 394 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 395 | fi 396 | done 397 | fi 398 | 399 | rm -f /tmp/.EMPTY_DB 400 | fi 401 | 402 | echo "Starting PostgreSQL server..." 403 | exec start-stop-daemon --start --chuid ${PG_USER}:${PG_USER} --exec ${PG_BIN_DIR}/postgres -- \ 404 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf -c timezone=${PG_TZ} -------------------------------------------------------------------------------- /9.3/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | PG_VERSION=${PG_VERSION:-} 5 | PG_USER=${PG_USER:-} 6 | PG_HOME=${PG_HOME:-} 7 | PG_LOG_DIR=${PG_LOG_DIR:-} 8 | PG_DATA_DIR=${PG_DATA_DIR:-} 9 | PG_RUN_DIR=${PG_RUN_DIR:-} 10 | PG_CONF_DIR=${PG_CONF_DIR:-} 11 | PG_BIN_DIR=${PG_BIN_DIR:-} 12 | PG_TZ=${PG_TZ:-"UTC"} 13 | 14 | PG_BACKUP_DIR=${PG_BACKUP_DIR:-"/tmp/backup"} 15 | PG_BACKUP_FILENAME=${PG_BACKUP_FILENAME:-"backup.last.tar.bz2"} 16 | PG_ROTATE_BACKUP=${PG_ROTATE_BACKUP:-true} 17 | PG_CHECK=${PG_CHECK:-} 18 | PG_RESTORE=${PG_RESTORE:-} 19 | 20 | # set this env variable to true to enable a line in the 21 | # pg_hba.conf file to trust samenet. this can be used to connect 22 | # from other containers on the same host without authentication 23 | PG_TRUST_LOCALNET=${PG_TRUST_LOCALNET:-false} 24 | 25 | DB_NAME=${DB_NAME:-} 26 | DB_USER=${DB_USER:-} 27 | DB_PASS=${DB_PASS:-} 28 | DB_LOCALE=${DB_LOCALE:-"${OS_LOCALE}"} 29 | DB_UNACCENT=${DB_UNACCENT:false} 30 | 31 | # set this environment variable to master, slave or snapshot to use replication features. 32 | # "snapshot" will create a point in time backup of a master instance. 33 | PG_MODE=${PG_MODE:-} 34 | 35 | REPLICATION_USER=${REPLICATION_USER:-replica} 36 | REPLICATION_PASS=${REPLICATION_PASS:-replica} 37 | REPLICATION_HOST=${REPLICATION_HOST:-} 38 | REPLICATION_PORT=${REPLICATION_PORT:-5432} 39 | PG_WAL_SEGMENTS=${PG_WAL_SEGMENTS:-8} 40 | PG_CHECKPOINT_SEGMENTS=${PG_CHECKPOINT_SEGMENTS:-8} 41 | PG_MAX_WAL_SENDERS=${PG_MAX_WAL_SENDERS:-3} 42 | 43 | # set this env variable to "require" to enable encryption and "verify-full" for verification. 44 | PG_SSLMODE=${PG_SSLMODE:-disable} 45 | 46 | map_postgres_uid() { 47 | USERMAP_ORIG_UID=$(id -u ${PG_USER}) 48 | USERMAP_ORIG_GID=$(id -g ${PG_USER}) 49 | USERMAP_GID=${USERMAP_GID:-${USERMAP_UID:-$USERMAP_ORIG_GID}} 50 | USERMAP_UID=${USERMAP_UID:-$USERMAP_ORIG_UID} 51 | if [[ ${USERMAP_UID} != ${USERMAP_ORIG_UID} ]] || [[ ${USERMAP_GID} != ${USERMAP_ORIG_GID} ]]; then 52 | echo "Adapting uid and gid for ${PG_USER}:${PG_USER} to $USERMAP_UID:$USERMAP_GID" 53 | groupmod -g ${USERMAP_GID} ${PG_USER} 54 | sed -i -e "s/:${USERMAP_ORIG_UID}:${USERMAP_GID}:/:${USERMAP_UID}:${USERMAP_GID}:/" /etc/passwd 55 | fi 56 | } 57 | 58 | create_home_dir() { 59 | mkdir -p ${PG_HOME} 60 | chmod -R 0700 ${PG_HOME} 61 | chown -R ${PG_USER}:${PG_USER} ${PG_HOME} 62 | } 63 | 64 | create_data_dir() { 65 | mkdir -p ${PG_DATA_DIR} 66 | chmod -R 0700 ${PG_DATA_DIR} 67 | chown -R ${PG_USER}:${PG_USER} ${PG_DATA_DIR} 68 | } 69 | 70 | create_log_dir() { 71 | mkdir -p ${PG_LOG_DIR} 72 | chmod -R 1775 ${PG_LOG_DIR} 73 | chown -R root:${PG_USER} ${PG_LOG_DIR} 74 | } 75 | 76 | create_run_dir() { 77 | mkdir -p ${PG_RUN_DIR} ${PG_RUN_DIR}/${PG_VERSION}-main.pg_stat_tmp 78 | chmod -R 0755 ${PG_RUN_DIR} 79 | chmod g+s ${PG_RUN_DIR} 80 | chown -R ${PG_USER}:${PG_USER} ${PG_RUN_DIR} 81 | } 82 | 83 | create_backup_dir() { 84 | mkdir -p ${PG_BACKUP_DIR}/ 85 | chmod -R 0755 ${PG_BACKUP_DIR} 86 | chown -R root:${PG_USER} ${PG_BACKUP_DIR} 87 | } 88 | 89 | rotate_backup() 90 | { 91 | echo "Rotate backup..." 92 | 93 | if [[ ${PG_ROTATE_BACKUP} == true ]]; then 94 | 95 | WEEK=$(date +"%V") 96 | MONTH=$(date +"%b") 97 | let "INDEX = WEEK % 5" || true 98 | if [[ ${INDEX} == 0 ]]; then 99 | INDEX=4 100 | fi 101 | 102 | test -e ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 && rm ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 103 | mv ${PG_BACKUP_DIR}/backup.tar.bz2 ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 104 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2" 105 | 106 | test -e ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2 && rm ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2 107 | ln ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2 108 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2" 109 | 110 | test -e ${PG_BACKUP_DIR}/backup.last.tar.bz2 && rm ${PG_BACKUP_DIR}/backup.last.tar.bz2 111 | ln ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 ${PG_BACKUP_DIR}/backup.last.tar.bz2 112 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.last.tar.bz2" 113 | else 114 | mv ${PG_BACKUP_DIR}/backup.tar.bz2 ${PG_BACKUP_DIR}/backup.last.tar.bz2 115 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.last.tar.bz2" 116 | fi 117 | } 118 | 119 | import_backup() 120 | { 121 | FILE=$1 122 | if [[ ${FILE} == default ]]; then 123 | FILE="${PG_BACKUP_DIR}/${PG_BACKUP_FILENAME}" 124 | fi 125 | if [[ ! -f "${FILE}" ]]; then 126 | echo "Unknown backup: ${FILE}" 127 | exit 1 128 | fi 129 | create_data_dir 130 | sudo -Hu ${PG_USER} lbzip2 -dc -n 2 ${FILE} | tar -C ${PG_DATA_DIR} -x 131 | } 132 | 133 | remove_recovery_file() 134 | { 135 | if [[ -f "${PG_DATA_DIR}/recovery.conf" ]]; then 136 | echo "Remove file: '${PG_DATA_DIR}/recovery.conf'" 137 | rm ${PG_DATA_DIR}/recovery.conf 138 | fi 139 | } 140 | 141 | # Sets a locale 142 | locale-gen ${DB_LOCALE} && dpkg-reconfigure --frontend=noninteractive locales 143 | 144 | map_postgres_uid 145 | create_home_dir 146 | create_log_dir 147 | create_run_dir 148 | create_backup_dir 149 | 150 | # fix ownership of ${PG_CONF_DIR} (may be necessary if USERMAP_* was set) 151 | chown -R ${PG_USER}:${PG_USER} ${PG_CONF_DIR} 152 | 153 | if [[ ! -f /tmp/.CONFIGURE_1 ]]; then 154 | if [[ ${PG_SSLMODE} == disable ]]; then 155 | sed 's/ssl = true/#ssl = true/' -i ${PG_CONF_DIR}/postgresql.conf 156 | fi 157 | 158 | # Change DSM from `posix' to `sysv' if we are inside an lx-brand container 159 | if [[ $(uname -v) == "BrandZ virtual linux" ]]; then 160 | sed 's/\(dynamic_shared_memory_type = \)posix/\1sysv/' \ 161 | -i ${PG_CONF_DIR}/postgresql.conf 162 | fi 163 | 164 | # listen on all interfaces 165 | cat >> ${PG_CONF_DIR}/postgresql.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/postgresql.conf < ${PG_BACKUP_DIR}/backup.tar.bz2 230 | else 231 | echo "Used host: ${REPLICATION_HOST}" 232 | sudo -Hu ${PG_USER} \ 233 | PGPASSWORD=$REPLICATION_PASS ${PG_BIN_DIR}/pg_basebackup \ 234 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -x -v -P --format=t ${EXTRA_OPTS} \ 235 | -D - | lbzip2 -n 2 -9 > ${PG_BACKUP_DIR}/backup.tar.bz2 236 | fi 237 | rotate_backup 238 | exit 0 239 | fi 240 | 241 | # Check backup 242 | if [[ -n ${PG_CHECK} ]]; then 243 | 244 | echo "Check backup..." 245 | if [[ -z ${DB_NAME} ]]; then 246 | echo "Unknown database. DB_NAME does not null" 247 | exit 1; 248 | fi 249 | 250 | if [[ ! -d ${PG_DATA_DIR} ]]; then 251 | import_backup ${PG_CHECK} 252 | fi 253 | remove_recovery_file 254 | CHECK=$(echo "SELECT datname FROM pg_database WHERE lower(datname) = lower('${DB_NAME}');" | \ 255 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 256 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf) 257 | 258 | if [[ $(echo ${CHECK} | grep -w ${DB_NAME} | wc -l) == 1 ]]; then 259 | echo "Success checking backup" 260 | else 261 | echo "Fail checking backup" 262 | exit 1 263 | fi 264 | 265 | exit 0 266 | fi 267 | 268 | # Restore from backup 269 | if [[ ! -d ${PG_DATA_DIR} && -n ${PG_RESTORE} ]]; then 270 | if [[ -n ${PG_RESTORE} ]]; then 271 | echo "Import backup..." 272 | import_backup ${PG_RESTORE} 273 | fi 274 | fi 275 | 276 | if [[ ! -d ${PG_DATA_DIR} && ${PG_MODE} == master_restore ]]; then 277 | sudo -Hu ${PG_USER} \ 278 | PGPASSWORD=$REPLICATION_PASS ${PG_BIN_DIR}/pg_basebackup -D ${PG_DATA_DIR} \ 279 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -x -v -P 280 | fi 281 | 282 | # Create snapshot 283 | if [[ ! -d ${PG_DATA_DIR} && ${PG_MODE} == snapshot ]]; then 284 | echo "Snapshot database..." 285 | sudo -Hu ${PG_USER} \ 286 | PGPASSWORD=$REPLICATION_PASS ${PG_BIN_DIR}/pg_basebackup -D ${PG_DATA_DIR} \ 287 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -X stream -v -P 288 | 289 | fi 290 | 291 | # Create slave 292 | if [[ ${PG_MODE} =~ ^slave && ! -f /tmp/.CONFIGURE_2 ]]; then 293 | echo "Replicating database..." 294 | if [[ ! -d ${PG_DATA_DIR} ]]; then 295 | # Setup streaming replication. 296 | sudo -Hu ${PG_USER} \ 297 | PGPASSWORD=$REPLICATION_PASS ${PG_BIN_DIR}/pg_basebackup -D ${PG_DATA_DIR} \ 298 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -X stream -v -P 299 | fi 300 | echo "Setting up hot standby configuration..." 301 | cat >> ${PG_CONF_DIR}/postgresql.conf <> ${PG_DATA_DIR}/recovery.conf </dev/null | sort -r | head -n1 | cut -d'/' -f5) 317 | 318 | echo "Initializing database..." 319 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/initdb --pgdata=${PG_DATA_DIR} \ 320 | --username=${PG_USER} --encoding=unicode --auth=trust >/dev/null 321 | touch /tmp/.EMPTY_DB 322 | fi 323 | 324 | if [[ -n ${PG_OLD_VERSION} ]]; then 325 | echo "Migrating postgresql ${PG_OLD_VERSION} data..." 326 | PG_OLD_CONFDIR="/etc/postgresql/${PG_OLD_VERSION}/main" 327 | PG_OLD_BINDIR="/usr/lib/postgresql/${PG_OLD_VERSION}/bin" 328 | PG_OLD_DATADIR="${PG_HOME}/${PG_OLD_VERSION}/main" 329 | 330 | # backup ${PG_OLD_DATADIR} to avoid data loss 331 | PG_BKP_SUFFIX=$(date +%Y%m%d%H%M%S) 332 | echo "Backing up ${PG_OLD_DATADIR} to ${PG_OLD_DATADIR}.${PG_BKP_SUFFIX}..." 333 | cp -a ${PG_OLD_DATADIR} ${PG_OLD_DATADIR}.${PG_BKP_SUFFIX} 334 | 335 | echo "Installing postgresql-${PG_OLD_VERSION}..." 336 | apt-get update 337 | apt-get install postgresql-${PG_OLD_VERSION} postgresql-client-${PG_OLD_VERSION} 338 | rm -rf /var/lib/apt/lists/* 339 | 340 | # migrate ${PG_OLD_VERSION} data 341 | echo "Migration in progress. This could take a while, please be patient..." 342 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/pg_upgrade \ 343 | -b ${PG_OLD_BINDIR} -B ${PG_BIN_DIR} \ 344 | -d ${PG_OLD_DATADIR} -D ${PG_DATA_DIR} \ 345 | -o "-c config_file=${PG_OLD_CONFDIR}/postgresql.conf" \ 346 | -O "-c config_file=${PG_CONF_DIR}/postgresql.conf" >/dev/null 347 | fi 348 | 349 | # Create databases and users 350 | if [[ -f /tmp/.EMPTY_DB && ( -z ${PG_MODE} || ${PG_MODE} =~ ^master ) ]]; then 351 | 352 | if [[ ${PG_MODE} =~ ^master ]]; then 353 | remove_recovery_file 354 | echo "Creating user \"${REPLICATION_USER}\"..." 355 | echo "CREATE ROLE ${REPLICATION_USER} WITH REPLICATION LOGIN ENCRYPTED PASSWORD '${REPLICATION_PASS}';" | 356 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 357 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 358 | fi 359 | 360 | if [[ -n ${DB_USER} ]]; then 361 | if [[ -z ${DB_PASS} ]]; then 362 | echo "" 363 | echo "WARNING: " 364 | echo " Please specify a password for \"${DB_USER}\". Skipping user creation..." 365 | echo "" 366 | DB_USER= 367 | else 368 | echo "Creating user \"${DB_USER}\"..." 369 | echo "CREATE ROLE ${DB_USER} with LOGIN CREATEDB PASSWORD '${DB_PASS}';" | 370 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 371 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 372 | fi 373 | fi 374 | 375 | if [[ -n ${DB_NAME} ]]; then 376 | for db in $(awk -F',' '{for (i = 1 ; i <= NF ; i++) print $i}' <<< "${DB_NAME}"); do 377 | echo "Creating database \"${db}\"..." 378 | 379 | echo "CREATE DATABASE ${db} ENCODING = 'UTF8' LC_COLLATE = '${DB_LOCALE}' LC_CTYPE = '${DB_LOCALE}' TEMPLATE = template0;" | \ 380 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 381 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 382 | 383 | if [[ ${DB_UNACCENT} == true ]]; then 384 | echo "Installing unaccent extension..." 385 | echo "CREATE EXTENSION IF NOT EXISTS unaccent;" | \ 386 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single ${db} \ 387 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 388 | fi 389 | 390 | if [[ -n ${DB_USER} ]]; then 391 | echo "Granting access to database \"${db}\" for user \"${DB_USER}\"..." 392 | echo "GRANT ALL PRIVILEGES ON DATABASE ${db} to ${DB_USER};" | 393 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 394 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 395 | fi 396 | done 397 | fi 398 | 399 | rm -f /tmp/.EMPTY_DB 400 | fi 401 | 402 | echo "Starting PostgreSQL server..." 403 | exec start-stop-daemon --start --chuid ${PG_USER}:${PG_USER} --exec ${PG_BIN_DIR}/postgres -- \ 404 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf -c timezone=${PG_TZ} -------------------------------------------------------------------------------- /9.4/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | PG_VERSION=${PG_VERSION:-} 5 | PG_USER=${PG_USER:-} 6 | PG_HOME=${PG_HOME:-} 7 | PG_LOG_DIR=${PG_LOG_DIR:-} 8 | PG_DATA_DIR=${PG_DATA_DIR:-} 9 | PG_RUN_DIR=${PG_RUN_DIR:-} 10 | PG_CONF_DIR=${PG_CONF_DIR:-} 11 | PG_BIN_DIR=${PG_BIN_DIR:-} 12 | PG_TZ=${PG_TZ:-"UTC"} 13 | 14 | PG_BACKUP_DIR=${PG_BACKUP_DIR:-"/tmp/backup"} 15 | PG_BACKUP_FILENAME=${PG_BACKUP_FILENAME:-"backup.last.tar.bz2"} 16 | PG_ROTATE_BACKUP=${PG_ROTATE_BACKUP:-true} 17 | PG_CHECK=${PG_CHECK:-} 18 | PG_RESTORE=${PG_RESTORE:-} 19 | 20 | # set this env variable to true to enable a line in the 21 | # pg_hba.conf file to trust samenet. this can be used to connect 22 | # from other containers on the same host without authentication 23 | PG_TRUST_LOCALNET=${PG_TRUST_LOCALNET:-false} 24 | 25 | DB_NAME=${DB_NAME:-} 26 | DB_USER=${DB_USER:-} 27 | DB_PASS=${DB_PASS:-} 28 | DB_LOCALE=${DB_LOCALE:-"${OS_LOCALE}"} 29 | DB_UNACCENT=${DB_UNACCENT:false} 30 | 31 | # set this environment variable to master, slave or snapshot to use replication features. 32 | # "snapshot" will create a point in time backup of a master instance. 33 | PG_MODE=${PG_MODE:-} 34 | 35 | REPLICATION_USER=${REPLICATION_USER:-replica} 36 | REPLICATION_PASS=${REPLICATION_PASS:-replica} 37 | REPLICATION_HOST=${REPLICATION_HOST:-} 38 | REPLICATION_PORT=${REPLICATION_PORT:-5432} 39 | PG_WAL_SEGMENTS=${PG_WAL_SEGMENTS:-8} 40 | PG_CHECKPOINT_SEGMENTS=${PG_CHECKPOINT_SEGMENTS:-8} 41 | PG_MAX_WAL_SENDERS=${PG_MAX_WAL_SENDERS:-3} 42 | 43 | # set this env variable to "require" to enable encryption and "verify-full" for verification. 44 | PG_SSLMODE=${PG_SSLMODE:-disable} 45 | 46 | map_postgres_uid() { 47 | USERMAP_ORIG_UID=$(id -u ${PG_USER}) 48 | USERMAP_ORIG_GID=$(id -g ${PG_USER}) 49 | USERMAP_GID=${USERMAP_GID:-${USERMAP_UID:-$USERMAP_ORIG_GID}} 50 | USERMAP_UID=${USERMAP_UID:-$USERMAP_ORIG_UID} 51 | if [[ ${USERMAP_UID} != ${USERMAP_ORIG_UID} ]] || [[ ${USERMAP_GID} != ${USERMAP_ORIG_GID} ]]; then 52 | echo "Adapting uid and gid for ${PG_USER}:${PG_USER} to $USERMAP_UID:$USERMAP_GID" 53 | groupmod -g ${USERMAP_GID} ${PG_USER} 54 | sed -i -e "s/:${USERMAP_ORIG_UID}:${USERMAP_GID}:/:${USERMAP_UID}:${USERMAP_GID}:/" /etc/passwd 55 | fi 56 | } 57 | 58 | create_home_dir() { 59 | mkdir -p ${PG_HOME} 60 | chmod -R 0700 ${PG_HOME} 61 | chown -R ${PG_USER}:${PG_USER} ${PG_HOME} 62 | } 63 | 64 | create_data_dir() { 65 | mkdir -p ${PG_DATA_DIR} 66 | chmod -R 0700 ${PG_DATA_DIR} 67 | chown -R ${PG_USER}:${PG_USER} ${PG_DATA_DIR} 68 | } 69 | 70 | create_log_dir() { 71 | mkdir -p ${PG_LOG_DIR} 72 | chmod -R 1775 ${PG_LOG_DIR} 73 | chown -R root:${PG_USER} ${PG_LOG_DIR} 74 | } 75 | 76 | create_run_dir() { 77 | mkdir -p ${PG_RUN_DIR} ${PG_RUN_DIR}/${PG_VERSION}-main.pg_stat_tmp 78 | chmod -R 0755 ${PG_RUN_DIR} 79 | chmod g+s ${PG_RUN_DIR} 80 | chown -R ${PG_USER}:${PG_USER} ${PG_RUN_DIR} 81 | } 82 | 83 | create_backup_dir() { 84 | mkdir -p ${PG_BACKUP_DIR}/ 85 | chmod -R 0755 ${PG_BACKUP_DIR} 86 | chown -R root:${PG_USER} ${PG_BACKUP_DIR} 87 | } 88 | 89 | rotate_backup() 90 | { 91 | echo "Rotate backup..." 92 | 93 | if [[ ${PG_ROTATE_BACKUP} == true ]]; then 94 | 95 | WEEK=$(date +"%V") 96 | MONTH=$(date +"%b") 97 | let "INDEX = WEEK % 5" || true 98 | if [[ ${INDEX} == 0 ]]; then 99 | INDEX=4 100 | fi 101 | 102 | test -e ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 && rm ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 103 | mv ${PG_BACKUP_DIR}/backup.tar.bz2 ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 104 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2" 105 | 106 | test -e ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2 && rm ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2 107 | ln ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2 108 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2" 109 | 110 | test -e ${PG_BACKUP_DIR}/backup.last.tar.bz2 && rm ${PG_BACKUP_DIR}/backup.last.tar.bz2 111 | ln ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 ${PG_BACKUP_DIR}/backup.last.tar.bz2 112 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.last.tar.bz2" 113 | else 114 | mv ${PG_BACKUP_DIR}/backup.tar.bz2 ${PG_BACKUP_DIR}/backup.last.tar.bz2 115 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.last.tar.bz2" 116 | fi 117 | } 118 | 119 | import_backup() 120 | { 121 | FILE=$1 122 | if [[ ${FILE} == default ]]; then 123 | FILE="${PG_BACKUP_DIR}/${PG_BACKUP_FILENAME}" 124 | fi 125 | if [[ ! -f "${FILE}" ]]; then 126 | echo "Unknown backup: ${FILE}" 127 | exit 1 128 | fi 129 | create_data_dir 130 | sudo -Hu ${PG_USER} lbzip2 -dc -n 2 ${FILE} | tar -C ${PG_DATA_DIR} -x 131 | } 132 | 133 | remove_recovery_file() 134 | { 135 | if [[ -f "${PG_DATA_DIR}/recovery.conf" ]]; then 136 | echo "Remove file: '${PG_DATA_DIR}/recovery.conf'" 137 | rm ${PG_DATA_DIR}/recovery.conf 138 | fi 139 | } 140 | 141 | # Sets a locale 142 | locale-gen ${DB_LOCALE} && dpkg-reconfigure --frontend=noninteractive locales 143 | 144 | map_postgres_uid 145 | create_home_dir 146 | create_log_dir 147 | create_run_dir 148 | create_backup_dir 149 | 150 | # fix ownership of ${PG_CONF_DIR} (may be necessary if USERMAP_* was set) 151 | chown -R ${PG_USER}:${PG_USER} ${PG_CONF_DIR} 152 | 153 | if [[ ! -f /tmp/.CONFIGURE_1 ]]; then 154 | if [[ ${PG_SSLMODE} == disable ]]; then 155 | sed 's/ssl = true/#ssl = true/' -i ${PG_CONF_DIR}/postgresql.conf 156 | fi 157 | 158 | # Change DSM from `posix' to `sysv' if we are inside an lx-brand container 159 | if [[ $(uname -v) == "BrandZ virtual linux" ]]; then 160 | sed 's/\(dynamic_shared_memory_type = \)posix/\1sysv/' \ 161 | -i ${PG_CONF_DIR}/postgresql.conf 162 | fi 163 | 164 | # listen on all interfaces 165 | cat >> ${PG_CONF_DIR}/postgresql.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/postgresql.conf < ${PG_BACKUP_DIR}/backup.tar.bz2 230 | else 231 | echo "Used host: ${REPLICATION_HOST}" 232 | sudo -Hu ${PG_USER} \ 233 | PGPASSWORD=$REPLICATION_PASS ${PG_BIN_DIR}/pg_basebackup \ 234 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -x -v -P --format=t ${EXTRA_OPTS} \ 235 | -D - | lbzip2 -n 2 -9 > ${PG_BACKUP_DIR}/backup.tar.bz2 236 | fi 237 | rotate_backup 238 | exit 0 239 | fi 240 | 241 | # Check backup 242 | if [[ -n ${PG_CHECK} ]]; then 243 | 244 | echo "Check backup..." 245 | if [[ -z ${DB_NAME} ]]; then 246 | echo "Unknown database. DB_NAME does not null" 247 | exit 1; 248 | fi 249 | 250 | if [[ ! -d ${PG_DATA_DIR} ]]; then 251 | import_backup ${PG_CHECK} 252 | fi 253 | remove_recovery_file 254 | CHECK=$(echo "SELECT datname FROM pg_database WHERE lower(datname) = lower('${DB_NAME}');" | \ 255 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 256 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf) 257 | 258 | if [[ $(echo ${CHECK} | grep -w ${DB_NAME} | wc -l) == 1 ]]; then 259 | echo "Success checking backup" 260 | else 261 | echo "Fail checking backup" 262 | exit 1 263 | fi 264 | 265 | exit 0 266 | fi 267 | 268 | # Restore from backup 269 | if [[ ! -d ${PG_DATA_DIR} && -n ${PG_RESTORE} ]]; then 270 | if [[ -n ${PG_RESTORE} ]]; then 271 | echo "Import backup..." 272 | import_backup ${PG_RESTORE} 273 | fi 274 | fi 275 | 276 | if [[ ! -d ${PG_DATA_DIR} && ${PG_MODE} == master_restore ]]; then 277 | sudo -Hu ${PG_USER} \ 278 | PGPASSWORD=$REPLICATION_PASS ${PG_BIN_DIR}/pg_basebackup -D ${PG_DATA_DIR} \ 279 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -x -v -P 280 | fi 281 | 282 | # Create snapshot 283 | if [[ ! -d ${PG_DATA_DIR} && ${PG_MODE} == snapshot ]]; then 284 | echo "Snapshot database..." 285 | sudo -Hu ${PG_USER} \ 286 | PGPASSWORD=$REPLICATION_PASS ${PG_BIN_DIR}/pg_basebackup -D ${PG_DATA_DIR} \ 287 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -X stream -v -P 288 | 289 | fi 290 | 291 | # Create slave 292 | if [[ ${PG_MODE} =~ ^slave && ! -f /tmp/.CONFIGURE_2 ]]; then 293 | echo "Replicating database..." 294 | if [[ ! -d ${PG_DATA_DIR} ]]; then 295 | # Setup streaming replication. 296 | sudo -Hu ${PG_USER} \ 297 | PGPASSWORD=$REPLICATION_PASS ${PG_BIN_DIR}/pg_basebackup -D ${PG_DATA_DIR} \ 298 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -X stream -v -P 299 | fi 300 | echo "Setting up hot standby configuration..." 301 | cat >> ${PG_CONF_DIR}/postgresql.conf <> ${PG_DATA_DIR}/recovery.conf </dev/null | sort -r | head -n1 | cut -d'/' -f5) 317 | 318 | echo "Initializing database..." 319 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/initdb --pgdata=${PG_DATA_DIR} \ 320 | --username=${PG_USER} --encoding=unicode --auth=trust >/dev/null 321 | touch /tmp/.EMPTY_DB 322 | fi 323 | 324 | if [[ -n ${PG_OLD_VERSION} ]]; then 325 | echo "Migrating postgresql ${PG_OLD_VERSION} data..." 326 | PG_OLD_CONFDIR="/etc/postgresql/${PG_OLD_VERSION}/main" 327 | PG_OLD_BINDIR="/usr/lib/postgresql/${PG_OLD_VERSION}/bin" 328 | PG_OLD_DATADIR="${PG_HOME}/${PG_OLD_VERSION}/main" 329 | 330 | # backup ${PG_OLD_DATADIR} to avoid data loss 331 | PG_BKP_SUFFIX=$(date +%Y%m%d%H%M%S) 332 | echo "Backing up ${PG_OLD_DATADIR} to ${PG_OLD_DATADIR}.${PG_BKP_SUFFIX}..." 333 | cp -a ${PG_OLD_DATADIR} ${PG_OLD_DATADIR}.${PG_BKP_SUFFIX} 334 | 335 | echo "Installing postgresql-${PG_OLD_VERSION}..." 336 | apt-get update 337 | apt-get install postgresql-${PG_OLD_VERSION} postgresql-client-${PG_OLD_VERSION} 338 | rm -rf /var/lib/apt/lists/* 339 | 340 | # migrate ${PG_OLD_VERSION} data 341 | echo "Migration in progress. This could take a while, please be patient..." 342 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/pg_upgrade \ 343 | -b ${PG_OLD_BINDIR} -B ${PG_BIN_DIR} \ 344 | -d ${PG_OLD_DATADIR} -D ${PG_DATA_DIR} \ 345 | -o "-c config_file=${PG_OLD_CONFDIR}/postgresql.conf" \ 346 | -O "-c config_file=${PG_CONF_DIR}/postgresql.conf" >/dev/null 347 | fi 348 | 349 | # Create databases and users 350 | if [[ -f /tmp/.EMPTY_DB && ( -z ${PG_MODE} || ${PG_MODE} =~ ^master ) ]]; then 351 | 352 | if [[ ${PG_MODE} =~ ^master ]]; then 353 | remove_recovery_file 354 | echo "Creating user \"${REPLICATION_USER}\"..." 355 | echo "CREATE ROLE ${REPLICATION_USER} WITH REPLICATION LOGIN ENCRYPTED PASSWORD '${REPLICATION_PASS}';" | 356 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 357 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 358 | fi 359 | 360 | if [[ -n ${DB_USER} ]]; then 361 | if [[ -z ${DB_PASS} ]]; then 362 | echo "" 363 | echo "WARNING: " 364 | echo " Please specify a password for \"${DB_USER}\". Skipping user creation..." 365 | echo "" 366 | DB_USER= 367 | else 368 | echo "Creating user \"${DB_USER}\"..." 369 | echo "CREATE ROLE ${DB_USER} with LOGIN CREATEDB PASSWORD '${DB_PASS}';" | 370 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 371 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 372 | fi 373 | fi 374 | 375 | if [[ -n ${DB_NAME} ]]; then 376 | for db in $(awk -F',' '{for (i = 1 ; i <= NF ; i++) print $i}' <<< "${DB_NAME}"); do 377 | echo "Creating database \"${db}\"..." 378 | 379 | echo "CREATE DATABASE ${db} ENCODING = 'UTF8' LC_COLLATE = '${DB_LOCALE}' LC_CTYPE = '${DB_LOCALE}' TEMPLATE = template0;" | \ 380 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 381 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 382 | 383 | if [[ ${DB_UNACCENT} == true ]]; then 384 | echo "Installing unaccent extension..." 385 | echo "CREATE EXTENSION IF NOT EXISTS unaccent;" | \ 386 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single ${db} \ 387 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 388 | fi 389 | 390 | if [[ -n ${DB_USER} ]]; then 391 | echo "Granting access to database \"${db}\" for user \"${DB_USER}\"..." 392 | echo "GRANT ALL PRIVILEGES ON DATABASE ${db} to ${DB_USER};" | 393 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 394 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 395 | fi 396 | done 397 | fi 398 | 399 | rm -f /tmp/.EMPTY_DB 400 | fi 401 | 402 | echo "Starting PostgreSQL server..." 403 | exec start-stop-daemon --start --chuid ${PG_USER}:${PG_USER} --exec ${PG_BIN_DIR}/postgres -- \ 404 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf -c timezone=${PG_TZ} -------------------------------------------------------------------------------- /10/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | PG_VERSION=${PG_VERSION:-} 6 | PG_USER=${PG_USER:-} 7 | PG_HOME=${PG_HOME:-} 8 | PG_LOG_DIR=${PG_LOG_DIR:-} 9 | PG_DATA_DIR=${PG_DATA_DIR:-} 10 | PG_RUN_DIR=${PG_RUN_DIR:-} 11 | PG_CONF_DIR=${PG_CONF_DIR:-} 12 | PG_BIN_DIR=${PG_BIN_DIR:-} 13 | PG_TZ=${PG_TZ:-"UTC"} 14 | 15 | PG_BACKUP_DIR=${PG_BACKUP_DIR:-"/tmp/backup"} 16 | PG_BACKUP_FILENAME=${PG_BACKUP_FILENAME:-"backup.last.tar.bz2"} 17 | PG_ROTATE_BACKUP=${PG_ROTATE_BACKUP:-true} 18 | PG_CHECK=${PG_CHECK:-} 19 | PG_RESTORE=${PG_RESTORE:-} 20 | 21 | # set this env variable to true to enable a line in the 22 | # pg_hba.conf file to trust samenet. this can be used to connect 23 | # from other containers on the same host without authentication 24 | PG_TRUST_LOCALNET=${PG_TRUST_LOCALNET:-false} 25 | 26 | DB_NAME=${DB_NAME:-} 27 | DB_USER=${DB_USER:-} 28 | DB_PASS=${DB_PASS:-} 29 | DB_LOCALE=${DB_LOCALE:-"${OS_LOCALE}"} 30 | DB_UNACCENT=${DB_UNACCENT:false} 31 | 32 | # set this environment variable to master, slave or snapshot to use replication features. 33 | # "snapshot" will create a point in time backup of a master instance. 34 | PG_MODE=${PG_MODE:-} 35 | 36 | REPLICATION_USER=${REPLICATION_USER:-replica} 37 | REPLICATION_PASS=${REPLICATION_PASS:-replica} 38 | REPLICATION_HOST=${REPLICATION_HOST:-} 39 | REPLICATION_PORT=${REPLICATION_PORT:-5432} 40 | PG_WAL_SEGMENTS=${PG_WAL_SEGMENTS:-8} 41 | PG_MAX_WAL_SIZE=${PG_MAX_WAL_SIZE:-"1GB"} 42 | PG_MAX_WAL_SENDERS=${PG_MAX_WAL_SENDERS:-3} 43 | 44 | # set this env variable to "require" to enable encryption and "verify-full" for verification. 45 | PG_SSLMODE=${PG_SSLMODE:-disable} 46 | 47 | map_postgres_uid() { 48 | USERMAP_ORIG_UID=$(id -u ${PG_USER}) 49 | USERMAP_ORIG_GID=$(id -g ${PG_USER}) 50 | USERMAP_GID=${USERMAP_GID:-${USERMAP_UID:-$USERMAP_ORIG_GID}} 51 | USERMAP_UID=${USERMAP_UID:-$USERMAP_ORIG_UID} 52 | if [[ ${USERMAP_UID} != ${USERMAP_ORIG_UID} ]] || [[ ${USERMAP_GID} != ${USERMAP_ORIG_GID} ]]; then 53 | echo "Adapting uid and gid for ${PG_USER}:${PG_USER} to $USERMAP_UID:$USERMAP_GID" 54 | groupmod -g ${USERMAP_GID} ${PG_USER} 55 | sed -i -e "s/:${USERMAP_ORIG_UID}:${USERMAP_GID}:/:${USERMAP_UID}:${USERMAP_GID}:/" /etc/passwd 56 | fi 57 | } 58 | 59 | create_home_dir() { 60 | mkdir -p ${PG_HOME} 61 | chmod -R 0700 ${PG_HOME} 62 | chown -R ${PG_USER}:${PG_USER} ${PG_HOME} 63 | } 64 | 65 | create_data_dir() { 66 | mkdir -p ${PG_DATA_DIR} 67 | chmod -R 0700 ${PG_DATA_DIR} 68 | chown -R ${PG_USER}:${PG_USER} ${PG_DATA_DIR} 69 | } 70 | 71 | create_log_dir() { 72 | mkdir -p ${PG_LOG_DIR} 73 | chmod -R 1775 ${PG_LOG_DIR} 74 | chown -R root:${PG_USER} ${PG_LOG_DIR} 75 | } 76 | 77 | create_run_dir() { 78 | mkdir -p ${PG_RUN_DIR} ${PG_RUN_DIR}/${PG_VERSION}-main.pg_stat_tmp 79 | chmod -R 0755 ${PG_RUN_DIR} 80 | chmod g+s ${PG_RUN_DIR} 81 | chown -R ${PG_USER}:${PG_USER} ${PG_RUN_DIR} 82 | } 83 | 84 | create_backup_dir() { 85 | mkdir -p ${PG_BACKUP_DIR}/ 86 | chmod -R 0755 ${PG_BACKUP_DIR} 87 | chown -R root:${PG_USER} ${PG_BACKUP_DIR} 88 | } 89 | 90 | rotate_backup() 91 | { 92 | echo "Rotate backup..." 93 | 94 | if [[ ${PG_ROTATE_BACKUP} == true ]]; then 95 | 96 | WEEK=$(date +"%V") 97 | MONTH=$(date +"%b") 98 | let "INDEX = WEEK % 5" || true 99 | if [[ ${INDEX} == 0 ]]; then 100 | INDEX=4 101 | fi 102 | 103 | test -e ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 && rm ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 104 | mv ${PG_BACKUP_DIR}/backup.tar.bz2 ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 105 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2" 106 | 107 | test -e ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2 && rm ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2 108 | ln ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2 109 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2" 110 | 111 | test -e ${PG_BACKUP_DIR}/backup.last.tar.bz2 && rm ${PG_BACKUP_DIR}/backup.last.tar.bz2 112 | ln ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 ${PG_BACKUP_DIR}/backup.last.tar.bz2 113 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.last.tar.bz2" 114 | else 115 | mv ${PG_BACKUP_DIR}/backup.tar.bz2 ${PG_BACKUP_DIR}/backup.last.tar.bz2 116 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.last.tar.bz2" 117 | fi 118 | } 119 | 120 | import_backup() 121 | { 122 | FILE=$1 123 | if [[ ${FILE} == default ]]; then 124 | FILE="${PG_BACKUP_DIR}/${PG_BACKUP_FILENAME}" 125 | fi 126 | if [[ ! -f "${FILE}" ]]; then 127 | echo "Unknown backup: ${FILE}" 128 | exit 1 129 | fi 130 | create_data_dir 131 | sudo -Hu ${PG_USER} lbzip2 -dc -n 2 ${FILE} | tar -C ${PG_DATA_DIR} -x 132 | } 133 | 134 | remove_recovery_file() 135 | { 136 | if [[ -f "${PG_DATA_DIR}/recovery.conf" ]]; then 137 | echo "Remove file: '${PG_DATA_DIR}/recovery.conf'" 138 | rm ${PG_DATA_DIR}/recovery.conf 139 | fi 140 | } 141 | 142 | # Sets a locale 143 | locale-gen ${DB_LOCALE} && dpkg-reconfigure --frontend=noninteractive locales 144 | 145 | map_postgres_uid 146 | create_home_dir 147 | create_log_dir 148 | create_run_dir 149 | create_backup_dir 150 | 151 | # fix ownership of ${PG_CONF_DIR} (may be necessary if USERMAP_* was set) 152 | chown -R ${PG_USER}:${PG_USER} ${PG_CONF_DIR} 153 | 154 | if [[ ! -f /tmp/.CONFIGURE_1 ]]; then 155 | if [[ ${PG_SSLMODE} == disable ]]; then 156 | sed 's/ssl = true/#ssl = true/' -i ${PG_CONF_DIR}/postgresql.conf 157 | fi 158 | 159 | # Change DSM from `posix' to `sysv' if we are inside an lx-brand container 160 | if [[ $(uname -v) == "BrandZ virtual linux" ]]; then 161 | sed 's/\(dynamic_shared_memory_type = \)posix/\1sysv/' \ 162 | -i ${PG_CONF_DIR}/postgresql.conf 163 | fi 164 | 165 | # listen on all interfaces 166 | cat >> ${PG_CONF_DIR}/postgresql.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/postgresql.conf < ${PG_BACKUP_DIR}/backup.tar.bz2 230 | else 231 | echo "Used host: ${REPLICATION_HOST}" 232 | sudo -Hu ${PG_USER} \ 233 | PGPASSWORD=${REPLICATION_PASS} ${PG_BIN_DIR}/pg_basebackup \ 234 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -X fetch -v -P --format=t ${EXTRA_OPTS} \ 235 | -D - | lbzip2 -n 2 -9 > ${PG_BACKUP_DIR}/backup.tar.bz2 236 | fi 237 | rotate_backup 238 | exit 0 239 | fi 240 | 241 | # Check backup 242 | if [[ -n ${PG_CHECK} ]]; then 243 | 244 | echo "Check backup..." 245 | if [[ -z ${DB_NAME} ]]; then 246 | echo "Unknown database. DB_NAME does not null" 247 | exit 1; 248 | fi 249 | 250 | if [[ ! -d ${PG_DATA_DIR} ]]; then 251 | import_backup ${PG_CHECK} 252 | fi 253 | remove_recovery_file 254 | CHECK=$(echo "SELECT datname FROM pg_database WHERE lower(datname) = lower('${DB_NAME}');" | \ 255 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 256 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf) 257 | 258 | if [[ $(echo ${CHECK} | grep -w ${DB_NAME} | wc -l) == 1 ]]; then 259 | echo "Success checking backup" 260 | else 261 | echo "Fail checking backup" 262 | exit 1 263 | fi 264 | 265 | exit 0 266 | fi 267 | 268 | # Restore from backup 269 | if [[ ! -d ${PG_DATA_DIR} && -n ${PG_RESTORE} ]]; then 270 | if [[ -n ${PG_RESTORE} ]]; then 271 | echo "Import backup..." 272 | import_backup ${PG_RESTORE} 273 | fi 274 | fi 275 | 276 | if [[ ! -d ${PG_DATA_DIR} && ${PG_MODE} == master_restore ]]; then 277 | sudo -Hu ${PG_USER} \ 278 | PGPASSWORD=${REPLICATION_PASS} ${PG_BIN_DIR}/pg_basebackup -D ${PG_DATA_DIR} \ 279 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -X fetch -v -P 280 | fi 281 | 282 | # Create snapshot 283 | if [[ ! -d ${PG_DATA_DIR} && ${PG_MODE} == snapshot ]]; then 284 | echo "Snapshot database..." 285 | sudo -Hu ${PG_USER} \ 286 | PGPASSWORD=${REPLICATION_PASS} ${PG_BIN_DIR}/pg_basebackup -D ${PG_DATA_DIR} \ 287 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -X stream -v -P 288 | 289 | fi 290 | 291 | # Create slave 292 | if [[ ${PG_MODE} =~ ^slave && ! -f /tmp/.CONFIGURE_2 ]]; then 293 | echo "Replicating database..." 294 | if [[ ! -d ${PG_DATA_DIR} ]]; then 295 | # Setup streaming replication. 296 | sudo -Hu ${PG_USER} \ 297 | PGPASSWORD=${REPLICATION_PASS} ${PG_BIN_DIR}/pg_basebackup -D ${PG_DATA_DIR} \ 298 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -X stream -v -P 299 | fi 300 | echo "Setting up hot standby configuration..." 301 | cat >> ${PG_CONF_DIR}/postgresql.conf <> ${PG_DATA_DIR}/recovery.conf </dev/null | sort -r | head -n1 | cut -d'/' -f5) 317 | 318 | echo "Initializing database..." 319 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/initdb --pgdata=${PG_DATA_DIR} \ 320 | --username=${PG_USER} --encoding=unicode --auth=trust >/dev/null 321 | touch /tmp/.EMPTY_DB 322 | fi 323 | 324 | if [[ -n ${PG_OLD_VERSION} ]]; then 325 | echo "Migrating postgresql ${PG_OLD_VERSION} data..." 326 | PG_OLD_CONFDIR="/etc/postgresql/${PG_OLD_VERSION}/main" 327 | PG_OLD_BINDIR="/usr/lib/postgresql/${PG_OLD_VERSION}/bin" 328 | PG_OLD_DATADIR="${PG_HOME}/${PG_OLD_VERSION}/main" 329 | 330 | # backup ${PG_OLD_DATADIR} to avoid data loss 331 | PG_BKP_SUFFIX=$(date +%Y%m%d%H%M%S) 332 | echo "Backing up ${PG_OLD_DATADIR} to ${PG_OLD_DATADIR}.${PG_BKP_SUFFIX}..." 333 | cp -a ${PG_OLD_DATADIR} ${PG_OLD_DATADIR}.${PG_BKP_SUFFIX} 334 | 335 | echo "Installing postgresql-${PG_OLD_VERSION}..." 336 | apt-get update 337 | apt-get install postgresql-${PG_OLD_VERSION} postgresql-client-${PG_OLD_VERSION} 338 | rm -rf /var/lib/apt/lists/* 339 | 340 | # migrate ${PG_OLD_VERSION} data 341 | echo "Migration in progress. This could take a while, please be patient..." 342 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/pg_upgrade \ 343 | -b ${PG_OLD_BINDIR} -B ${PG_BIN_DIR} \ 344 | -d ${PG_OLD_DATADIR} -D ${PG_DATA_DIR} \ 345 | -o "-c config_file=${PG_OLD_CONFDIR}/postgresql.conf" \ 346 | -O "-c config_file=${PG_CONF_DIR}/postgresql.conf" >/dev/null 347 | fi 348 | 349 | # Create databases and users 350 | if [[ -f /tmp/.EMPTY_DB && ( -z ${PG_MODE} || ${PG_MODE} =~ ^master ) ]]; then 351 | 352 | if [[ ${PG_MODE} =~ ^master ]]; then 353 | remove_recovery_file 354 | echo "Creating user \"${REPLICATION_USER}\"..." 355 | echo "CREATE ROLE ${REPLICATION_USER} WITH REPLICATION LOGIN ENCRYPTED PASSWORD '${REPLICATION_PASS}';" | 356 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 357 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 358 | fi 359 | 360 | if [[ -n ${DB_USER} ]]; then 361 | if [[ -z ${DB_PASS} ]]; then 362 | echo "" 363 | echo "WARNING: " 364 | echo " Please specify a password for \"${DB_USER}\". Skipping user creation..." 365 | echo "" 366 | DB_USER= 367 | else 368 | echo "Creating user \"${DB_USER}\"..." 369 | echo "CREATE ROLE ${DB_USER} with LOGIN CREATEDB PASSWORD '${DB_PASS}';" | 370 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 371 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 372 | fi 373 | fi 374 | 375 | if [[ -n ${DB_NAME} ]]; then 376 | for db in $(awk -F',' '{for (i = 1 ; i <= NF ; i++) print $i}' <<< "${DB_NAME}"); do 377 | echo "Creating database \"${db}\"..." 378 | 379 | echo "CREATE DATABASE ${db} ENCODING = 'UTF8' LC_COLLATE = '${DB_LOCALE}' LC_CTYPE = '${DB_LOCALE}' TEMPLATE = template0;" | \ 380 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 381 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 382 | 383 | if [[ ${DB_UNACCENT} == true ]]; then 384 | echo "Installing unaccent extension..." 385 | echo "CREATE EXTENSION IF NOT EXISTS unaccent;" | \ 386 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single ${db} \ 387 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 388 | fi 389 | 390 | if [[ -n ${DB_USER} ]]; then 391 | echo "Granting access to database \"${db}\" for user \"${DB_USER}\"..." 392 | echo "GRANT ALL PRIVILEGES ON DATABASE ${db} to ${DB_USER};" | 393 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 394 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 395 | fi 396 | done 397 | fi 398 | 399 | rm -f /tmp/.EMPTY_DB 400 | fi 401 | 402 | echo "Starting PostgreSQL server..." 403 | exec start-stop-daemon --start --chuid ${PG_USER}:${PG_USER} --exec ${PG_BIN_DIR}/postgres -- \ 404 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf -c timezone=${PG_TZ} -------------------------------------------------------------------------------- /11/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | PG_VERSION=${PG_VERSION:-} 6 | PG_USER=${PG_USER:-} 7 | PG_HOME=${PG_HOME:-} 8 | PG_LOG_DIR=${PG_LOG_DIR:-} 9 | PG_DATA_DIR=${PG_DATA_DIR:-} 10 | PG_RUN_DIR=${PG_RUN_DIR:-} 11 | PG_CONF_DIR=${PG_CONF_DIR:-} 12 | PG_BIN_DIR=${PG_BIN_DIR:-} 13 | PG_TZ=${PG_TZ:-"UTC"} 14 | 15 | PG_BACKUP_DIR=${PG_BACKUP_DIR:-"/tmp/backup"} 16 | PG_BACKUP_FILENAME=${PG_BACKUP_FILENAME:-"backup.last.tar.bz2"} 17 | PG_ROTATE_BACKUP=${PG_ROTATE_BACKUP:-true} 18 | PG_CHECK=${PG_CHECK:-} 19 | PG_RESTORE=${PG_RESTORE:-} 20 | 21 | # set this env variable to true to enable a line in the 22 | # pg_hba.conf file to trust samenet. this can be used to connect 23 | # from other containers on the same host without authentication 24 | PG_TRUST_LOCALNET=${PG_TRUST_LOCALNET:-false} 25 | 26 | DB_NAME=${DB_NAME:-} 27 | DB_USER=${DB_USER:-} 28 | DB_PASS=${DB_PASS:-} 29 | DB_LOCALE=${DB_LOCALE:-"${OS_LOCALE}"} 30 | DB_UNACCENT=${DB_UNACCENT:false} 31 | 32 | # set this environment variable to master, slave or snapshot to use replication features. 33 | # "snapshot" will create a point in time backup of a master instance. 34 | PG_MODE=${PG_MODE:-} 35 | 36 | REPLICATION_USER=${REPLICATION_USER:-replica} 37 | REPLICATION_PASS=${REPLICATION_PASS:-replica} 38 | REPLICATION_HOST=${REPLICATION_HOST:-} 39 | REPLICATION_PORT=${REPLICATION_PORT:-5432} 40 | PG_WAL_SEGMENTS=${PG_WAL_SEGMENTS:-8} 41 | PG_MAX_WAL_SIZE=${PG_MAX_WAL_SIZE:-"1GB"} 42 | PG_MAX_WAL_SENDERS=${PG_MAX_WAL_SENDERS:-3} 43 | 44 | # set this env variable to "require" to enable encryption and "verify-full" for verification. 45 | PG_SSLMODE=${PG_SSLMODE:-disable} 46 | 47 | map_postgres_uid() { 48 | USERMAP_ORIG_UID=$(id -u ${PG_USER}) 49 | USERMAP_ORIG_GID=$(id -g ${PG_USER}) 50 | USERMAP_GID=${USERMAP_GID:-${USERMAP_UID:-$USERMAP_ORIG_GID}} 51 | USERMAP_UID=${USERMAP_UID:-$USERMAP_ORIG_UID} 52 | if [[ ${USERMAP_UID} != ${USERMAP_ORIG_UID} ]] || [[ ${USERMAP_GID} != ${USERMAP_ORIG_GID} ]]; then 53 | echo "Adapting uid and gid for ${PG_USER}:${PG_USER} to $USERMAP_UID:$USERMAP_GID" 54 | groupmod -g ${USERMAP_GID} ${PG_USER} 55 | sed -i -e "s/:${USERMAP_ORIG_UID}:${USERMAP_GID}:/:${USERMAP_UID}:${USERMAP_GID}:/" /etc/passwd 56 | fi 57 | } 58 | 59 | create_home_dir() { 60 | mkdir -p ${PG_HOME} 61 | chmod -R 0700 ${PG_HOME} 62 | chown -R ${PG_USER}:${PG_USER} ${PG_HOME} 63 | } 64 | 65 | create_data_dir() { 66 | mkdir -p ${PG_DATA_DIR} 67 | chmod -R 0700 ${PG_DATA_DIR} 68 | chown -R ${PG_USER}:${PG_USER} ${PG_DATA_DIR} 69 | } 70 | 71 | create_log_dir() { 72 | mkdir -p ${PG_LOG_DIR} 73 | chmod -R 1775 ${PG_LOG_DIR} 74 | chown -R root:${PG_USER} ${PG_LOG_DIR} 75 | } 76 | 77 | create_run_dir() { 78 | mkdir -p ${PG_RUN_DIR} ${PG_RUN_DIR}/${PG_VERSION}-main.pg_stat_tmp 79 | chmod -R 0755 ${PG_RUN_DIR} 80 | chmod g+s ${PG_RUN_DIR} 81 | chown -R ${PG_USER}:${PG_USER} ${PG_RUN_DIR} 82 | } 83 | 84 | create_backup_dir() { 85 | mkdir -p ${PG_BACKUP_DIR}/ 86 | chmod -R 0755 ${PG_BACKUP_DIR} 87 | chown -R root:${PG_USER} ${PG_BACKUP_DIR} 88 | } 89 | 90 | rotate_backup() 91 | { 92 | echo "Rotate backup..." 93 | 94 | if [[ ${PG_ROTATE_BACKUP} == true ]]; then 95 | 96 | WEEK=$(date +"%V") 97 | MONTH=$(date +"%b") 98 | let "INDEX = WEEK % 5" || true 99 | if [[ ${INDEX} == 0 ]]; then 100 | INDEX=4 101 | fi 102 | 103 | test -e ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 && rm ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 104 | mv ${PG_BACKUP_DIR}/backup.tar.bz2 ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 105 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2" 106 | 107 | test -e ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2 && rm ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2 108 | ln ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2 109 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2" 110 | 111 | test -e ${PG_BACKUP_DIR}/backup.last.tar.bz2 && rm ${PG_BACKUP_DIR}/backup.last.tar.bz2 112 | ln ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 ${PG_BACKUP_DIR}/backup.last.tar.bz2 113 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.last.tar.bz2" 114 | else 115 | mv ${PG_BACKUP_DIR}/backup.tar.bz2 ${PG_BACKUP_DIR}/backup.last.tar.bz2 116 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.last.tar.bz2" 117 | fi 118 | } 119 | 120 | import_backup() 121 | { 122 | FILE=$1 123 | if [[ ${FILE} == default ]]; then 124 | FILE="${PG_BACKUP_DIR}/${PG_BACKUP_FILENAME}" 125 | fi 126 | if [[ ! -f "${FILE}" ]]; then 127 | echo "Unknown backup: ${FILE}" 128 | exit 1 129 | fi 130 | create_data_dir 131 | sudo -Hu ${PG_USER} lbzip2 -dc -n 2 ${FILE} | tar -C ${PG_DATA_DIR} -x 132 | } 133 | 134 | remove_recovery_file() 135 | { 136 | if [[ -f "${PG_DATA_DIR}/recovery.conf" ]]; then 137 | echo "Remove file: '${PG_DATA_DIR}/recovery.conf'" 138 | rm ${PG_DATA_DIR}/recovery.conf 139 | fi 140 | } 141 | 142 | # Sets a locale 143 | locale-gen ${DB_LOCALE} && dpkg-reconfigure --frontend=noninteractive locales 144 | 145 | map_postgres_uid 146 | create_home_dir 147 | create_log_dir 148 | create_run_dir 149 | create_backup_dir 150 | 151 | # fix ownership of ${PG_CONF_DIR} (may be necessary if USERMAP_* was set) 152 | chown -R ${PG_USER}:${PG_USER} ${PG_CONF_DIR} 153 | 154 | if [[ ! -f /tmp/.CONFIGURE_1 ]]; then 155 | if [[ ${PG_SSLMODE} == disable ]]; then 156 | sed 's/ssl = true/#ssl = true/' -i ${PG_CONF_DIR}/postgresql.conf 157 | fi 158 | 159 | # Change DSM from `posix' to `sysv' if we are inside an lx-brand container 160 | if [[ $(uname -v) == "BrandZ virtual linux" ]]; then 161 | sed 's/\(dynamic_shared_memory_type = \)posix/\1sysv/' \ 162 | -i ${PG_CONF_DIR}/postgresql.conf 163 | fi 164 | 165 | # listen on all interfaces 166 | cat >> ${PG_CONF_DIR}/postgresql.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/postgresql.conf < ${PG_BACKUP_DIR}/backup.tar.bz2 230 | else 231 | echo "Used host: ${REPLICATION_HOST}" 232 | sudo -Hu ${PG_USER} \ 233 | PGPASSWORD=${REPLICATION_PASS} ${PG_BIN_DIR}/pg_basebackup \ 234 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -X fetch -v -P --format=t ${EXTRA_OPTS} \ 235 | -D - | lbzip2 -n 2 -9 > ${PG_BACKUP_DIR}/backup.tar.bz2 236 | fi 237 | rotate_backup 238 | exit 0 239 | fi 240 | 241 | # Check backup 242 | if [[ -n ${PG_CHECK} ]]; then 243 | 244 | echo "Check backup..." 245 | if [[ -z ${DB_NAME} ]]; then 246 | echo "Unknown database. DB_NAME does not null" 247 | exit 1; 248 | fi 249 | 250 | if [[ ! -d ${PG_DATA_DIR} ]]; then 251 | import_backup ${PG_CHECK} 252 | fi 253 | remove_recovery_file 254 | CHECK=$(echo "SELECT datname FROM pg_database WHERE lower(datname) = lower('${DB_NAME}');" | \ 255 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 256 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf) 257 | 258 | if [[ $(echo ${CHECK} | grep -w ${DB_NAME} | wc -l) == 1 ]]; then 259 | echo "Success checking backup" 260 | else 261 | echo "Fail checking backup" 262 | exit 1 263 | fi 264 | 265 | exit 0 266 | fi 267 | 268 | # Restore from backup 269 | if [[ ! -d ${PG_DATA_DIR} && -n ${PG_RESTORE} ]]; then 270 | if [[ -n ${PG_RESTORE} ]]; then 271 | echo "Import backup..." 272 | import_backup ${PG_RESTORE} 273 | fi 274 | fi 275 | 276 | if [[ ! -d ${PG_DATA_DIR} && ${PG_MODE} == master_restore ]]; then 277 | sudo -Hu ${PG_USER} \ 278 | PGPASSWORD=${REPLICATION_PASS} ${PG_BIN_DIR}/pg_basebackup -D ${PG_DATA_DIR} \ 279 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -X fetch -v -P 280 | fi 281 | 282 | # Create snapshot 283 | if [[ ! -d ${PG_DATA_DIR} && ${PG_MODE} == snapshot ]]; then 284 | echo "Snapshot database..." 285 | sudo -Hu ${PG_USER} \ 286 | PGPASSWORD=${REPLICATION_PASS} ${PG_BIN_DIR}/pg_basebackup -D ${PG_DATA_DIR} \ 287 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -X stream -v -P 288 | 289 | fi 290 | 291 | # Create slave 292 | if [[ ${PG_MODE} =~ ^slave && ! -f /tmp/.CONFIGURE_2 ]]; then 293 | echo "Replicating database..." 294 | if [[ ! -d ${PG_DATA_DIR} ]]; then 295 | # Setup streaming replication. 296 | sudo -Hu ${PG_USER} \ 297 | PGPASSWORD=${REPLICATION_PASS} ${PG_BIN_DIR}/pg_basebackup -D ${PG_DATA_DIR} \ 298 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -X stream -v -P 299 | fi 300 | echo "Setting up hot standby configuration..." 301 | cat >> ${PG_CONF_DIR}/postgresql.conf <> ${PG_DATA_DIR}/recovery.conf </dev/null | sort -r | head -n1 | cut -d'/' -f5) 317 | 318 | echo "Initializing database..." 319 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/initdb --pgdata=${PG_DATA_DIR} \ 320 | --username=${PG_USER} --encoding=unicode --auth=trust >/dev/null 321 | touch /tmp/.EMPTY_DB 322 | fi 323 | 324 | if [[ -n ${PG_OLD_VERSION} ]]; then 325 | echo "Migrating postgresql ${PG_OLD_VERSION} data..." 326 | PG_OLD_CONFDIR="/etc/postgresql/${PG_OLD_VERSION}/main" 327 | PG_OLD_BINDIR="/usr/lib/postgresql/${PG_OLD_VERSION}/bin" 328 | PG_OLD_DATADIR="${PG_HOME}/${PG_OLD_VERSION}/main" 329 | 330 | # backup ${PG_OLD_DATADIR} to avoid data loss 331 | PG_BKP_SUFFIX=$(date +%Y%m%d%H%M%S) 332 | echo "Backing up ${PG_OLD_DATADIR} to ${PG_OLD_DATADIR}.${PG_BKP_SUFFIX}..." 333 | cp -a ${PG_OLD_DATADIR} ${PG_OLD_DATADIR}.${PG_BKP_SUFFIX} 334 | 335 | echo "Installing postgresql-${PG_OLD_VERSION}..." 336 | apt-get update 337 | apt-get install postgresql-${PG_OLD_VERSION} postgresql-client-${PG_OLD_VERSION} 338 | rm -rf /var/lib/apt/lists/* 339 | 340 | # migrate ${PG_OLD_VERSION} data 341 | echo "Migration in progress. This could take a while, please be patient..." 342 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/pg_upgrade \ 343 | -b ${PG_OLD_BINDIR} -B ${PG_BIN_DIR} \ 344 | -d ${PG_OLD_DATADIR} -D ${PG_DATA_DIR} \ 345 | -o "-c config_file=${PG_OLD_CONFDIR}/postgresql.conf" \ 346 | -O "-c config_file=${PG_CONF_DIR}/postgresql.conf" >/dev/null 347 | fi 348 | 349 | # Create databases and users 350 | if [[ -f /tmp/.EMPTY_DB && ( -z ${PG_MODE} || ${PG_MODE} =~ ^master ) ]]; then 351 | 352 | if [[ ${PG_MODE} =~ ^master ]]; then 353 | remove_recovery_file 354 | echo "Creating user \"${REPLICATION_USER}\"..." 355 | echo "CREATE ROLE ${REPLICATION_USER} WITH REPLICATION LOGIN ENCRYPTED PASSWORD '${REPLICATION_PASS}';" | 356 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 357 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 358 | fi 359 | 360 | if [[ -n ${DB_USER} ]]; then 361 | if [[ -z ${DB_PASS} ]]; then 362 | echo "" 363 | echo "WARNING: " 364 | echo " Please specify a password for \"${DB_USER}\". Skipping user creation..." 365 | echo "" 366 | DB_USER= 367 | else 368 | echo "Creating user \"${DB_USER}\"..." 369 | echo "CREATE ROLE ${DB_USER} with LOGIN CREATEDB PASSWORD '${DB_PASS}';" | 370 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 371 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 372 | fi 373 | fi 374 | 375 | if [[ -n ${DB_NAME} ]]; then 376 | for db in $(awk -F',' '{for (i = 1 ; i <= NF ; i++) print $i}' <<< "${DB_NAME}"); do 377 | echo "Creating database \"${db}\"..." 378 | 379 | echo "CREATE DATABASE ${db} ENCODING = 'UTF8' LC_COLLATE = '${DB_LOCALE}' LC_CTYPE = '${DB_LOCALE}' TEMPLATE = template0;" | \ 380 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 381 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 382 | 383 | if [[ ${DB_UNACCENT} == true ]]; then 384 | echo "Installing unaccent extension..." 385 | echo "CREATE EXTENSION IF NOT EXISTS unaccent;" | \ 386 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single ${db} \ 387 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 388 | fi 389 | 390 | if [[ -n ${DB_USER} ]]; then 391 | echo "Granting access to database \"${db}\" for user \"${DB_USER}\"..." 392 | echo "GRANT ALL PRIVILEGES ON DATABASE ${db} to ${DB_USER};" | 393 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 394 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 395 | fi 396 | done 397 | fi 398 | 399 | rm -f /tmp/.EMPTY_DB 400 | fi 401 | 402 | echo "Starting PostgreSQL server..." 403 | exec start-stop-daemon --start --chuid ${PG_USER}:${PG_USER} --exec ${PG_BIN_DIR}/postgres -- \ 404 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf -c timezone=${PG_TZ} -------------------------------------------------------------------------------- /9.6/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | PG_VERSION=${PG_VERSION:-} 6 | PG_USER=${PG_USER:-} 7 | PG_HOME=${PG_HOME:-} 8 | PG_LOG_DIR=${PG_LOG_DIR:-} 9 | PG_DATA_DIR=${PG_DATA_DIR:-} 10 | PG_RUN_DIR=${PG_RUN_DIR:-} 11 | PG_CONF_DIR=${PG_CONF_DIR:-} 12 | PG_BIN_DIR=${PG_BIN_DIR:-} 13 | PG_TZ=${PG_TZ:-"UTC"} 14 | 15 | PG_BACKUP_DIR=${PG_BACKUP_DIR:-"/tmp/backup"} 16 | PG_BACKUP_FILENAME=${PG_BACKUP_FILENAME:-"backup.last.tar.bz2"} 17 | PG_ROTATE_BACKUP=${PG_ROTATE_BACKUP:-true} 18 | PG_CHECK=${PG_CHECK:-} 19 | PG_RESTORE=${PG_RESTORE:-} 20 | 21 | # set this env variable to true to enable a line in the 22 | # pg_hba.conf file to trust samenet. this can be used to connect 23 | # from other containers on the same host without authentication 24 | PG_TRUST_LOCALNET=${PG_TRUST_LOCALNET:-false} 25 | 26 | DB_NAME=${DB_NAME:-} 27 | DB_USER=${DB_USER:-} 28 | DB_PASS=${DB_PASS:-} 29 | DB_LOCALE=${DB_LOCALE:-"${OS_LOCALE}"} 30 | DB_UNACCENT=${DB_UNACCENT:false} 31 | 32 | # set this environment variable to master, slave or snapshot to use replication features. 33 | # "snapshot" will create a point in time backup of a master instance. 34 | PG_MODE=${PG_MODE:-} 35 | 36 | REPLICATION_USER=${REPLICATION_USER:-replica} 37 | REPLICATION_PASS=${REPLICATION_PASS:-replica} 38 | REPLICATION_HOST=${REPLICATION_HOST:-} 39 | REPLICATION_PORT=${REPLICATION_PORT:-5432} 40 | PG_WAL_SEGMENTS=${PG_WAL_SEGMENTS:-8} 41 | PG_MAX_WAL_SIZE=${PG_MAX_WAL_SIZE:-"1GB"} 42 | PG_MAX_WAL_SENDERS=${PG_MAX_WAL_SENDERS:-3} 43 | 44 | # set this env variable to "require" to enable encryption and "verify-full" for verification. 45 | PG_SSLMODE=${PG_SSLMODE:-disable} 46 | 47 | map_postgres_uid() { 48 | USERMAP_ORIG_UID=$(id -u ${PG_USER}) 49 | USERMAP_ORIG_GID=$(id -g ${PG_USER}) 50 | USERMAP_GID=${USERMAP_GID:-${USERMAP_UID:-$USERMAP_ORIG_GID}} 51 | USERMAP_UID=${USERMAP_UID:-$USERMAP_ORIG_UID} 52 | if [[ ${USERMAP_UID} != ${USERMAP_ORIG_UID} ]] || [[ ${USERMAP_GID} != ${USERMAP_ORIG_GID} ]]; then 53 | echo "Adapting uid and gid for ${PG_USER}:${PG_USER} to $USERMAP_UID:$USERMAP_GID" 54 | groupmod -g ${USERMAP_GID} ${PG_USER} 55 | sed -i -e "s/:${USERMAP_ORIG_UID}:${USERMAP_GID}:/:${USERMAP_UID}:${USERMAP_GID}:/" /etc/passwd 56 | fi 57 | } 58 | 59 | create_home_dir() { 60 | mkdir -p ${PG_HOME} 61 | chmod -R 0700 ${PG_HOME} 62 | chown -R ${PG_USER}:${PG_USER} ${PG_HOME} 63 | } 64 | 65 | create_data_dir() { 66 | mkdir -p ${PG_DATA_DIR} 67 | chmod -R 0700 ${PG_DATA_DIR} 68 | chown -R ${PG_USER}:${PG_USER} ${PG_DATA_DIR} 69 | } 70 | 71 | create_log_dir() { 72 | mkdir -p ${PG_LOG_DIR} 73 | chmod -R 1775 ${PG_LOG_DIR} 74 | chown -R root:${PG_USER} ${PG_LOG_DIR} 75 | } 76 | 77 | create_run_dir() { 78 | mkdir -p ${PG_RUN_DIR} ${PG_RUN_DIR}/${PG_VERSION}-main.pg_stat_tmp 79 | chmod -R 0755 ${PG_RUN_DIR} 80 | chmod g+s ${PG_RUN_DIR} 81 | chown -R ${PG_USER}:${PG_USER} ${PG_RUN_DIR} 82 | } 83 | 84 | create_backup_dir() { 85 | mkdir -p ${PG_BACKUP_DIR}/ 86 | chmod -R 0755 ${PG_BACKUP_DIR} 87 | chown -R root:${PG_USER} ${PG_BACKUP_DIR} 88 | } 89 | 90 | rotate_backup() 91 | { 92 | echo "Rotate backup..." 93 | 94 | if [[ ${PG_ROTATE_BACKUP} == true ]]; then 95 | 96 | WEEK=$(date +"%V") 97 | MONTH=$(date +"%b") 98 | let "INDEX = WEEK % 5" || true 99 | if [[ ${INDEX} == 0 ]]; then 100 | INDEX=4 101 | fi 102 | 103 | test -e ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 && rm ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 104 | mv ${PG_BACKUP_DIR}/backup.tar.bz2 ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 105 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2" 106 | 107 | test -e ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2 && rm ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2 108 | ln ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2 109 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.${MONTH}.tar.bz2" 110 | 111 | test -e ${PG_BACKUP_DIR}/backup.last.tar.bz2 && rm ${PG_BACKUP_DIR}/backup.last.tar.bz2 112 | ln ${PG_BACKUP_DIR}/backup.${INDEX}.tar.bz2 ${PG_BACKUP_DIR}/backup.last.tar.bz2 113 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.last.tar.bz2" 114 | else 115 | mv ${PG_BACKUP_DIR}/backup.tar.bz2 ${PG_BACKUP_DIR}/backup.last.tar.bz2 116 | echo "Create backup file: ${PG_BACKUP_DIR}/backup.last.tar.bz2" 117 | fi 118 | } 119 | 120 | import_backup() 121 | { 122 | FILE=$1 123 | if [[ ${FILE} == default ]]; then 124 | FILE="${PG_BACKUP_DIR}/${PG_BACKUP_FILENAME}" 125 | fi 126 | if [[ ! -f "${FILE}" ]]; then 127 | echo "Unknown backup: ${FILE}" 128 | exit 1 129 | fi 130 | create_data_dir 131 | sudo -Hu ${PG_USER} lbzip2 -dc -n 2 ${FILE} | tar -C ${PG_DATA_DIR} -x 132 | } 133 | 134 | remove_recovery_file() 135 | { 136 | if [[ -f "${PG_DATA_DIR}/recovery.conf" ]]; then 137 | echo "Remove file: '${PG_DATA_DIR}/recovery.conf'" 138 | rm ${PG_DATA_DIR}/recovery.conf 139 | fi 140 | } 141 | 142 | # Sets a locale 143 | #localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias ${DB_LOCALE} 144 | #export LANG=${DB_LOCALE} 145 | #export LANG=${DB_LOCALE} 146 | #export LANGUAGE=${DB_LOCALE} 147 | #export LC_ALL=${DB_LOCALE} 148 | #locale-gen ${DB_LOCALE} && update-locale LANG="${DB_LOCALE}" LANGUAGE="${OS_LANGUAGE}" && dpkg-reconfigure --frontend=noninteractive locales 149 | locale-gen ${DB_LOCALE} && dpkg-reconfigure --frontend=noninteractive locales 150 | 151 | map_postgres_uid 152 | create_home_dir 153 | create_log_dir 154 | create_run_dir 155 | create_backup_dir 156 | 157 | # fix ownership of ${PG_CONF_DIR} (may be necessary if USERMAP_* was set) 158 | chown -R ${PG_USER}:${PG_USER} ${PG_CONF_DIR} 159 | 160 | if [[ ! -f /tmp/.CONFIGURE_1 ]]; then 161 | if [[ ${PG_SSLMODE} == disable ]]; then 162 | sed 's/ssl = true/#ssl = true/' -i ${PG_CONF_DIR}/postgresql.conf 163 | fi 164 | 165 | # Change DSM from `posix' to `sysv' if we are inside an lx-brand container 166 | if [[ $(uname -v) == "BrandZ virtual linux" ]]; then 167 | sed 's/\(dynamic_shared_memory_type = \)posix/\1sysv/' \ 168 | -i ${PG_CONF_DIR}/postgresql.conf 169 | fi 170 | 171 | # listen on all interfaces 172 | cat >> ${PG_CONF_DIR}/postgresql.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/pg_hba.conf <> ${PG_CONF_DIR}/postgresql.conf < ${PG_BACKUP_DIR}/backup.tar.bz2 236 | else 237 | echo "Used host: ${REPLICATION_HOST}" 238 | sudo -Hu ${PG_USER} \ 239 | PGPASSWORD=${REPLICATION_PASS} ${PG_BIN_DIR}/pg_basebackup \ 240 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -x -v -P --format=t ${EXTRA_OPTS} \ 241 | -D - | lbzip2 -n 2 -9 > ${PG_BACKUP_DIR}/backup.tar.bz2 242 | fi 243 | rotate_backup 244 | exit 0 245 | fi 246 | 247 | # Check backup 248 | if [[ -n ${PG_CHECK} ]]; then 249 | 250 | echo "Check backup..." 251 | if [[ -z ${DB_NAME} ]]; then 252 | echo "Unknown database. DB_NAME does not null" 253 | exit 1; 254 | fi 255 | 256 | if [[ ! -d ${PG_DATA_DIR} ]]; then 257 | import_backup ${PG_CHECK} 258 | fi 259 | remove_recovery_file 260 | CHECK=$(echo "SELECT datname FROM pg_database WHERE lower(datname) = lower('${DB_NAME}');" | \ 261 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 262 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf) 263 | 264 | if [[ $(echo ${CHECK} | grep -w ${DB_NAME} | wc -l) == 1 ]]; then 265 | echo "Success checking backup" 266 | else 267 | echo "Fail checking backup" 268 | exit 1 269 | fi 270 | 271 | exit 0 272 | fi 273 | 274 | # Restore from backup 275 | if [[ ! -d ${PG_DATA_DIR} && -n ${PG_RESTORE} ]]; then 276 | if [[ -n ${PG_RESTORE} ]]; then 277 | echo "Import backup..." 278 | import_backup ${PG_RESTORE} 279 | fi 280 | fi 281 | 282 | if [[ ! -d ${PG_DATA_DIR} && ${PG_MODE} == master_restore ]]; then 283 | sudo -Hu ${PG_USER} \ 284 | PGPASSWORD=${REPLICATION_PASS} ${PG_BIN_DIR}/pg_basebackup -D ${PG_DATA_DIR} \ 285 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -x -v -P 286 | fi 287 | 288 | # Create snapshot 289 | if [[ ! -d ${PG_DATA_DIR} && ${PG_MODE} == snapshot ]]; then 290 | echo "Snapshot database..." 291 | sudo -Hu ${PG_USER} \ 292 | PGPASSWORD=${REPLICATION_PASS} ${PG_BIN_DIR}/pg_basebackup -D ${PG_DATA_DIR} \ 293 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -X stream -v -P 294 | 295 | fi 296 | 297 | # Create slave 298 | if [[ ${PG_MODE} =~ ^slave && ! -f /tmp/.CONFIGURE_2 ]]; then 299 | echo "Replicating database..." 300 | if [[ ! -d ${PG_DATA_DIR} ]]; then 301 | # Setup streaming replication. 302 | sudo -Hu ${PG_USER} \ 303 | PGPASSWORD=${REPLICATION_PASS} ${PG_BIN_DIR}/pg_basebackup -D ${PG_DATA_DIR} \ 304 | -h ${REPLICATION_HOST} -p ${REPLICATION_PORT} -U ${REPLICATION_USER} -w -X stream -v -P 305 | fi 306 | echo "Setting up hot standby configuration..." 307 | cat >> ${PG_CONF_DIR}/postgresql.conf <> ${PG_DATA_DIR}/recovery.conf </dev/null | sort -r | head -n1 | cut -d'/' -f5) 323 | 324 | echo "Initializing database..." 325 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/initdb --pgdata=${PG_DATA_DIR} \ 326 | --username=${PG_USER} --encoding=unicode --auth=trust >/dev/null 327 | touch /tmp/.EMPTY_DB 328 | fi 329 | 330 | if [[ -n ${PG_OLD_VERSION} ]]; then 331 | echo "Migrating postgresql ${PG_OLD_VERSION} data..." 332 | PG_OLD_CONFDIR="/etc/postgresql/${PG_OLD_VERSION}/main" 333 | PG_OLD_BINDIR="/usr/lib/postgresql/${PG_OLD_VERSION}/bin" 334 | PG_OLD_DATADIR="${PG_HOME}/${PG_OLD_VERSION}/main" 335 | 336 | # backup ${PG_OLD_DATADIR} to avoid data loss 337 | PG_BKP_SUFFIX=$(date +%Y%m%d%H%M%S) 338 | echo "Backing up ${PG_OLD_DATADIR} to ${PG_OLD_DATADIR}.${PG_BKP_SUFFIX}..." 339 | cp -a ${PG_OLD_DATADIR} ${PG_OLD_DATADIR}.${PG_BKP_SUFFIX} 340 | 341 | echo "Installing postgresql-${PG_OLD_VERSION}..." 342 | apt-get update 343 | apt-get install postgresql-${PG_OLD_VERSION} postgresql-client-${PG_OLD_VERSION} 344 | rm -rf /var/lib/apt/lists/* 345 | 346 | # migrate ${PG_OLD_VERSION} data 347 | echo "Migration in progress. This could take a while, please be patient..." 348 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/pg_upgrade \ 349 | -b ${PG_OLD_BINDIR} -B ${PG_BIN_DIR} \ 350 | -d ${PG_OLD_DATADIR} -D ${PG_DATA_DIR} \ 351 | -o "-c config_file=${PG_OLD_CONFDIR}/postgresql.conf" \ 352 | -O "-c config_file=${PG_CONF_DIR}/postgresql.conf" >/dev/null 353 | fi 354 | 355 | # Create databases and users 356 | if [[ -f /tmp/.EMPTY_DB && ( -z ${PG_MODE} || ${PG_MODE} =~ ^master ) ]]; then 357 | 358 | if [[ ${PG_MODE} =~ ^master ]]; then 359 | remove_recovery_file 360 | echo "Creating user \"${REPLICATION_USER}\"..." 361 | echo "CREATE ROLE ${REPLICATION_USER} WITH REPLICATION LOGIN ENCRYPTED PASSWORD '${REPLICATION_PASS}';" | 362 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 363 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 364 | fi 365 | 366 | if [[ -n ${DB_USER} ]]; then 367 | if [[ -z ${DB_PASS} ]]; then 368 | echo "" 369 | echo "WARNING: " 370 | echo " Please specify a password for \"${DB_USER}\". Skipping user creation..." 371 | echo "" 372 | DB_USER= 373 | else 374 | echo "Creating user \"${DB_USER}\"..." 375 | echo "CREATE ROLE ${DB_USER} with LOGIN CREATEDB PASSWORD '${DB_PASS}';" | 376 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 377 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 378 | fi 379 | fi 380 | 381 | if [[ -n ${DB_NAME} ]]; then 382 | for db in $(awk -F',' '{for (i = 1 ; i <= NF ; i++) print $i}' <<< "${DB_NAME}"); do 383 | echo "Creating database \"${db}\"..." 384 | 385 | echo "CREATE DATABASE ${db} ENCODING = 'UTF8' LC_COLLATE = '${DB_LOCALE}' LC_CTYPE = '${DB_LOCALE}' TEMPLATE = template0;" | \ 386 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 387 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 388 | 389 | if [[ ${DB_UNACCENT} == true ]]; then 390 | echo "Installing unaccent extension..." 391 | echo "CREATE EXTENSION IF NOT EXISTS unaccent;" | \ 392 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single ${db} \ 393 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 394 | fi 395 | 396 | if [[ -n ${DB_USER} ]]; then 397 | echo "Granting access to database \"${db}\" for user \"${DB_USER}\"..." 398 | echo "GRANT ALL PRIVILEGES ON DATABASE ${db} to ${DB_USER};" | 399 | sudo -Hu ${PG_USER} ${PG_BIN_DIR}/postgres --single \ 400 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf >/dev/null 401 | fi 402 | done 403 | fi 404 | 405 | rm -f /tmp/.EMPTY_DB 406 | fi 407 | 408 | echo "Starting PostgreSQL server..." 409 | exec start-stop-daemon --start --chuid ${PG_USER}:${PG_USER} --exec ${PG_BIN_DIR}/postgres -- \ 410 | -D ${PG_DATA_DIR} -c config_file=${PG_CONF_DIR}/postgresql.conf -c timezone=${PG_TZ} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Table of Contents 2 | ------------------- 3 | 4 | * [Installation](#installation) 5 | * [Quick Start](#quick-start) 6 | * [Persistence](#persistence) 7 | * [Creating user and database](#creating-user-and-database-at-run) 8 | * [Creating Database with specified locale](#creating-database-with-specified-locale-at-run) 9 | * [Backuping](#backuping) 10 | * [Checking backup](#checking-backup) 11 | * [Restore from backup](#restore-from-backup) 12 | * [Dumping database](#dumping-database) 13 | * [Replication - Master/Slave](#replication---masterslave) 14 | * [Search plain text with accent](#enable-unaccent-search-plain-text-with-accent) 15 | * [Host UID / GID Mapping](#host-uid--gid-mapping) 16 | * [Environment variables](#environment-variables) 17 | * [Logging](#logging) 18 | * [Out of the box](#out-of-the-box) 19 | 20 | Installation 21 | ------------------- 22 | 23 | * [Install Docker 1.9+](https://docs.docker.com/installation/) or [askubuntu](http://askubuntu.com/a/473720) 24 | * Pull the latest version of the image. 25 | 26 | ```bash 27 | docker pull romeoz/docker-postgresql 28 | ``` 29 | 30 | Alternately you can build the image yourself. 31 | 32 | ```bash 33 | git clone https://github.com/romeoz/docker-postgresql.git 34 | cd docker-postgresql 35 | docker build -t="$USER/postgresql" . 36 | ``` 37 | 38 | Quick Start 39 | ------------------- 40 | 41 | Run the postgresql container: 42 | 43 | ```bash 44 | docker run --name postgresql -d -p 5432:5432 romeoz/docker-postgresql 45 | ``` 46 | 47 | The simplest way to login to the postgresql container as the administrative `postgres` user is to use the `docker exec` command to attach a new process to the running container and connect to the postgresql server over the unix socket. 48 | 49 | ```bash 50 | docker exec -it postgresql sudo -u postgres psql 51 | ``` 52 | 53 | Persistence 54 | ------------------- 55 | 56 | For data persistence a volume should be mounted at `/var/lib/postgresql`. 57 | 58 | SELinux users are also required to change the security context of the mount point so that it plays nicely with selinux. 59 | 60 | ```bash 61 | mkdir -p /to/path/data 62 | sudo chcon -Rt svirt_sandbox_file_t /to/path/data 63 | ``` 64 | 65 | The updated run command looks like this. 66 | 67 | ```bash 68 | docker run --name postgresql -d \ 69 | -v /host/to/path/data:/var/lib/postgresql romeoz/docker-postgresql 70 | ``` 71 | 72 | This will make sure that the data stored in the database is not lost when the container is stopped and started again. 73 | 74 | Creating User and Database at run 75 | ------------------- 76 | 77 | The container allows you to create a user and database at run time. 78 | 79 | To create a new user you should specify the `DB_USER` and `DB_PASS` variables. The following command will create a new user *dbuser* with the password *dbpass*. 80 | 81 | ```bash 82 | docker run --name postgresql -d \ 83 | -e 'DB_USER=dbuser' -e 'DB_PASS=dbpass' \ 84 | romeoz/docker-postgresql 85 | ``` 86 | 87 | **NOTE** 88 | - If the password is not specified the user will not be created 89 | - If the user user already exists no changes will be made 90 | 91 | Similarly, you can also create a new database by specifying the database name in the `DB_NAME` variable. 92 | 93 | ```bash 94 | docker run --name postgresql -d \ 95 | -e 'DB_NAME=dbname' romeoz/docker-postgresql 96 | ``` 97 | 98 | You may also specify a comma separated list of database names in the `DB_NAME` variable. The following command creates two new databases named *dbname1* and *dbname2* (p.s. this feature is only available in releases greater than 9.1-1). 99 | 100 | ```bash 101 | docker run --name postgresql -d \ 102 | -e 'DB_NAME=dbname1,dbname2' \ 103 | romeoz/docker-postgresql 104 | ``` 105 | 106 | If the `DB_USER` and `DB_PASS` variables are also specified while creating the database, then the user is granted access to the database(s). 107 | 108 | For example, 109 | 110 | ```bash 111 | docker run --name postgresql -d \ 112 | -e 'DB_USER=dbuser' -e 'DB_PASS=dbpass' -e 'DB_NAME=dbname' \ 113 | romeoz/docker-postgresql 114 | ``` 115 | 116 | will create a user *dbuser* with the password *dbpass*. It will also create a database named *dbname* and the *dbuser* user will have full access to the *dbname* database. 117 | 118 | The `PG_TRUST_LOCALNET` environment variable can be used to configure postgres to trust connections on the same network. This is handy for other containers to connect without authentication. To enable this behavior, set `PG_TRUST_LOCALNET` to `true`. 119 | 120 | For example, 121 | 122 | ```bash 123 | docker run --name postgresql -d \ 124 | -e 'PG_TRUST_LOCALNET=true' \ 125 | romeoz/docker-postgresql 126 | ``` 127 | 128 | This has the effect of adding the following to the `pg_hba.conf` file: 129 | 130 | ``` 131 | host all all samenet trust 132 | ``` 133 | 134 | Creating Database with specified locale at run 135 | ------------------- 136 | 137 | ```bash 138 | docker run --name postgresql -d \ 139 | -e 'DB_LOCALE=ru_RU.UTF-8' -e 'DB_NAME=dbname' romeoz/docker-postgresql 140 | ``` 141 | 142 | or after run container 143 | 144 | ```bash 145 | docker run --name postgresql -d \ 146 | -e 'DB_LOCALE=ru_RU.UTF-8' romeoz/docker-postgresql 147 | 148 | docker exec -it postgresql bash -c 'sudo -u postgres psql' 149 | CREATE DATABASE dbname ENCODING = 'UTF8' LC_COLLATE = 'ru_RU.UTF-8' LC_CTYPE = 'ru_RU.UTF-8' TEMPLATE = template0; 150 | ``` 151 | 152 | Backuping 153 | ------------------- 154 | 155 | The backup is made over a regular PostgreSQL connection, and uses the replication protocol (used [pg_basebackup](http://www.postgresql.org/docs/9.5/static/app-pgbasebackup.html)). 156 | 157 | First we need to raise the master: 158 | 159 | ```bash 160 | docker network create pg_net 161 | 162 | docker run --name='psql-master' -d \ 163 | --net pg_net 164 | -e 'PG_MODE=master' \ 165 | -e 'DB_NAME=dbname' \ 166 | -e 'PG_TRUST_LOCALNET=true' \ 167 | romeoz/docker-postgresql 168 | ``` 169 | 170 | Next, create a temporary container for backup: 171 | 172 | ```bash 173 | docker run -it --rm \ 174 | --net pg_net \ 175 | -e 'PG_MODE=backup' \ 176 | -e 'REPLICATION_HOST=psql-master' \ 177 | -e 'PG_TRUST_LOCALNET=true' \ 178 | -v /host/to/path/backup:/tmp/backup \ 179 | romeoz/docker-postgresql 180 | ``` 181 | Archive will be available in the `/host/to/path/backup`. 182 | 183 | > Algorithm: one backup per week (total 4), one backup per month (total 12) and the last backup. Example: `backup.last.tar.bz2`, `backup.1.tar.bz2` and `/backup.dec.tar.bz2`. 184 | 185 | You can disable the rotation by using env `PG_ROTATE_BACKUP=false`. 186 | 187 | Backuping slave requires that the slave was created with the WAL-settings. 188 | 189 | ```bash 190 | docker run --name psql-slave -d \ 191 | --net pg_net \ 192 | -e 'PG_MODE=slave_wal' -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=psql-master' \ 193 | romeoz/docker-postgresql 194 | ``` 195 | 196 | >So, you can used for restoring master 197 | 198 | Next, create a temporary container for backup: 199 | 200 | ```bash 201 | docker run -it --rm \ 202 | --net pg_net \ 203 | -e 'PG_MODE=backup' -e 'REPLICATION_HOST=psql-slave' 204 | -v -v /host/to/path/backup_slave:/tmp/backup \ 205 | romeoz/docker-postgresql 206 | ``` 207 | 208 | Checking backup 209 | ------------------- 210 | 211 | As the check-parameter is used a database name `DB_NAME`. 212 | 213 | ```bash 214 | docker run -it --rm \ 215 | -e 'PG_CHECK=default' \ 216 | -e 'DB_NAME=foo' \ 217 | -v /host/to/path/backup:/tmp/backup \ 218 | romeoz/docker-postgresql 219 | ``` 220 | 221 | Default used the `/tmp/backup/backup.last.bz2`. 222 | 223 | Restore from backup 224 | ------------------- 225 | 226 | ###Restore from backup file 227 | 228 | ```bash 229 | docker run --name='psql-master' -d \ 230 | -e 'PG_MODE=master' \ 231 | -e 'PG_RESTORE=default' \ 232 | -v /host/to/path/backup_master:/tmp/backup \ 233 | romeoz/docker-postgresql 234 | ``` 235 | 236 | or for slave 237 | 238 | ```bash 239 | docker run --name='psql-slave' -d \ 240 | -e 'PG_MODE=slave' \ 241 | -e 'PG_RESTORE=default' \ 242 | -v /host/to/path/backup_master:/tmp/backup \ 243 | romeoz/docker-postgresql 244 | ``` 245 | 246 | >Can be used files backup-master or backup-slave. 247 | 248 | ###Restore master from slave with WAL 249 | 250 | ```bash 251 | docker run --name master -d \ 252 | --net pg_net \ 253 | -e 'PG_MODE=master_restore' \ 254 | -e 'PG_TRUST_LOCALNET=true' -e 'REPLICATION_HOST=slave_wal' \ 255 | romeoz/docker-postgresql 256 | ``` 257 | 258 | Dumping database 259 | ------------------- 260 | 261 | Create a database named "foo": 262 | 263 | ```bash 264 | docker run --name db -d -e 'DB_NAME=foo' \ 265 | -v /to/path/backup:/tmp/backup \ 266 | romeoz/docker-postgresql 267 | ``` 268 | 269 | Dumping database to /tmp/backup/: 270 | 271 | ```bash 272 | docker exec -it db bash -c \ 273 | 'sudo -u postgres pg_dump --dbname=foo --format=tar | lbzip2 -n 2 -9 > /tmp/backup/backup.tar.bz2' 274 | ``` 275 | 276 | Restore database: 277 | 278 | ```bash 279 | docker run --name restore_db -d \ 280 | -v /to/path/backup:/tmp/backup \ 281 | romeoz/docker-postgresql 282 | 283 | docker exec -it restore_db bash -c \ 284 | 'lbzip2 -dc -n 2 /tmp/backup/backup.tar.bz2 | $(sudo -u postgres pg_restore --create --verbose -d template1)' 285 | ``` 286 | >Instead of volumes you can use the command `docker cp /to/path/backup/backup.tar.bz2 restore_db:/tmp/backup/backup.tar.bz2` (support Docker 1.8+). 287 | 288 | Replication - Master/Slave 289 | ------------------------- 290 | 291 | You may use the `PG_MODE` variable along with `REPLICATION_HOST`, `REPLICATION_PORT`, `REPLICATION_USER` and `REPLICATION_PASS` to create a snapshot of an existing database and enable stream replication. 292 | 293 | Your master database must support replication or super-user access for the credentials you specify. The `PG_MODE` variable should be set to `master`, for replication on your master node and `slave` or `snapshot` respectively for streaming replication or a point-in-time snapshot of a running instance. 294 | 295 | Create a master instance 296 | 297 | ```bash 298 | docker network create pg_net 299 | 300 | docker run --name='psql-master' -d \ 301 | --net pg_net \ 302 | -e 'PG_MODE=master' -e 'PG_TRUST_LOCALNET=true' \ 303 | -e 'REPLICATION_USER=replicator' -e 'REPLICATION_PASS=replicatorpass' \ 304 | -e 'DB_NAME=dbname' -e 'DB_USER=dbuser' -e 'DB_PASS=dbpass' \ 305 | romeoz/docker-postgresql 306 | ``` 307 | 308 | Create a slave instance + fast import backup from master 309 | 310 | ```bash 311 | docker run --name='psql-slave' -d \ 312 | --net pg_net \ 313 | -e 'PG_MODE=slave' -e 'PG_TRUST_LOCALNET=true' \ 314 | -e 'REPLICATION_HOST=psql-master' -e 'REPLICATION_PORT=5432' \ 315 | -e 'REPLICATION_USER=replicator' -e 'REPLICATION_PASS=replicatorpass' \ 316 | romeoz/docker-postgresql 317 | ``` 318 | 319 | Enable Unaccent (Search plain text with accent) 320 | ------------------- 321 | 322 | Unaccent is a text search dictionary that removes accents (diacritic signs) from lexemes. It's a filtering dictionary, which means its output is always passed to the next dictionary (if any), unlike the normal behavior of dictionaries. This allows accent-insensitive processing for full text search. 323 | 324 | By default unaccent is configure to `false` 325 | 326 | ```bash 327 | docker run --name postgresql -d \ 328 | -e 'DB_UNACCENT=true' \ 329 | romeoz/docker-postgresql 330 | ``` 331 | 332 | Host UID / GID Mapping 333 | ------------------- 334 | 335 | Per default the container is configured to run postgres as user and group `postgres` with some unknown `uid` and `gid`. The host possibly uses these ids for different purposes leading to unfavorable effects. From the host it appears as if the mounted data volumes are owned by the host's user/group `[whatever id postgres has in the image]`. 336 | 337 | Also the container processes seem to be executed as the host's user/group `[whatever id postgres has in the image]`. The container can be configured to map the `uid` and `gid` of `postgres` to different ids on host by passing the environment variables `USERMAP_UID` and `USERMAP_GID`. The following command maps the ids to user and group `postgres` on the host. 338 | 339 | ```bash 340 | docker run --name=postgresql -it --rm [options] \ 341 | --env="USERMAP_UID=$(id -u postgres)" --env="USERMAP_GID=$(id -g postgres)" \ 342 | romeoz/docker-postgresql 343 | ``` 344 | 345 | Environment variables 346 | --------------------- 347 | 348 | `PG_USER`: Set a specific username for the admin account (default "postgres"). 349 | 350 | `PG_TZ`: Set a timezone DB (default "UTC"). 351 | 352 | `PG_MODE`: Set a specific mode. Takes on the values `master`, `slave` or `backup`. 353 | 354 | `PG_BACKUP_DIR`: Set a specific backup directory (default "/tmp/backup"). 355 | 356 | `PG_BACKUP_FILENAME`: Set a specific filename backup (default "backup.last.bz2"). 357 | 358 | `PG_CHECK`: Defines name of backup-file to initialize the database. Note that the backup must be inside the container, so you may need to mount them. You can specify as `default` that is equivalent to the `/tmp/backup/backup.last.bz2` 359 | 360 | `PG_RESTORE`: Defines name of backup-file to initialize the database. Note that the backup must be inside the container, so you may need to mount them. You can specify as `default` that is equivalent to the `/tmp/backup/backup.last.bz2` 361 | 362 | `PG_ROTATE_BACKUP`: Determines whether to use the rotation of backups (default "true"). 363 | 364 | `REPLICATION_PORT`: Set a specific replication port for the master instance (default "5432"). 365 | 366 | `REPLICATION_USER`: Set a specific replication username for the master instance (default "replica"). 367 | 368 | `REPLICATION_PASS`: Set a specific replication password for the master instance (default "replica"). 369 | 370 | `PG_TRUST_LOCALNET`: Set this env variable to true to enable a line in the pg_hba.conf file to trust samenet. This can be used to connect from other containers on the same host without authentication (default "false"). 371 | 372 | `PG_SSLMODE`: Set this env variable to "require" to enable encryption and "verify-full" for verification (default "disable"). 373 | 374 | `DB_NAME`: Set name DB. 375 | 376 | `DB_USER`: Set name by user. 377 | 378 | `DB_PASS`: Set password by user. 379 | 380 | `DB_LOCALE` (alias `OS_LOCALE`): Set a locale DB (default "en_US.UTF-8"). 381 | 382 | Logging 383 | ------------------- 384 | 385 | All the logs are forwarded to stdout and sterr. You have use the command `docker logs`. 386 | 387 | ```bash 388 | docker logs postgresql 389 | ``` 390 | 391 | ####Split the logs 392 | 393 | You can then simply split the stdout & stderr of the container by piping the separate streams and send them to files: 394 | 395 | ```bash 396 | docker logs postgresql > stdout.log 2>stderr.log 397 | cat stdout.log 398 | cat stderr.log 399 | ``` 400 | 401 | or split stdout and error to host stdout: 402 | 403 | ```bash 404 | docker logs postgresql > - 405 | docker logs postgresql 2> - 406 | ``` 407 | 408 | ####Rotate logs 409 | 410 | Create the file `/etc/logrotate.d/docker-containers` with the following text inside: 411 | 412 | ``` 413 | /var/lib/docker/containers/*/*.log { 414 | rotate 31 415 | daily 416 | nocompress 417 | missingok 418 | notifempty 419 | copytruncate 420 | } 421 | ``` 422 | > Optionally, you can replace `nocompress` to `compress` and change the number of days. 423 | 424 | Out of the box 425 | ------------------- 426 | * Ubuntu 16.04/18.04 LTS 427 | * PostgreSQL 9.3, 9.4, 9.5, 9.6, 10 or 11 428 | 429 | License 430 | ------------------- 431 | 432 | PostgreSQL docker image is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT) --------------------------------------------------------------------------------