ARG UPSTREAM_IMAGE_VERSION ARG BASE_IMAGE FROM docker.io/library/postgres:${UPSTREAM_IMAGE_VERSION}-trixie AS postgresql-upstream FROM ${BASE_IMAGE} AS base ## --- FROM base AS postgresql SHELL [ "/bin/sh", "-ec" ] COPY /scripts/* /usr/local/sbin/ ENV PG_UID=11111 PG_GID=11111 ENV PGHOME=/var/lib/postgresql ENV PGDATA=${PGHOME}/data RUN echo "postgres:x:${PG_UID}:${PG_GID}:postgres:${PGHOME}:/bin/bash" >> /etc/passwd ; \ echo "postgres:x:${PG_GID}:" >> /etc/group ; \ echo 'postgres:!:::::::' >> /etc/shadow ; \ install -d -o postgres -g postgres -m 0755 "${PGHOME}" RUN install -d -o postgres -g postgres -m 3755 /run/postgresql VOLUME [ "/run/postgresql" ] COPY /apt/sources.pgdg /etc/apt/sources.list.d/pgdg.sources COPY /apt/sources.pgdg-ver.in /tmp/pgdg-ver.sources COPY /apt/preferences.pgdg /etc/apt/preferences.d/pgdg COPY /apt/preferences.pgdg-ver.in /tmp/pgdg-ver.prefs RUN sed "s/%{PG_MAJOR}/${PG_MAJOR}/g" < /tmp/pgdg-ver.sources > "/etc/apt/sources.list.d/pgdg-${PG_MAJOR}.sources" ; \ sed "s/%{PG_MAJOR}/${PG_MAJOR}/g" < /tmp/pgdg-ver.prefs > "/etc/apt/preferences.d/pgdg-${PG_MAJOR}" ; \ rm -f /tmp/pgdg-ver.sources /tmp/pgdg-ver.prefs COPY --from=postgresql-upstream /etc/postgresql-common/createcluster.conf /etc/postgresql-common/ RUN apt-install.sh postgresql-common ; \ apt-install.sh \ "postgresql-${PG_MAJOR}" \ ; \ apt-clean.sh ; \ f="/usr/share/postgresql/${PG_MAJOR}/postgresql.conf.sample" ; \ dpkg-divert --add --rename --divert "$f.dpkg" "$f" ; \ ln -sv ../postgresql.conf.sample "/usr/share/postgresql/${PG_MAJOR}/" COPY --from=postgresql-upstream /usr/share/postgresql/postgresql.conf.sample /usr/share/postgresql/ ENV PATH=${PATH}:/usr/lib/postgresql/${PG_MAJOR}/bin COPY --from=postgresql-upstream /docker-entrypoint-initdb.d/ /docker-entrypoint-initdb.d/ COPY --from=postgresql-upstream /usr/local/bin/*.sh /usr/local/bin/ ## compatibility ;) RUN ln -sv /usr/local/sbin/dumb-run-as.sh /usr/local/bin/gosu ## --- FROM postgresql AS pybuild SHELL [ "/bin/sh", "-ec" ] COPY /scripts/* /usr/local/sbin/ COPY /requirements.txt /tmp/ ENV DEV_PACKAGES='libffi-dev libpq-dev libyaml-dev' # psutil ENV CIBUILDWHEEL=1 # pyyaml ENV PYYAML_FORCE_CYTHON=1 RUN w=$(mktemp -d) ; : "${w:?}" ; \ { apt-mark showauto ; apt-mark showmanual ; } | sort -uV > "$w/t0" ; \ printf '%s\n' ${DEV_PACKAGES} | sort -uV > "$w/t1" ; \ apt-install.sh ${DEV_PACKAGES} ; \ { apt-mark showauto ; apt-mark showmanual ; } | sort -uV > "$w/t2" ; \ set +e ; \ grep -Fxv -f "$w/t0" "$w/t2" > "$w/t3" ; \ grep -Fxv -f "$w/t1" "$w/t3" > "$w/t4" ; \ grep -Ev -e '-(dev|doc)$' "$w/t4" > "${PYTHON_SITE_PACKAGES}/apt-deps.txt" ; \ set -e ; \ rm -rf "$w/" ; unset w ; \ apt-install.sh build-essential ; \ pip-env.sh pip install 'cython~=3.1.3' ; \ pip-env.sh pip install \ --no-binary 'cffi,psutil,pyyaml' \ -r /tmp/requirements.txt \ ; \ pip-env.sh pip uninstall -y 'cython' ; \ python-rm-cache.sh /usr/local ; \ rm -rf \ /usr/local/bin/patroni_aws \ /usr/local/bin/patroni_raft_controller \ "${PYTHON_SITE_PACKAGES}/etcd/tests" \ "${PYTHON_SITE_PACKAGES}/netaddr/tests" \ "${PYTHON_SITE_PACKAGES}/psutil/tests" \ ; \ truncate -s 0 \ "${PYTHON_SITE_PACKAGES}/netaddr/eui/iab.idx" \ "${PYTHON_SITE_PACKAGES}/netaddr/eui/iab.txt" \ "${PYTHON_SITE_PACKAGES}/netaddr/eui/oui.txt" \ "${PYTHON_SITE_PACKAGES}/netaddr/eui/oui.idx" \ ; \ find "${PYTHON_SITE_PACKAGES}/" -type f -name '*.so*' -exec ls -l {} + ; \ echo ; \ find "${PYTHON_SITE_PACKAGES}/" -type f -name '*.so*' -printf '%p\0' \ | sed -zE '/rust/d' \ | xargs -0r strip --strip-debug --strip-unneeded ; \ echo ; \ find "${PYTHON_SITE_PACKAGES}/" -type f -name '*.so*' -exec ls -l {} + ; \ apt-remove.sh build-essential ; \ apt-clean.sh ## avoid changing already present packages RUN rm -rfv \ /usr/local/bin/pip \ /usr/local/bin/pip3* \ ; \ find "${PYTHON_SITE_PACKAGES}/" -mindepth 1 -maxdepth 1 -printf '%P\0' \ | sed -zEn \ -e '/^pip(|-.+\.dist-info)$/p' \ | env -C "${PYTHON_SITE_PACKAGES}" xargs -0r rm -rf ## --- FROM pybuild AS pycache SHELL [ "/bin/sh", "-ec" ] COPY /scripts/* /usr/local/sbin/ ENV PYTHONDONTWRITEBYTECODE='' ## Python cache preseed RUN libpython="${PYTHON_SITE_PACKAGES%/*}" ; \ find "${libpython}/" -mindepth 1 -maxdepth 1 -printf '%P\0' \ | sed -zEn \ -e '/^(asyncio|collections|concurrent|ctypes|email|encodings|html|http|importlib|json|logging|multiprocessing|re|urllib|zipfile|zoneinfo)$/p' \ | sort -zV \ | env -C "${libpython}" xargs -0r \ python3 -m compileall -q -j 2 ; \ find "${PYTHON_SITE_PACKAGES}/" -mindepth 1 -maxdepth 1 -printf '%P\0' \ | sed -zE \ -e '/\.(dist-info|pth|so|txt)$/d' \ -e '/^pip$/d' \ | sort -zV \ | env -C "${PYTHON_SITE_PACKAGES}" xargs -0r \ python3 -m compileall -q -j 2 ## Python cache warmup RUN export PYTHONPROFILEIMPORTTIME=1 ; \ patroni --help ; \ patronictl --help ; \ patroni_barman --help ; \ patroni_wale_restore --help ; \ cdiff --help ; \ netaddr --help ; \ ydiff --help ## Python cache adjustments RUN d="@$(date '+%s')" ; \ find /usr/local/lib/ -name '*.pyc' -exec touch -m -d "$d" {} + ; \ find /usr/local/lib/ -name __pycache__ -exec touch -m -d "$d" {} + WORKDIR /pycache RUN find /usr/local/ -type f -name '*.py[co]' -printf '%P\0' \ | sort -zV \ | tar -C /usr/local --null -T - -cf - \ | tar -xf - ## --- FROM postgresql AS postgresql-patroni COPY --from=pybuild /usr/local/bin/ /usr/local/bin/ COPY --from=pybuild /${PYTHON_SITE_PACKAGES}/ /${PYTHON_SITE_PACKAGES}/ COPY --from=pycache /pycache/ /usr/local/ ## install missing dependencies for Python site-packages RUN f="${PYTHON_SITE_PACKAGES}/apt-deps.txt" ; \ [ -s "$f" ] || exit 0 ; \ xargs -a "$f" apt-install.sh ; \ apt-clean.sh ## --- FROM postgresql-patroni AS postgresql-extras SHELL [ "/bin/sh", "-ec" ] RUN apt-install.sh \ pgbouncer \ "postgresql-${PG_MAJOR}-cron" \ "postgresql-${PG_MAJOR}-hll" \ "postgresql-${PG_MAJOR}-hypopg" \ "postgresql-${PG_MAJOR}-icu-ext" \ "postgresql-${PG_MAJOR}-pg-catcheck" \ "postgresql-${PG_MAJOR}-pg-checksums" \ "postgresql-${PG_MAJOR}-pg-failover-slots" \ "postgresql-${PG_MAJOR}-pg-hint-plan" \ "postgresql-${PG_MAJOR}-pg-qualstats" \ "postgresql-${PG_MAJOR}-pg-stat-kcache" \ "postgresql-${PG_MAJOR}-pgextwlist" \ "postgresql-${PG_MAJOR}-pgfaceting" \ "postgresql-${PG_MAJOR}-pgfincore" \ "postgresql-${PG_MAJOR}-pglogical" \ "postgresql-${PG_MAJOR}-pglogical-ticker" \ "postgresql-${PG_MAJOR}-pgpcre" \ "postgresql-${PG_MAJOR}-powa" \ "postgresql-${PG_MAJOR}-repack" \ "postgresql-${PG_MAJOR}-roaringbitmap" \ "postgresql-${PG_MAJOR}-rum" \ "postgresql-${PG_MAJOR}-semver" \ "postgresql-${PG_MAJOR}-show-plans" \ "postgresql-${PG_MAJOR}-similarity" \ "postgresql-${PG_MAJOR}-squeeze" \ "postgresql-${PG_MAJOR}-tablelog" \ "postgresql-${PG_MAJOR}-tdigest" \ "postgresql-${PG_MAJOR}-timescaledb" \ "postgresql-${PG_MAJOR}-toastinfo" \ "postgresql-${PG_MAJOR}-unit" \ "postgresql-${PG_MAJOR}-wal2json" \ ; \ apt-clean.sh ## --- FROM postgresql-extras AS citus SHELL [ "/bin/sh", "-ec" ] COPY /apt/sources.citus /etc/apt/sources.list.d/citus.sources RUN apt-env.sh apt-get update ; \ citus_pkg=$(apt-cache search "^postgresql-${PG_MAJOR}-citus-[0-9.]+\$" | awk '{print $1}' | sort -rV | head -n1) ; \ : "${citus_pkg:?}" ; \ apt-install.sh \ "${citus_pkg}" \ "postgresql-${PG_MAJOR}-topn" \ ; apt-clean.sh VOLUME [ "${PGHOME}" ] ## --- ## TODO: disabled until citus packages are ready for Debian 13 # FROM citus FROM postgresql-extras SHELL [ "/bin/sh", "-ec" ] COPY /Dockerfile /usr/local/share/ COPY /ep.sh /usr/local/sbin/ COPY /postgres-shim.sh /usr/local/sbin/ ## quirk RUN ln -sv postgres-shim.sh /usr/local/sbin/postgres WORKDIR "${PGHOME}" ## "Fast Shutdown mode" in PostgreSQL ## NB: override to SIGTERM in order to switch to "Smart Shutdown mode" STOPSIGNAL SIGINT ENV MALLOC_ARENA_MAX=4 \ GOMAXPROCS=4 ENTRYPOINT [ "ep.sh" ] CMD [ "postgres" ]