Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 38 additions & 145 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,82 +30,38 @@ LABEL name="PostgreSQL Container Images" \
COPY build-deps.txt /

# Install runtime and build dependencies
RUN set -ex; \
apt-get update; \
RUN apt-get update && \
apt-get install -y --no-install-recommends \
gnupg \
dirmngr \
ca-certificates \
locales-all \
ssl-cert \
libnss-wrapper \
libxml2 \
libllvm16 \
libxslt1.1 \
xz-utils \
zstd \
$(cat /build-deps.txt); \
rm -rf /var/lib/apt/lists/*;
$(cat /build-deps.txt) && \
rm -rf /var/lib/apt/lists/* /var/cache/* /var/log/*

# 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=26 --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; \
RUN groupadd -r postgres --gid=999 && \
useradd -r -g postgres --uid=26 --home-dir=/var/lib/postgresql --shell=/bin/bash postgres && \
mkdir -p /var/lib/postgresql && \
chown -R postgres:postgres /var/lib/postgresql

# grab gosu for easy step-down from root
# https://github.com/tianon/gosu/releases
ENV GOSU_VERSION 1.17
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"; \
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

# 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 --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 mkdir /docker-entrypoint-initdb.d

ENV PG_MAJOR $PG_MAJOR
ENV PATH $PATH:/usr/lib/postgresql/$PG_MAJOR/bin
ENV PG_MAJOR=$PG_MAJOR
ENV PATH=/usr/lib/postgresql/$PG_MAJOR/bin:$PATH

# Build PostgreSQL
# Partially refer to https://github.com/docker-library/postgres/blob/master/16/alpine3.19/Dockerfile#L33-L160
RUN set -eux ; \
mkdir -p /usr/src/postgresql ; \
git clone -b "$PG_BRANCH" --single-branch "$PG_REPO" /usr/src/postgresql ; \
cd /usr/src/postgresql ; \
export LLVM_CONFIG="/usr/lib/llvm-16/bin/llvm-config" ; \
export CLANG=clang-16 ; \
# Partially refer to https://github.com/docker-library/postgres/blob/master/16/alpine3.21/Dockerfile#L119-L159
RUN mkdir -p /usr/src/postgresql && \
git clone -b "$PG_BRANCH" --single-branch "$PG_REPO" /usr/src/postgresql && \
cd /usr/src/postgresql && \
export LLVM_CONFIG="/usr/lib/llvm-16/bin/llvm-config" && \
export CLANG=clang-16 && \
./configure \
--build=x86_64-linux-gnu \
--prefix=/usr \
Expand Down Expand Up @@ -151,107 +107,44 @@ RUN set -eux ; \
LDFLAGS="-Wl,-z,relro -Wl,-z,now" \
CPPFLAGS="-Wdate-time -D_FORTIFY_SOURCE=2" \
CXXFLAGS="-g -Og -fstack-protector-strong -Wformat -Werror=format-security" \
; \
make -j "$(nproc)" world-bin ; \
make install-world-bin ; \
cd / ; \
rm -rf /usr/src/postgresql ; \
postgres --version
&& \
make -j "$(nproc)" world-bin && \
make install-world-bin && \
rm -rf /usr/src/postgresql

# TODO: re-enable once https://github.com/pgaudit/pgaudit/issues/257 is fixed
# Build PgAudit
# See to https://github.com/pgaudit/pgaudit/blob/master/README.md#compile-and-install
# RUN set -eux ; \
# mkdir -p /usr/src/pgaudit ; \
# git clone -b main --single-branch https://github.com/pgaudit/pgaudit.git /usr/src/pgaudit ; \
# cd /usr/src/pgaudit ; \
# make install USE_PGXS=1 PG_CONFIG=/usr/lib/postgresql/$PG_MAJOR/bin/pg_config ; \
# cd / ; \
# RUN mkdir -p /usr/src/pgaudit && \
# git clone -b main --single-branch https://github.com/pgaudit/pgaudit.git /usr/src/pgaudit && \
# cd /usr/src/pgaudit && \
# make install USE_PGXS=1 PG_CONFIG=/usr/lib/postgresql/$PG_MAJOR/bin/pg_config && \
# rm -rf /usr/src/pgaudit

# Purge build dependencies
RUN set -xe ; \
apt-get purge -y --autoremove $(cat /build-deps.txt)

# Even though we compile from source, we still need PGDG to gather an updated version of psycopg2
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)"; \
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"
RUN apt-get purge -y --autoremove $(cat /build-deps.txt)

# Install barman-cloud
RUN set -xe; \
aptRepo="[ signed-by=/usr/local/share/keyrings/postgres.gpg.asc ] http://apt.postgresql.org/pub/repos/apt/ bookworm-pgdg main $PG_MAJOR"; \
echo "deb $aptRepo" > /etc/apt/sources.list.d/pgdg.list; \
apt-get update; \
RUN 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" && \
aptRepo="[ signed-by=/usr/local/share/keyrings/postgres.gpg.asc ] http://apt.postgresql.org/pub/repos/apt/ bookworm-pgdg main $PG_MAJOR" && \
echo "deb $aptRepo" > /etc/apt/sources.list.d/pgdg.list && \
apt-get update && \
apt-get install -y --no-install-recommends \
python3-pip \
python3-psycopg2 \
python3-setuptools \
; \
pip3 install --break-system-packages --upgrade pip; \
pip3 install --break-system-packages barman[cloud,azure,snappy,google] boto3==1.35.99; \
rm -rf /var/lib/apt/lists/*;

# 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 3777 /var/run/postgresql

ENV PGDATA /var/lib/postgresql/data
# this 1777 will be replaced by 0700 at runtime (allows semi-arbitrary "--user" values)
RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 1777 "$PGDATA"
VOLUME /var/lib/postgresql/data
&& \
pip3 install --break-system-packages --upgrade pip && \
pip3 install --break-system-packages barman[cloud,azure,snappy,google] boto3==1.35.99 && \
rm -rf /var/lib/apt/lists/* /var/cache/* /var/log/*

# DoD 2.3 - remove setuid/setgid from any binary that not strictly requires it, and before doing that list them on the stdout
RUN find / -not -path "/proc/*" -perm /6000 -type f -exec ls -ld {} \; -exec chmod a-s {} \; || true

USER 26

COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]

# We set the default STOPSIGNAL to SIGINT, which corresponds to what PostgreSQL
# calls "Fast Shutdown mode" wherein new connections are disallowed and any
# in-progress transactions are aborted, allowing PostgreSQL to stop cleanly and
# flush tables to disk, which is the best compromise available to avoid data
# corruption.
#
# Users who know their applications do not keep open long-lived idle connections
# may way to use a value of SIGTERM instead, which corresponds to "Smart
# Shutdown mode" in which any existing sessions are allowed to finish and the
# server stops when all sessions are terminated.
#
# See https://www.postgresql.org/docs/12/server-shutdown.html for more details
# about available PostgreSQL server shutdown signals.
#
# See also https://www.postgresql.org/docs/12/server-start.html for further
# justification of this as the default value, namely that the example (and
# shipped) systemd service files use the "Fast Shutdown mode" for service
# termination.
#
STOPSIGNAL SIGINT
#
# An additional setting that is recommended for all users regardless of this
# value is the runtime "--stop-timeout" (or your orchestrator/runtime's
# equivalent) for controlling how long to wait between sending the defined
# STOPSIGNAL and sending SIGKILL (which is likely to cause data corruption).
#
# The default in most runtimes (such as Docker) is 10 seconds, and the
# documentation at https://www.postgresql.org/docs/12/server-start.html notes
# that even 90 seconds may not be long enough in many instances.

EXPOSE 5432
CMD ["postgres"]
Loading