1
0
mirror of synced 2026-10-23 07:08:55 +03:00
Files
pgadmin4/Dockerfile
dev-hari-prasad 351376af7f Enforce --immutable on every yarn install, in CI and the release builds (#10389)
In the four GitHub Actions workflows the flag is documentation only, since
Yarn's enableImmutableInstalls already defaults to true whenever CI is set in
the environment, but making it explicit means the intent is visible in the
workflow rather than implied by the runner.

The six installs that run outside CI are where this actually changes
behaviour: the Makefile, the Dockerfile, and the pip, Linux, macOS and Windows
packaging builds all run with yarn.lock beside them, and until now any of them
would quietly rewrite the lockfile rather than fail. A release build that
rewrites the lockfile is shipping something other than what we reviewed, so
failing loudly there is the point of the exercise.
2026-09-22 16:50:39 +01:00

219 lines
7.7 KiB
Docker

########################################################################
#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2026, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#
#########################################################################
#########################################################################
# Create a Node container which will be used to build the JS components
# and clean up the web/ source code
#########################################################################
FROM alpine:latest AS app-builder
RUN apk add --no-cache \
autoconf \
automake \
bash \
g++ \
git \
libc6-compat \
libjpeg-turbo-dev \
libpng-dev \
libtool \
make \
nasm \
nodejs \
npm \
yarn \
zlib-dev
# Create the /pgadmin4 directory and copy the source into it
COPY web /pgadmin4/web
WORKDIR /pgadmin4/web
# Build the JS vendor code in the app-builder, and then remove the vendor source.
RUN --mount=type=bind,source=.git,target=/pgadmin4/.git \
--mount=type=tmpfs,target=node_modules \
--mount=type=tmpfs,target=pgadmin/static/js/generated/.cache \
export CPPFLAGS="-DPNG_ARM_NEON_OPT=0" && \
npm install -g corepack && \
corepack enable && \
yarn install --immutable && \
yarn run bundle && \
rm -rf yarn.lock \
package.json \
.[^.]* \
babel.cfg \
webpack.* \
jest.config.js \
babel.*
#########################################################################
# Next, create the base environment for Python
#########################################################################
FROM python:3-alpine AS env-builder
# Install dependencies
RUN apk add --no-cache \
make && \
apk add --no-cache --virtual build-deps \
build-base \
openssl-dev \
libffi-dev \
postgresql-dev \
krb5-dev \
rust \
cargo \
zlib-dev \
libjpeg-turbo-dev \
libpng-dev
COPY requirements.txt /
RUN python3 -m venv --system-site-packages --without-pip /venv && \
/venv/bin/python3 -m pip install --no-cache-dir -r requirements.txt && \
apk del --no-cache build-deps
#########################################################################
# Now, create a documentation build container for the Sphinx docs
#########################################################################
FROM env-builder AS docs-builder
# Install Sphinx
RUN /venv/bin/python3 -m pip install --no-cache-dir sphinx
RUN /venv/bin/python3 -m pip install --no-cache-dir sphinxcontrib-youtube
# Copy the docs from the local tree. Explicitly remove any existing builds that
# may be present
COPY docs /pgadmin4/docs
COPY web /pgadmin4/web
RUN rm -rf /pgadmin4/docs/en_US/_build
# Build the docs
RUN LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 /venv/bin/sphinx-build /pgadmin4/docs/en_US /pgadmin4/docs/en_US/_build/html
# Cleanup unwanted files
RUN rm -rf /pgadmin4/docs/en_US/_build/html/.doctrees
RUN rm -rf /pgadmin4/docs/en_US/_build/html/_sources
RUN rm -rf /pgadmin4/docs/en_US/_build/html/_static/*.png
#########################################################################
# Create additional builders to get all of the PostgreSQL utilities
#########################################################################
FROM postgres:13-alpine AS pg13-builder
FROM postgres:14-alpine AS pg14-builder
FROM postgres:15-alpine AS pg15-builder
FROM postgres:16-alpine AS pg16-builder
FROM postgres:17-alpine AS pg17-builder
FROM postgres:18-alpine AS pg18-builder
FROM alpine:latest AS tool-builder
# Copy the PG binaries
COPY --from=pg13-builder /usr/local/bin/pg_dump /usr/local/pgsql/pgsql-13/
COPY --from=pg13-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-13/
COPY --from=pg13-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-13/
COPY --from=pg13-builder /usr/local/bin/psql /usr/local/pgsql/pgsql-13/
COPY --from=pg14-builder /usr/local/bin/pg_dump /usr/local/pgsql/pgsql-14/
COPY --from=pg14-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-14/
COPY --from=pg14-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-14/
COPY --from=pg14-builder /usr/local/bin/psql /usr/local/pgsql/pgsql-14/
COPY --from=pg15-builder /usr/local/bin/pg_dump /usr/local/pgsql/pgsql-15/
COPY --from=pg15-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-15/
COPY --from=pg15-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-15/
COPY --from=pg15-builder /usr/local/bin/psql /usr/local/pgsql/pgsql-15/
COPY --from=pg16-builder /usr/local/bin/pg_dump /usr/local/pgsql/pgsql-16/
COPY --from=pg16-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-16/
COPY --from=pg16-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-16/
COPY --from=pg16-builder /usr/local/bin/psql /usr/local/pgsql/pgsql-16/
COPY --from=pg17-builder /usr/local/bin/pg_dump /usr/local/pgsql/pgsql-17/
COPY --from=pg17-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-17/
COPY --from=pg17-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-17/
COPY --from=pg17-builder /usr/local/bin/psql /usr/local/pgsql/pgsql-17/
COPY --from=pg18-builder /usr/local/bin/pg_dump /usr/local/pgsql/pgsql-18/
COPY --from=pg18-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-18/
COPY --from=pg18-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-18/
COPY --from=pg18-builder /usr/local/bin/psql /usr/local/pgsql/pgsql-18/
#########################################################################
# Assemble everything into the final container.
#########################################################################
FROM python:3-alpine
# Install runtime dependencies
RUN apk update && apk upgrade && \
apk add \
bash \
postfix \
krb5-libs \
libcurl \
libjpeg-turbo \
shadow \
sudo \
tzdata \
libedit \
libldap \
libcap \
su-exec && \
rm -rf /var/cache/apk/*
# Copy in the Python packages
COPY --from=env-builder /venv /venv
# Copy in the tools
COPY --from=tool-builder /usr/local/pgsql /usr/local/
COPY --from=pg18-builder /usr/local/lib/libpq.so.5.18 /usr/local/lib/libpq-oauth-18.so /usr/lib/liblz4.so.1.10.0 /usr/lib/
RUN ln -s libpq.so.5.18 /usr/lib/libpq.so.5 && \
ln -s libpq.so.5.18 /usr/lib/libpq.so && \
ln -s liblz4.so.1.10.0 /usr/lib/liblz4.so.1
WORKDIR /pgadmin4
ENV PYTHONPATH=/pgadmin4
# Copy in the code and docs
COPY --from=app-builder /pgadmin4/web /pgadmin4
COPY --from=docs-builder /pgadmin4/docs/en_US/_build/html/ /pgadmin4/docs
COPY pkg/docker/run_pgadmin.py pkg/docker/gunicorn_config.py /pgadmin4/
COPY pkg/docker/entrypoint.sh /entrypoint.sh
# License files
COPY LICENSE /pgadmin4/LICENSE
# Configure everything in one RUN step
RUN /venv/bin/python3 -m pip install --no-cache-dir gunicorn==23.0.0 && \
find / -type d -name '__pycache__' -exec rm -rf {} + && \
useradd -r -u 5050 -g root -s /sbin/nologin pgadmin && \
mkdir -p /run/pgadmin /var/lib/pgadmin && \
chown pgadmin:root /run/pgadmin /var/lib/pgadmin && \
chmod g=u /run/pgadmin /var/lib/pgadmin && \
touch /pgadmin4/config_distro.py && \
chown pgadmin:root /pgadmin4/config_distro.py && \
chmod g=u /pgadmin4/config_distro.py && \
chmod g=u /etc/passwd && \
PYBIN="$(ls /usr/local/bin/python3.[0-9][0-9] 2>/dev/null | head -n1)" && \
cp "$PYBIN" /usr/local/bin/python3-cap && \
setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/python3-cap && \
ln -s /usr/local/bin/python3-cap /venv/bin/python3-cap && \
echo "pgadmin ALL = NOPASSWD: /usr/sbin/postfix start" > /etc/sudoers.d/postfix && \
echo "pgadminr ALL = NOPASSWD: /usr/sbin/postfix start" >> /etc/sudoers.d/postfix
USER 5050
# Finish up
VOLUME /var/lib/pgadmin
EXPOSE 80 443
ENTRYPOINT ["/entrypoint.sh"]