mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2026-10-27 23:20:05 -05:00
python:3-alpine now resolves to Python 3.15, whose psycopg[c] wheel links against the system libpq. postgresql-dev is removed with build-deps, so libpq.so.5 was no longer present at runtime and importing psycopg (as the Sphinx docs build does via config.py) failed with 'no pq wrapper available', breaking the container build. Install the runtime libpq package separately so it survives the build-deps cleanup.
233 lines
8.4 KiB
Docker
233 lines
8.4 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
|
|
#
|
|
# libpq is a runtime dependency of psycopg's C extension: psycopg[c] is built
|
|
# from source against postgresql-dev, but that is removed with build-deps
|
|
# below, so libpq.so.5 must be installed separately to survive. Without it,
|
|
# importing psycopg (which the Sphinx docs build does, via config.py) fails
|
|
# with "no pq wrapper available".
|
|
RUN apk add --no-cache \
|
|
make \
|
|
libpq && \
|
|
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
|
|
|
|
# Remove the files pgAdmin never uses. The script reads the language list from
|
|
# web/config.py, so it is copied in separately to avoid a change to it
|
|
# reinstalling the requirements above.
|
|
COPY pkg/prune_site_packages.py /prune/pkg/
|
|
COPY web/config.py /prune/web/
|
|
RUN /venv/bin/python3 /prune/pkg/prune_site_packages.py /venv
|
|
|
|
#########################################################################
|
|
# 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"]
|