adrian@home:~$

Distroless Python Images With Docker

Lately I needed to reduce the attack surface of a Python 3.10 Docker image to a bare minimum. I searched the web for best practices and came across distroless Docker images. As time of my investigations the Python version on the provided distroless image was 3.9.

After gathering enough information in various blog posts I have created a Dockerfile to serve my Python application on a distroless Docker image.

FROM python:3.10-slim as base

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONFAULTHANDLER 1

FROM base AS python-deps

RUN pip install pipenv

COPY Pipfile .
COPY Pipfile.lock .

# create virtual environment
RUN PIPENV_VENV_IN_PROJECT=1 pipenv install --deploy

#https://github.com/GoogleContainerTools/distroless/issues/973#issuecomment-1065169760
FROM gcr.io/distroless/base-debian11:nonroot

WORKDIR /app

ARG ARCH=x86_64-linux-gnu

# copy necessary system libs
COPY --from=python-deps /lib/${ARCH}/libz.so.1 /lib/${ARCH}/libz.so.1

# copy python 3.10 and relevant libs
COPY --from=python-deps /usr/local/bin/python3.10 /usr/local/bin/python3.10
COPY --from=python-deps /usr/local/lib/libpython3.10.so.1.0 /usr/local/lib/libpython3.10.so.1.0
COPY --from=python-deps /usr/local/lib/python3.10 /usr/local/lib/python3.10

# copy packages
COPY --from=python-deps /.venv/lib/python3.10/site-packages /app/site-packages

# set envs
ENV PYTHONPATH /app/site-packages
ENV LD_LIBRARY_PATH /usr/local/lib

# copy program
COPY main.py .

EXPOSE 8080
ENTRYPOINT ["python3.10", "main.py"]

You can also find this Dockerfile here. You might notice that the distroless Python image is makred as ‘experimental’. You can find a discussion in the issues section of the GitHub repostiory.

For me that is not an issue as I was able to reduce the attack surface rigorously.