While this guide's focus is on python, the general advice here applies to anyone trying to build docker images on top of distroless base images.
No dependencies
If you have a simple python script with no dependencies, you can follow this guide, whose Dockerfile is reproduced below.
FROM python:3-slim AS build-env
COPY . /app
WORKDIR /app
FROM gcr.io/distroless/python3
COPY --from=build-env /app /app
WORKDIR /app
CMD ["hello.py", "/etc"]
Pure-python dependencies
If you have a requirements.txt
but no additional native dependencies you can follow this guide
# Build a virtualenv using the appropriate Debian release
# * Install python3-venv for the built-in Python3 venv module (not installed by default)
# * Install gcc libpython3-dev to compile C Python modules
# * In the virtualenv: Update pip setuputils and wheel to support building new packages
FROM debian:11-slim AS build
RUN apt-get update && \
apt-get install --no-install-suggests --no-install-recommends --yes python3-venv gcc libpython3-dev && \
python3 -m venv /venv && \
/venv/bin/pip install --upgrade pip setuptools wheel
# Build the virtualenv as a separate step: Only re-execute this step when requirements.txt changes
FROM build AS build-venv
COPY requirements.txt /requirements.txt
RUN /venv/bin/pip install --disable-pip-version-check -r /requirements.txt
# Copy the virtualenv into a distroless image
FROM gcr.io/distroless/python3-debian11
COPY --from=build-venv /venv /venv
COPY . /app
WORKDIR /app
ENTRYPOINT ["/venv/bin/python3", "psutil_example.py"]
Native dependencies
Finally if we have native dependencies, we can download them from a debian-based build stage, extract their contents to a temp directory (i.e. /dpkg
), then copy those into the root distroless image during the final stage.
One way to generate a list of dependencies needed is to call apt-cache depends <your-lib-here>
.
In our case we want to install the psycopg2 library, that has a native dependency on libpq. To find the package (and its dependencies) in debian, we'll first need the name of the package.
$ apt-get update
<snip>
Reading package lists... Done
$ apt-cache search libpq
<snip>
libpq5 - PostgreSQL C client library
Now that we have the name of the package (libpq5
) we can see what dependencies it has.
$ apt-cache depends --recurse libpq5
libpq5
Depends: libc6
Depends: libgssapi-krb5-2
Depends: libldap-2.4-2
Depends: libssl1.1
We can see the pre-installed distroless dependencies listed in the python build file, the cc build file and the base build file. Looks like we'll need to add these dependencies.
NOTE: Dependencies might have dependencies, you can use the script here (written by @tuananh) to get all dependencies.
Final Dockerfile
# Build a virtualenv using the appropriate Debian release
# * Install python3-venv for the built-in Python3 venv module (not installed by default)
# * Install gcc libpython3-dev to compile C Python modules
# * In the virtualenv: Update pip setuputils and wheel to support building new packages
FROM debian:11-slim AS build
RUN apt-get update && \
apt-get install --no-install-suggests --no-install-recommends --yes python3-venv gcc libpython3-dev && \
python3 -m venv /venv && \
/venv/bin/pip install --upgrade pip setuptools wheel
RUN cd /tmp && \
apt-get update && \
apt-get install -y --no-install-recommends \
# install only deps
curl \
ca-certificates \
openssl \
&& \
apt-get download \
# ca-certificates \
\
# additional python dependencies
libpq5 \
&& \
mkdir -p /dpkg/var/lib/dpkg/status.d/ && \
for deb in *.deb; do \
package_name=$(dpkg-deb -I ${deb} | awk '/^ Package: .*$/ {print $2}'); \
echo "Process: ${package_name}"; \
dpkg --ctrl-tarfile $deb | tar -Oxf - ./control > /dpkg/var/lib/dpkg/status.d/${package_name}; \
dpkg --extract $deb /dpkg || exit 10; \
done
# Build the virtualenv as a separate step: Only re-execute this step when requirements.txt changes
FROM build AS build-venv
COPY requirements.txt /requirements.txt
RUN /venv/bin/pip install --disable-pip-version-check -r /requirements.txt
# Copy the virtualenv into a distroless image
FROM gcr.io/distroless/python3-debian11
COPY --from=build-venv /venv /venv
COPY --from=build/dpkg /
COPY . /app
WORKDIR /app
ENTRYPOINT ["/venv/bin/python3", "psutil_example.py"]
Top comments (0)