You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I’m trying to determine the recommended approach to installing PostgreSQL extensions (specifically PostGIS) when using hardened container images. I see a request for adding PostgreSQL with the extension pre-installed to the catalog; however, I am trying to determine the best approach for instances where you need more than one or an extension not yet pre-built
Background
I’m working with a hardened Postgres image where:
• The PostgreSQL runtime lives under: /opt/postgresql/17/
• The image intentionally does not include a package manager in the final stage (unless using -dev).
• I’m trying to avoid compiling extensions from source if possible but am ok with installing via apt or another tool.
When I install PostGIS using apt in a builder stage:
apt-get install postgresql-17-postgis-3
it installs extension files into the default Debian paths, such as:
However, the hardened image expects everything under /opt/postgresql/..., which causes issues like:
• Postgres not finding PostGIS.control
• Extension load failures:
extension "postgis" is not available
Could not open extension control file ...
Current Workaround
Right now I’m experimenting with:
using a debian-dev harden image and adding Postgres and PostGIS via apt
…but this feels like it's going the wrong direction (losing out on the hardening), and images are being bigger than the DHI version.
Example Dockerfile
FROM dhi.io/debian-base:trixie-dev AS production
ENV DEBIAN_FRONTEND=noninteractive
ENV POSTGRES_DB=testDB
ENV POSTGRES_USER=testUser
ENV POSTGRES_PASSWORD=testPassword
ENV PG_MAJOR=17
ENV PGDATA=/var/lib/postgresql/data/
ENV PATH="/usr/lib/postgresql/${PG_MAJOR}/bin:$PATH"
ENV PAGER=cat
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
# THIS IS all in one run command to minimize the number of layers and reduce image size
# scans of the build history and image layers will also not show the individual package installation commands
RUN apt-get update && apt-get install --no-install-recommends -y \
ca-certificates \
tzdata \
util-linux \
hostname \
ssl-cert \
&& apt-get install -y postgresql-common \
&& /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y trixie \
&& apt-get update && apt-get install -y \
postgresql-17 \
postgis \
postgresql-17-postgis-3 \
libc-bin \
&& rm -f /etc/ssl/private/ssl-cert-snakeoil.key \
&& rm -f /etc/ssl/certs/ssl-cert-snakeoil.pem \
&& apt-get clean \
&& apt-get autoremove -y \
&& rm -rf /var/lib/apt/lists/* \
&& set -eux; \
# Remove package managers entirely (final image hardening)
\
# Remove unused PostgreSQL versions (keep only 17)
apt-get purge -y \
postgresql-18* \
postgresql-client-18* \
# # postgresql-common-dev \
|| true; \
\
# Remove system services not needed in containers
apt-get purge -y \
cron \
cron-daemon-common \
dbus \
dbus-bin \
dbus-daemon \
dbus-session-bus-common \
dbus-system-bus-common \
systemd \
systemd-timesyncd \
systemd-cryptsetup \
sysvinit-utils \
logrotate \
sysstat \
linux-sysctl-defaults \
|| true; \
\
# Remove mail stack
apt-get purge -y \
exim4-base \
exim4-config \
exim4-daemon-light \
bsd-mailx \
|| true; \
\
# Remove build / dev tooling
apt-get purge -y \
gcc-* \
perl \
perl-base \
perl-modules-* \
make \
diffutils \
gnu-which \
|| true; \
\
\
# Remove package managers entirely (final image hardening)
rm -rf \
/usr/bin/apt* \
/usr/bin/dpkg* \
/var/lib/apt \
/var/lib/dpkg \
/etc/apt \
/etc/dpkg; \
\
# Final cleanup
rm -rf \
/tmp/* \
/var/tmp/* \
/var/cache/* \
/usr/share/doc/* \
/usr/share/man/* \
/usr/share/info/*; \
\
ldconfig
# Create init directory
# Copy init SQL (app schema, data, etc)
RUN mkdir -p /docker-entrypoint-initdb.d/
COPY schema.sql /docker-entrypoint-initdb.d/01-schema.sql
COPY schmea-fix-permissions.sql /docker-entrypoint-initdb.d/999999999-fix-permissions.sql
# Copy entrypoint
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
EXPOSE 5432
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["postgres"]
Questions
Is there a supported or recommended way to install extensions into a non-standard Postgres prefix (like /opt/postgresql) without rebuilding from source?
Is there an easier workflow for hardened images that avoids manually copying extension artifacts?
Are extensions expected to always be compiled against the same prefix as the Postgres binary?
How are others handling extension installs in distroless/hardened containers?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
Hi everyone,
I’m trying to determine the recommended approach to installing PostgreSQL extensions (specifically PostGIS) when using hardened container images. I see a request for adding PostgreSQL with the extension pre-installed to the catalog; however, I am trying to determine the best approach for instances where you need more than one or an extension not yet pre-built
Background
I’m working with a hardened Postgres image where:
• The PostgreSQL runtime lives under:
/opt/postgresql/17/• The image intentionally does not include a package manager in the final stage (unless using -dev).
• I’m trying to avoid compiling extensions from source if possible but am ok with installing via apt or another tool.
When I install PostGIS using apt in a builder stage:
it installs extension files into the default Debian paths, such as:
However, the hardened image expects everything under /opt/postgresql/..., which causes issues like:
• Postgres not finding PostGIS.control
• Extension load failures:
extension "postgis" is not available Could not open extension control file ...Current Workaround
Right now I’m experimenting with:
…but this feels like it's going the wrong direction (losing out on the hardening), and images are being bigger than the DHI version.
Example Dockerfile
Questions
Beta Was this translation helpful? Give feedback.
All reactions