From 908f4408cfde4ae5a0a2a4564088066eea5fa25e Mon Sep 17 00:00:00 2001 From: Qi Zheng Date: Fri, 9 Aug 2019 21:45:59 +0000 Subject: [PATCH] Update postgresql from 9 to 11 Signed-off-by: Qi Zheng --- postgres/Dockerfile | 21 +++-- postgres/docker-entrypoint.sh | 171 ++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+), 7 deletions(-) create mode 100644 postgres/docker-entrypoint.sh diff --git a/postgres/Dockerfile b/postgres/Dockerfile index 21fb1da..d830583 100644 --- a/postgres/Dockerfile +++ b/postgres/Dockerfile @@ -17,7 +17,7 @@ RUN source /os-release && \ mkdir /install_root \ && swupd os-install -V ${VERSION_ID} \ --path /install_root --statedir /swupd-state \ - --bundles=postgresql,su-exec --no-boot-update + --bundles=postgresql11,su-exec --no-boot-update # For some Host OS configuration with redirect_dir on, # extra data are saved on the upper layer when the same @@ -32,14 +32,21 @@ FROM clearlinux/os-core:latest COPY --from=builder /install_root / +ENV PATH $PATH:/usr/libexec/postgresql11 ENV PGDATA /var/lib/pgsql/data -RUN mkdir -p /run/postgresql && chown -R postgres:postgres /run/postgresql -RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" -VOLUME /var/lib/pgsql/data +RUN sed -i "s|#listen_addresses.*|listen_addresses = '*'|" /usr/share/postgresql11/postgresql.conf.sample && \ + mkdir -p /run/postgresql11 && chown -R postgres:postgres /run/postgresql11 && \ + mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && \ + mkdir /docker-entrypoint-initdb.d && \ + mkdir -p /usr/local/bin -RUN mkdir -p /usr/local/bin -COPY bootstrap.sh /usr/local/bin -ENTRYPOINT ["bootstrap.sh"] +VOLUME /var/lib/pgsql/data +COPY docker-entrypoint.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/docker-entrypoint.sh && \ + ln -s /usr/local/bin/docker-entrypoint.sh / && \ + ln -s /usr/share/postgresql11 /usr/share/postgresql + +ENTRYPOINT ["docker-entrypoint.sh"] EXPOSE 5432 CMD ["postgres"] diff --git a/postgres/docker-entrypoint.sh b/postgres/docker-entrypoint.sh new file mode 100644 index 0000000..8f09db9 --- /dev/null +++ b/postgres/docker-entrypoint.sh @@ -0,0 +1,171 @@ +#!/usr/bin/env bash +set -Eeo pipefail +# TODO swap to -Eeuo pipefail above (after handling all potentially-unset variables) + +# usage: file_env VAR [DEFAULT] +# ie: file_env 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +file_env() { + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + local val="$def" + if [ "${!var:-}" ]; then + val="${!var}" + elif [ "${!fileVar:-}" ]; then + val="$(< "${!fileVar}")" + fi + export "$var"="$val" + unset "$fileVar" +} + +if [ "${1:0:1}" = '-' ]; then + set -- postgres "$@" +fi + +# allow the container to be started with `--user` +if [ "$1" = 'postgres' ] && [ "$(id -u)" = '0' ]; then + mkdir -p "$PGDATA" + chown -R postgres "$PGDATA" + chmod 700 "$PGDATA" + + mkdir -p /var/run/postgresql11 + chown -R postgres /var/run/postgresql11 + chmod 775 /var/run/postgresql11 + + # Create the transaction log directory before initdb is run (below) so the directory is owned by the correct user + if [ "$POSTGRES_INITDB_WALDIR" ]; then + mkdir -p "$POSTGRES_INITDB_WALDIR" + chown -R postgres "$POSTGRES_INITDB_WALDIR" + chmod 700 "$POSTGRES_INITDB_WALDIR" + fi + + exec su-exec postgres "$BASH_SOURCE" "$@" +fi + +if [ "$1" = 'postgres' ]; then + mkdir -p "$PGDATA" + chown -R "$(id -u)" "$PGDATA" 2>/dev/null || : + chmod 700 "$PGDATA" 2>/dev/null || : + + # look specifically for PG_VERSION, as it is expected in the DB dir + if [ ! -s "$PGDATA/PG_VERSION" ]; then + # "initdb" is particular about the current user existing in "/etc/passwd", so we use "nss_wrapper" to fake that if necessary + # see https://github.com/docker-library/postgres/pull/253, https://github.com/docker-library/postgres/issues/359, https://cwrap.org/nss_wrapper.html + if ! getent passwd "$(id -u)" &> /dev/null && [ -e /usr/lib/libnss_wrapper.so ]; then + export LD_PRELOAD='/usr/lib/libnss_wrapper.so' + export NSS_WRAPPER_PASSWD="$(mktemp)" + export NSS_WRAPPER_GROUP="$(mktemp)" + echo "postgres:x:$(id -u):$(id -g):PostgreSQL:$PGDATA:/bin/false" > "$NSS_WRAPPER_PASSWD" + echo "postgres:x:$(id -g):" > "$NSS_WRAPPER_GROUP" + fi + + file_env 'POSTGRES_USER' 'postgres' + file_env 'POSTGRES_PASSWORD' + + file_env 'POSTGRES_INITDB_ARGS' + if [ "$POSTGRES_INITDB_WALDIR" ]; then + export POSTGRES_INITDB_ARGS="$POSTGRES_INITDB_ARGS --waldir $POSTGRES_INITDB_WALDIR" + fi + eval 'initdb --username="$POSTGRES_USER" --pwfile=<(echo "$POSTGRES_PASSWORD") '"$POSTGRES_INITDB_ARGS" + + # unset/cleanup "nss_wrapper" bits + if [ "${LD_PRELOAD:-}" = '/usr/lib/libnss_wrapper.so' ]; then + rm -f "$NSS_WRAPPER_PASSWD" "$NSS_WRAPPER_GROUP" + unset LD_PRELOAD NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP + fi + + # check password first so we can output the warning before postgres + # messes it up + if [ -n "$POSTGRES_PASSWORD" ]; then + authMethod=md5 + + if [ "${#POSTGRES_PASSWORD}" -ge 100 ]; then + cat >&2 <<-'EOWARN' + WARNING: The supplied POSTGRES_PASSWORD is 100+ characters. + This will not work if used via PGPASSWORD with "psql". + https://www.postgresql.org/message-id/flat/E1Rqxp2-0004Qt-PL%40wrigleys.postgresql.org (BUG #6412) + https://github.com/docker-library/postgres/issues/507 + EOWARN + fi + else + # The - option suppresses leading tabs but *not* spaces. :) + cat >&2 <<-'EOWARN' + **************************************************** + WARNING: No password has been set for the database. + This will allow anyone with access to the + Postgres port to access your database. In + Docker's default configuration, this is + effectively any other container on the same + system. + Use "-e POSTGRES_PASSWORD=password" to set + it in "docker run". + **************************************************** + EOWARN + + authMethod=trust + fi + + { + echo + echo "host all all all $authMethod" + } >> "$PGDATA/pg_hba.conf" + + # internal start of server in order to allow set-up using psql-client + # does not listen on external TCP/IP and waits until start finishes + PGUSER="${PGUSER:-$POSTGRES_USER}" \ + pg_ctl -D "$PGDATA" \ + -o "-c listen_addresses=''" \ + -w start + + file_env 'POSTGRES_DB' "$POSTGRES_USER" + + export PGPASSWORD="${PGPASSWORD:-$POSTGRES_PASSWORD}" + psql=( psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --no-password ) + + if [ "$POSTGRES_DB" != 'postgres' ]; then + "${psql[@]}" --dbname postgres --set db="$POSTGRES_DB" <<-'EOSQL' + CREATE DATABASE :"db" ; + EOSQL + echo + fi + psql+=( --dbname "$POSTGRES_DB" ) + + echo + for f in /docker-entrypoint-initdb.d/*; do + case "$f" in + *.sh) + # https://github.com/docker-library/postgres/issues/450#issuecomment-393167936 + # https://github.com/docker-library/postgres/pull/452 + if [ -x "$f" ]; then + echo "$0: running $f" + "$f" + else + echo "$0: sourcing $f" + . "$f" + fi + ;; + *.sql) echo "$0: running $f"; "${psql[@]}" -f "$f"; echo ;; + *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${psql[@]}"; echo ;; + *) echo "$0: ignoring $f" ;; + esac + echo + done + + PGUSER="${PGUSER:-$POSTGRES_USER}" \ + pg_ctl -D "$PGDATA" -m fast -w stop + + unset PGPASSWORD + + echo + echo 'PostgreSQL init process complete; ready for start up.' + echo + fi +fi + +exec "$@"