diff --git a/Dockerfile b/Dockerfile index ab6edba..79b62a8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,9 @@ FROM postgres:15 - -RUN mkdir -p "$PGDATA" && \ - chmod 00700 "$PGDATA" && \ - mkdir -p /var/run/postgresql && \ - chmod 03755 /var/run/postgresql - -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - postgresql-15-pgpool2 \ - && \ - rm -rf /var/lib/apt/lists/* +RUN set -eux && \ + groupadd -r postgres --gid=5432 && \ + useradd -r -g postgres --uid=5432 --home-dir=/var/lib/postgresql --shell=/bin/bash postgres && \ + install --verbose --directory --owner postgres --group postgres --mode 1755 /var/lib/postgresql RUN apt-get update && \ apt-get install -y --no-install-recommends \ @@ -18,13 +11,109 @@ RUN apt-get update && \ sudo \ && \ rm -rf /var/lib/apt/lists/* && \ - echo "postgres ALL = (ALL) NOPASSWD:ALL" >> /etc/sudoers && \ + echo "postgres ALL = (ALL) NOPASSWD:ALL" >> /etc/sudoers && \ echo "X11Forwarding no" >> /etc/ssh/sshd_config && \ echo "PasswordAuthentication no" >> /etc/ssh/sshd_config && \ echo "StrictHostKeyChecking no" >> /etc/ssh/ssh_config -COPY --chown=postgres:postgres postgres /var/lib/postgresql/ +RUN set -ex && \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + gnupg \ + less \ + && \ + rm -rf /var/lib/apt/lists/* + +ENV GOSU_VERSION=1.19 +RUN set -eux && \ + savedAptMark="$(apt-mark showmanual)" && \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + wget \ + && \ + rm -rf /var/lib/apt/lists/* && \ + dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')" && \ + wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-${dpkgArch}" && \ + wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-${dpkgArch}.asc" &6 \ + export GNUPGHOME="$(mktemp -d)" && \ + gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 && \ + gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu && \ + gpgconf --kill all && \ + rm -rf "${GNUPGHOME}" /usr/local/bin/gosu.asc && \ + apt-mark auto '.*' > /dev/null && \ + [ -z "${savedAptMark}" ] || apt-mark manual "${savedAptMark}" > /dev/null && \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false && \ + chmod +x /usr/local/bin/gosu && \ + gosu --version && \ + gosu nobody true + +RUN set -eux; \ + 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 && \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + locales && \ + rm -rf /var/lib/apt/lists/* && \ + echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen && \ + locale-gen && \ + locale -a | grep 'en_US.utf8' +ENV LANG=en_US.utf8 + +RUN set -eux && \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + xz-utils \ + zstd \ + && \ + rm -rf /var/lib/apt/lists/* + +RUN set -ex && \ + key='B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8' && \ + export GNUPGHOME="$(mktemp -d)" && \ + mkdir -p /usr/local/share/keyrings/ && \ + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "${key}" && \ + gpg --batch --export --armor "${key}" > /usr/local/share/keyrings/postgres.gpg.asc && \ + gpgconf --kill all && \ + rm -rf "${GNUPGHOME}" + +ENV PG_MAJOR=15 +ENV PATH=$PATH:/usr/lib/postgresql/$PG_MAJOR/bin +ENV PG_VERSION=15.16-1.pgdg13+1 +ENV PGDATA=/var/lib/postgresql/data + +RUN install --verbose --directory --owner postgres --group postgres --mode 3777 /var/run/postgresql && \ + install --verbose --directory --owner postgres --group postgres --mode 3755 /var/lib/postgresql && \ + install --verbose --directory --owner postgres --group postgres --mode 1777 "${PGDATA}" + +RUN set -ex && \ + dpkgArch="$(dpkg --print-architecture)" && \ + aptRepo="[ signed-by=/usr/local/share/keyrings/postgres.gpg.asc ] http://apt.postgresql.org/pub/repos/apt trixie-pgdg main ${PG_MAJOR}" && \ + echo "deb ${aptRepo}" > /etc/apt/sources.list.d/pgdg.list && \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + postgresql-common \ + && \ + sed -ri 's/#(create_main_cluster) .*$/\1 = false/' /etc/postgresql-common/createcluster.conf && \ + apt-get install -y --no-install-recommends \ + "postgresql-${PG_MAJOR}=${PG_VERSION}" \ + "postgresql-${PG_MAJOR}-pgpool2" \ + && \ + rm -rf /var/lib/apt/lists/* && \ + postgres --version + +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 + +VOLUME /var/lib/postgresql/data + +COPY --chown=postgres:postgres postgres /var/lib/postgresql/ COPY --chmod=755 entrypoint.sh /usr/local/bin/ ENTRYPOINT ["entrypoint.sh"] diff --git a/entrypoint.sh b/entrypoint.sh index 0196ac0..4b2877f 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -28,41 +28,17 @@ docker_setup_env() { file_env 'POSTGRES_PGPOOL_PASSWORD' } -docker_init_database() { - local uid; uid="$(id -u)" - if ! getent passwd "$uid" &> /dev/null; then - local wrapper - for wrapper in {/usr,}/lib{/*,}/libnss_wrapper.so; do - if [ -s "$wrapper" ]; then - NSS_WRAPPER_PASSWD="$(mktemp)" - NSS_WRAPPER_GROUP="$(mktemp)" - export LD_PRELOAD="$wrapper" NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP - local gid; gid="$(id -g)" - printf 'postgres:x:%s:%s:PostgreSQL:%s:/bin/false\n' "$uid" "$gid" "$PGDATA" > "$NSS_WRAPPER_PASSWD" - printf 'postgres:x:%s:\n' "$gid" > "$NSS_WRAPPER_GROUP" - break - fi - done - fi - eval 'initdb --username=postgres --pwfile=<(printf "%s\n" "$POSTGRES_PASSWORD") '"$POSTGRES_INITDB_ARGS"' "$@"' - - if [[ "${LD_PRELOAD:-}" == */libnss_wrapper.so ]]; then - rm -f "$NSS_WRAPPER_PASSWD" "$NSS_WRAPPER_GROUP" - unset LD_PRELOAD NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP - fi -} - docker_temp_server_start() { NOTIFY_SOCKET= \ - PGUSER="${PGUSER:-postgres}" \ - pg_ctl -D "$PGDATA" \ + PGUSER="postgres" \ + pg_ctl -D "${PGDATA}" \ -o "-c listen_addresses='' -p 5432" \ -w start } docker_temp_server_stop() { - PGUSER="${PGUSER:-postgres}" \ - pg_ctl -D "$PGDATA" -m fast -w stop + PGUSER="postgres" \ + pg_ctl -D "${PGDATA}" -m fast -w stop } pg_setup_conf() { @@ -100,7 +76,6 @@ pg_setup_hba_conf() { } >> "$PGDATA/pg_hba.conf" } - if [ "$(id -u)" = '0' ]; then exec gosu postgres "$BASH_SOURCE" fi @@ -109,10 +84,9 @@ docker_setup_env if [[ ! -s "$PGDATA/PG_VERSION" ]]; then if [[ -z $POSTGRES_UPSTREAM ]] || [[ -z $POSTGRES_REPLICATOR_USERNAME ]]; then - docker_init_database + initdb --username=postgres --pwfile=<(printf "%s\n" "${POSTGRES_PASSWORD}") pg_setup_conf pg_setup_hba_conf - if [[ -n $POSTGRES_REPLICATOR_USERNAME ]] || [[ -n $POSTGRES_PGPOOL_USERNAME ]]; then export PGPASSWORD="$POSTGRES_PASSWORD" docker_temp_server_start @@ -126,7 +100,6 @@ if [[ ! -s "$PGDATA/PG_VERSION" ]]; then docker_temp_server_stop unset PGPASSWORD fi - else until pg_basebackup -h "${POSTGRES_UPSTREAM}" -U "${POSTGRES_REPLICATOR_USERNAME}" -D "${PGDATA}" -Fp -Xs -R &> /dev/null do @@ -134,9 +107,7 @@ if [[ ! -s "$PGDATA/PG_VERSION" ]]; then sleep 300 done fi - fi sudo service ssh start - postgres