From 6f7881a307a7856aa7671260b1f0b690ca51b740 Mon Sep 17 00:00:00 2001 From: Piotr Brzuska Date: Thu, 23 May 2019 20:35:30 +0200 Subject: [PATCH 1/4] Add 12~beta1 --- 12/Dockerfile | 177 +++++++++++++++++++++++++++++++++ 12/alpine/Dockerfile | 154 ++++++++++++++++++++++++++++ 12/alpine/docker-entrypoint.sh | 176 ++++++++++++++++++++++++++++++++ 12/docker-entrypoint.sh | 176 ++++++++++++++++++++++++++++++++ 4 files changed, 683 insertions(+) create mode 100644 12/Dockerfile create mode 100644 12/alpine/Dockerfile create mode 100755 12/alpine/docker-entrypoint.sh create mode 100755 12/docker-entrypoint.sh diff --git a/12/Dockerfile b/12/Dockerfile new file mode 100644 index 0000000000..312eb12255 --- /dev/null +++ b/12/Dockerfile @@ -0,0 +1,177 @@ +# vim:set ft=dockerfile: +FROM debian:stretch-slim + +RUN set -ex; \ + if ! command -v gpg > /dev/null; then \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + gnupg \ + dirmngr \ + ; \ + rm -rf /var/lib/apt/lists/*; \ + fi + +# explicitly set user/group IDs +RUN set -eux; \ + groupadd -r postgres --gid=999; \ +# https://salsa.debian.org/postgresql/postgresql-common/blob/997d842ee744687d99a2b2d95c1083a2615c79e8/debian/postgresql-common.postinst#L32-35 + useradd -r -g postgres --uid=999 --home-dir=/var/lib/postgresql --shell=/bin/bash postgres; \ +# also create the postgres user's home directory with appropriate permissions +# see https://github.com/docker-library/postgres/issues/274 + mkdir -p /var/lib/postgresql; \ + chown -R postgres:postgres /var/lib/postgresql + +# grab gosu for easy step-down from root +ENV GOSU_VERSION 1.11 +RUN set -x \ + && apt-get update && apt-get install -y --no-install-recommends ca-certificates wget && rm -rf /var/lib/apt/lists/* \ + && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \ + && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \ + && export GNUPGHOME="$(mktemp -d)" \ + && gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \ + && gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \ + && { command -v gpgconf > /dev/null && gpgconf --kill all || :; } \ + && rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc \ + && chmod +x /usr/local/bin/gosu \ + && gosu nobody true \ + && apt-get purge -y --auto-remove ca-certificates wget + +# make the "en_US.UTF-8" locale so postgres will be utf-8 enabled by default +RUN set -eux; \ + if [ -f /etc/dpkg/dpkg.cfg.d/docker ]; then \ +# if this file exists, we're likely in "debian:xxx-slim", and locales are thus being excluded so we need to remove that exclusion (since we need locales) + grep -q '/usr/share/locale' /etc/dpkg/dpkg.cfg.d/docker; \ + sed -ri '/\/usr\/share\/locale/d' /etc/dpkg/dpkg.cfg.d/docker; \ + ! grep -q '/usr/share/locale' /etc/dpkg/dpkg.cfg.d/docker; \ + fi; \ + apt-get update; apt-get install -y locales; rm -rf /var/lib/apt/lists/*; \ + localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 +ENV LANG en_US.utf8 + +# install "nss_wrapper" in case we need to fake "/etc/passwd" and "/etc/group" (especially for OpenShift) +# https://github.com/docker-library/postgres/issues/359 +# https://cwrap.org/nss_wrapper.html +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends libnss-wrapper; \ + rm -rf /var/lib/apt/lists/* + +RUN mkdir /docker-entrypoint-initdb.d + +RUN set -ex; \ +# pub 4096R/ACCC4CF8 2011-10-13 [expires: 2019-07-02] +# Key fingerprint = B97B 0AFC AA1A 47F0 44F2 44A0 7FCC 7D46 ACCC 4CF8 +# uid PostgreSQL Debian Repository + key='B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8'; \ + export GNUPGHOME="$(mktemp -d)"; \ + gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \ + gpg --batch --export "$key" > /etc/apt/trusted.gpg.d/postgres.gpg; \ + command -v gpgconf > /dev/null && gpgconf --kill all; \ + rm -rf "$GNUPGHOME"; \ + apt-key list + +ENV PG_MAJOR 12 +ENV PG_VERSION 12~beta1-1.pgdg90+1 + +RUN set -ex; \ + \ +# see note below about "*.pyc" files + export PYTHONDONTWRITEBYTECODE=1; \ + \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "$dpkgArch" in \ + amd64|i386|ppc64el) \ +# arches officialy built by upstream + echo "deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main $PG_MAJOR" > /etc/apt/sources.list.d/pgdg.list; \ + echo "deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg-testing main $PG_MAJOR" > /etc/apt/sources.list.d/pgdg-testing.list; \ + apt-get update; \ + ;; \ + *) \ +# we're on an architecture upstream doesn't officially build for +# let's build binaries from their published source packages + echo "deb-src http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main $PG_MAJOR" > /etc/apt/sources.list.d/pgdg.list; \ + \ + case "$PG_MAJOR" in \ + 9.* | 10 ) ;; \ + *) \ +# https://github.com/docker-library/postgres/issues/484 (clang-6.0 required, only available in stretch-backports) +# TODO remove this once we hit buster+ + echo 'deb http://deb.debian.org/debian stretch-backports main' >> /etc/apt/sources.list.d/pgdg.list; \ + ;; \ + esac; \ + \ + tempDir="$(mktemp -d)"; \ + cd "$tempDir"; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + \ +# build .deb files from upstream's source packages (which are verified by apt-get) + apt-get update; \ + apt-get build-dep -y \ + postgresql-common pgdg-keyring \ + "postgresql-$PG_MAJOR=$PG_VERSION" \ + ; \ + DEB_BUILD_OPTIONS="nocheck parallel=$(nproc)" \ + apt-get source --compile \ + postgresql-common pgdg-keyring \ + "postgresql-$PG_MAJOR=$PG_VERSION" \ + ; \ +# we don't remove APT lists here because they get re-downloaded and removed later + \ +# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies +# (which is done after we install the built packages so we don't have to redownload any overlapping dependencies) + apt-mark showmanual | xargs apt-mark auto > /dev/null; \ + apt-mark manual $savedAptMark; \ + \ +# create a temporary local APT repo to install from (so that dependency resolution can be handled by APT, as it should be) + ls -lAFh; \ + dpkg-scanpackages . > Packages; \ + grep '^Package: ' Packages; \ + echo "deb [ trusted=yes ] file://$tempDir ./" > /etc/apt/sources.list.d/temp.list; \ +# work around the following APT issue by using "Acquire::GzipIndexes=false" (overriding "/etc/apt/apt.conf.d/docker-gzip-indexes") +# Could not open file /var/lib/apt/lists/partial/_tmp_tmp.ODWljpQfkE_._Packages - open (13: Permission denied) +# ... +# E: Failed to fetch store:/var/lib/apt/lists/partial/_tmp_tmp.ODWljpQfkE_._Packages Could not open file /var/lib/apt/lists/partial/_tmp_tmp.ODWljpQfkE_._Packages - open (13: Permission denied) + apt-get -o Acquire::GzipIndexes=false update; \ + ;; \ + esac; \ + \ + apt-get install -y postgresql-common; \ + sed -ri 's/#(create_main_cluster) .*$/\1 = false/' /etc/postgresql-common/createcluster.conf; \ + apt-get install -y \ + "postgresql-$PG_MAJOR=$PG_VERSION" \ + ; \ + \ + rm -rf /var/lib/apt/lists/*; \ + \ + if [ -n "$tempDir" ]; then \ +# if we have leftovers from building, let's purge them (including extra, unnecessary build deps) + apt-get purge -y --auto-remove; \ + rm -rf "$tempDir" /etc/apt/sources.list.d/temp.list; \ + fi; \ + \ +# some of the steps above generate a lot of "*.pyc" files (and setting "PYTHONDONTWRITEBYTECODE" beforehand doesn't propagate properly for some reason), so we clean them up manually (as long as they aren't owned by a package) + find /usr -name '*.pyc' -type f -exec bash -c 'for pyc; do dpkg -S "$pyc" &> /dev/null || rm -vf "$pyc"; done' -- '{}' + + +# make the sample config easier to munge (and "correct by default") +RUN set -eux; \ + dpkg-divert --add --rename --divert "/usr/share/postgresql/postgresql.conf.sample.dpkg" "/usr/share/postgresql/$PG_MAJOR/postgresql.conf.sample"; \ + cp -v /usr/share/postgresql/postgresql.conf.sample.dpkg /usr/share/postgresql/postgresql.conf.sample; \ + ln -sv ../postgresql.conf.sample "/usr/share/postgresql/$PG_MAJOR/"; \ + sed -ri "s!^#?(listen_addresses)\s*=\s*\S+.*!\1 = '*'!" /usr/share/postgresql/postgresql.conf.sample; \ + grep -F "listen_addresses = '*'" /usr/share/postgresql/postgresql.conf.sample + +RUN mkdir -p /var/run/postgresql && chown -R postgres:postgres /var/run/postgresql && chmod 2777 /var/run/postgresql + +ENV PATH $PATH:/usr/lib/postgresql/$PG_MAJOR/bin +ENV PGDATA /var/lib/postgresql/data +# this 777 will be replaced by 700 at runtime (allows semi-arbitrary "--user" values) +RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PGDATA" +VOLUME /var/lib/postgresql/data + +COPY docker-entrypoint.sh /usr/local/bin/ +RUN ln -s usr/local/bin/docker-entrypoint.sh / # backwards compat +ENTRYPOINT ["docker-entrypoint.sh"] + +EXPOSE 5432 +CMD ["postgres"] diff --git a/12/alpine/Dockerfile b/12/alpine/Dockerfile new file mode 100644 index 0000000000..12fe77b2a7 --- /dev/null +++ b/12/alpine/Dockerfile @@ -0,0 +1,154 @@ +# vim:set ft=dockerfile: +FROM alpine:3.9 + +# alpine includes "postgres" user/group in base install +# /etc/passwd:22:postgres:x:70:70::/var/lib/postgresql:/bin/sh +# /etc/group:34:postgres:x:70: +# the home directory for the postgres user, however, is not created by default +# see https://github.com/docker-library/postgres/issues/274 +RUN set -ex; \ + postgresHome="$(getent passwd postgres)"; \ + postgresHome="$(echo "$postgresHome" | cut -d: -f6)"; \ + [ "$postgresHome" = '/var/lib/postgresql' ]; \ + mkdir -p "$postgresHome"; \ + chown -R postgres:postgres "$postgresHome" + +# su-exec (gosu-compatible) is installed further down + +# make the "en_US.UTF-8" locale so postgres will be utf-8 enabled by default +# alpine doesn't require explicit locale-file generation +ENV LANG en_US.utf8 + +RUN mkdir /docker-entrypoint-initdb.d + +ENV PG_MAJOR 12 +ENV PG_VERSION 12beta1 +ENV PG_SHA256 203e2d0151d75e3328a6b6b85eae88e50168ae27423b39787cea595365da9fad + +RUN set -ex \ + \ + && apk add --no-cache --virtual .fetch-deps \ + ca-certificates \ + openssl \ + tar \ + \ + && wget -O postgresql.tar.bz2 "https://ftp.postgresql.org/pub/source/v$PG_VERSION/postgresql-$PG_VERSION.tar.bz2" \ + && echo "$PG_SHA256 *postgresql.tar.bz2" | sha256sum -c - \ + && mkdir -p /usr/src/postgresql \ + && tar \ + --extract \ + --file postgresql.tar.bz2 \ + --directory /usr/src/postgresql \ + --strip-components 1 \ + && rm postgresql.tar.bz2 \ + \ + && apk add --no-cache --virtual .build-deps \ + bison \ + coreutils \ + dpkg-dev dpkg \ + flex \ + gcc \ +# krb5-dev \ + libc-dev \ + libedit-dev \ + libxml2-dev \ + libxslt-dev \ + linux-headers \ + make \ +# openldap-dev \ + openssl-dev \ +# configure: error: prove not found + perl-utils \ +# configure: error: Perl module IPC::Run is required to run TAP tests + perl-ipc-run \ +# perl-dev \ +# python-dev \ +# python3-dev \ +# tcl-dev \ + util-linux-dev \ + zlib-dev \ + icu-dev \ + \ + && cd /usr/src/postgresql \ +# update "DEFAULT_PGSOCKET_DIR" to "/var/run/postgresql" (matching Debian) +# see https://anonscm.debian.org/git/pkg-postgresql/postgresql.git/tree/debian/patches/51-default-sockets-in-var.patch?id=8b539fcb3e093a521c095e70bdfa76887217b89f + && awk '$1 == "#define" && $2 == "DEFAULT_PGSOCKET_DIR" && $3 == "\"/tmp\"" { $3 = "\"/var/run/postgresql\""; print; next } { print }' src/include/pg_config_manual.h > src/include/pg_config_manual.h.new \ + && grep '/var/run/postgresql' src/include/pg_config_manual.h.new \ + && mv src/include/pg_config_manual.h.new src/include/pg_config_manual.h \ + && gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)" \ +# explicitly update autoconf config.guess and config.sub so they support more arches/libcs + && wget -O config/config.guess 'https://git.savannah.gnu.org/cgit/config.git/plain/config.guess?id=7d3d27baf8107b630586c962c057e22149653deb' \ + && wget -O config/config.sub 'https://git.savannah.gnu.org/cgit/config.git/plain/config.sub?id=7d3d27baf8107b630586c962c057e22149653deb' \ +# configure options taken from: +# https://anonscm.debian.org/cgit/pkg-postgresql/postgresql.git/tree/debian/rules?h=9.5 + && ./configure \ + --build="$gnuArch" \ +# "/usr/src/postgresql/src/backend/access/common/tupconvert.c:105: undefined reference to `libintl_gettext'" +# --enable-nls \ + --enable-integer-datetimes \ + --enable-thread-safety \ + --enable-tap-tests \ +# skip debugging info -- we want tiny size instead +# --enable-debug \ + --disable-rpath \ + --with-uuid=e2fs \ + --with-gnu-ld \ + --with-pgport=5432 \ + --with-system-tzdata=/usr/share/zoneinfo \ + --prefix=/usr/local \ + --with-includes=/usr/local/include \ + --with-libraries=/usr/local/lib \ + \ +# these make our image abnormally large (at least 100MB larger), which seems uncouth for an "Alpine" (ie, "small") variant :) +# --with-krb5 \ +# --with-gssapi \ +# --with-ldap \ +# --with-tcl \ +# --with-perl \ +# --with-python \ +# --with-pam \ + --with-openssl \ + --with-libxml \ + --with-libxslt \ + --with-icu \ + && make -j "$(nproc)" world \ + && make install-world \ + && make -C contrib install \ + \ + && runDeps="$( \ + scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \ + | tr ',' '\n' \ + | sort -u \ + | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ + )" \ + && apk add --no-cache --virtual .postgresql-rundeps \ + $runDeps \ + bash \ + su-exec \ +# tzdata is optional, but only adds around 1Mb to image size and is recommended by Django documentation: +# https://docs.djangoproject.com/en/1.10/ref/databases/#optimizing-postgresql-s-configuration + tzdata \ + && apk del .fetch-deps .build-deps \ + && cd / \ + && rm -rf \ + /usr/src/postgresql \ + /usr/local/share/doc \ + /usr/local/share/man \ + && find /usr/local -name '*.a' -delete + +# make the sample config easier to munge (and "correct by default") +RUN sed -ri "s!^#?(listen_addresses)\s*=\s*\S+.*!\1 = '*'!" /usr/local/share/postgresql/postgresql.conf.sample + +RUN mkdir -p /var/run/postgresql && chown -R postgres:postgres /var/run/postgresql && chmod 2777 /var/run/postgresql + +ENV PGDATA /var/lib/postgresql/data +# this 777 will be replaced by 700 at runtime (allows semi-arbitrary "--user" values) +RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PGDATA" +VOLUME /var/lib/postgresql/data + +COPY docker-entrypoint.sh /usr/local/bin/ +RUN ln -s usr/local/bin/docker-entrypoint.sh / # backwards compat +ENTRYPOINT ["docker-entrypoint.sh"] + +EXPOSE 5432 +CMD ["postgres"] diff --git a/12/alpine/docker-entrypoint.sh b/12/alpine/docker-entrypoint.sh new file mode 100755 index 0000000000..6dce8a15c6 --- /dev/null +++ b/12/alpine/docker-entrypoint.sh @@ -0,0 +1,176 @@ +#!/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/postgresql + chown -R postgres /var/run/postgresql + chmod 775 /var/run/postgresql + + # 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 "$@" diff --git a/12/docker-entrypoint.sh b/12/docker-entrypoint.sh new file mode 100755 index 0000000000..93ee4fba4d --- /dev/null +++ b/12/docker-entrypoint.sh @@ -0,0 +1,176 @@ +#!/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/postgresql + chown -R postgres /var/run/postgresql + chmod 775 /var/run/postgresql + + # 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 gosu 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 "$@" From e3d200e6becb79d9573d072810c2a5846d74942d Mon Sep 17 00:00:00 2001 From: Piotr Brzuska Date: Thu, 23 May 2019 20:46:21 +0200 Subject: [PATCH 2/4] Add 12~beta1 into Travis config --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index eaa66e00e1..c4d4c21d21 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,9 @@ language: bash services: docker env: + - VERSION=12 + - VERSION=12 FORCE_DEB_BUILD=1 + - VERSION=12 VARIANT=alpine - VERSION=11 - VERSION=11 FORCE_DEB_BUILD=1 - VERSION=11 VARIANT=alpine From 5992d8be755d8001474f737a44c73049c519cff3 Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Thu, 30 May 2019 13:17:17 -0700 Subject: [PATCH 3/4] Update "Dockerfile-alpine.template" and apply "update.sh" (after verifying that 12 still builds and works properly without the added "-testing" repository) --- 10/alpine/Dockerfile | 1 + 11/alpine/Dockerfile | 1 + 12/Dockerfile | 3 +-- 12/alpine/Dockerfile | 1 - 9.4/alpine/Dockerfile | 1 + 9.5/alpine/Dockerfile | 1 + 9.6/alpine/Dockerfile | 1 + Dockerfile-alpine.template | 1 + 8 files changed, 7 insertions(+), 3 deletions(-) diff --git a/10/alpine/Dockerfile b/10/alpine/Dockerfile index 126b1e8456..ab42d304b7 100644 --- a/10/alpine/Dockerfile +++ b/10/alpine/Dockerfile @@ -53,6 +53,7 @@ RUN set -ex \ libedit-dev \ libxml2-dev \ libxslt-dev \ + linux-headers \ make \ # openldap-dev \ openssl-dev \ diff --git a/11/alpine/Dockerfile b/11/alpine/Dockerfile index ffc861419c..f792826053 100644 --- a/11/alpine/Dockerfile +++ b/11/alpine/Dockerfile @@ -53,6 +53,7 @@ RUN set -ex \ libedit-dev \ libxml2-dev \ libxslt-dev \ + linux-headers \ make \ # openldap-dev \ openssl-dev \ diff --git a/12/Dockerfile b/12/Dockerfile index 312eb12255..134ba2d438 100644 --- a/12/Dockerfile +++ b/12/Dockerfile @@ -82,8 +82,7 @@ RUN set -ex; \ case "$dpkgArch" in \ amd64|i386|ppc64el) \ # arches officialy built by upstream - echo "deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main $PG_MAJOR" > /etc/apt/sources.list.d/pgdg.list; \ - echo "deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg-testing main $PG_MAJOR" > /etc/apt/sources.list.d/pgdg-testing.list; \ + echo "deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main $PG_MAJOR" > /etc/apt/sources.list.d/pgdg.list; \ apt-get update; \ ;; \ *) \ diff --git a/12/alpine/Dockerfile b/12/alpine/Dockerfile index 12fe77b2a7..b01912e82e 100644 --- a/12/alpine/Dockerfile +++ b/12/alpine/Dockerfile @@ -147,7 +147,6 @@ RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PG VOLUME /var/lib/postgresql/data COPY docker-entrypoint.sh /usr/local/bin/ -RUN ln -s usr/local/bin/docker-entrypoint.sh / # backwards compat ENTRYPOINT ["docker-entrypoint.sh"] EXPOSE 5432 diff --git a/9.4/alpine/Dockerfile b/9.4/alpine/Dockerfile index e2d77a19d5..ca66a98d5e 100644 --- a/9.4/alpine/Dockerfile +++ b/9.4/alpine/Dockerfile @@ -53,6 +53,7 @@ RUN set -ex \ libedit-dev \ libxml2-dev \ libxslt-dev \ + linux-headers \ make \ # openldap-dev \ openssl-dev \ diff --git a/9.5/alpine/Dockerfile b/9.5/alpine/Dockerfile index 905d69f37f..7128018a0b 100644 --- a/9.5/alpine/Dockerfile +++ b/9.5/alpine/Dockerfile @@ -53,6 +53,7 @@ RUN set -ex \ libedit-dev \ libxml2-dev \ libxslt-dev \ + linux-headers \ make \ # openldap-dev \ openssl-dev \ diff --git a/9.6/alpine/Dockerfile b/9.6/alpine/Dockerfile index f6fe91d1af..6dbf8b8248 100644 --- a/9.6/alpine/Dockerfile +++ b/9.6/alpine/Dockerfile @@ -53,6 +53,7 @@ RUN set -ex \ libedit-dev \ libxml2-dev \ libxslt-dev \ + linux-headers \ make \ # openldap-dev \ openssl-dev \ diff --git a/Dockerfile-alpine.template b/Dockerfile-alpine.template index a77577a361..217c60ffbc 100644 --- a/Dockerfile-alpine.template +++ b/Dockerfile-alpine.template @@ -53,6 +53,7 @@ RUN set -ex \ libedit-dev \ libxml2-dev \ libxslt-dev \ + linux-headers \ make \ # openldap-dev \ openssl-dev \ From 966d1ba7a639171895acee9b33cc6b8053498d18 Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Thu, 30 May 2019 13:28:13 -0700 Subject: [PATCH 4/4] Update 12+ to buster This is an initial attempt to get ahead of https://github.com/docker-library/postgres/issues/582 at least for newer PostgreSQL releases. --- 12/Dockerfile | 10 +++++----- update.sh | 9 +++++++-- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/12/Dockerfile b/12/Dockerfile index 134ba2d438..57db5f9dff 100644 --- a/12/Dockerfile +++ b/12/Dockerfile @@ -1,5 +1,5 @@ # vim:set ft=dockerfile: -FROM debian:stretch-slim +FROM debian:buster-slim RUN set -ex; \ if ! command -v gpg > /dev/null; then \ @@ -71,7 +71,7 @@ RUN set -ex; \ apt-key list ENV PG_MAJOR 12 -ENV PG_VERSION 12~beta1-1.pgdg90+1 +ENV PG_VERSION 12~beta1-1.pgdg100+1 RUN set -ex; \ \ @@ -82,20 +82,20 @@ RUN set -ex; \ case "$dpkgArch" in \ amd64|i386|ppc64el) \ # arches officialy built by upstream - echo "deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main $PG_MAJOR" > /etc/apt/sources.list.d/pgdg.list; \ + echo "deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main $PG_MAJOR" > /etc/apt/sources.list.d/pgdg.list; \ apt-get update; \ ;; \ *) \ # we're on an architecture upstream doesn't officially build for # let's build binaries from their published source packages - echo "deb-src http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main $PG_MAJOR" > /etc/apt/sources.list.d/pgdg.list; \ + echo "deb-src http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main $PG_MAJOR" > /etc/apt/sources.list.d/pgdg.list; \ \ case "$PG_MAJOR" in \ 9.* | 10 ) ;; \ *) \ # https://github.com/docker-library/postgres/issues/484 (clang-6.0 required, only available in stretch-backports) # TODO remove this once we hit buster+ - echo 'deb http://deb.debian.org/debian stretch-backports main' >> /etc/apt/sources.list.d/pgdg.list; \ + echo 'deb http://deb.debian.org/debian buster-backports main' >> /etc/apt/sources.list.d/pgdg.list; \ ;; \ esac; \ \ diff --git a/update.sh b/update.sh index 8664ff1fef..8432b9add9 100755 --- a/update.sh +++ b/update.sh @@ -12,9 +12,14 @@ versions=( "${versions[@]%/}" ) # sort version numbers with highest last (so it goes first in .travis.yml) IFS=$'\n'; versions=( $(echo "${versions[*]}" | sort -V) ); unset IFS -defaultDebianSuite='stretch-slim' +defaultDebianSuite='buster-slim' declare -A debianSuite=( - #[9.6]='jessie' + # https://github.com/docker-library/postgres/issues/582 + [9.4]='stretch-slim' + [9.5]='stretch-slim' + [9.6]='stretch-slim' + [10]='stretch-slim' + [11]='stretch-slim' ) defaultAlpineVersion='3.9' declare -A alpineVersion=(