Open artursmet opened 5 months ago
I made it worked this way
That way you have one a container that only has your app with its dependencies - no build tools. Hope this helps
I made it worked this way
1. Install pip/peotry into a distroless container (build container). Make sure to run in exec/vector mode as there is no shell. 2. Build your project 3. Copy the python sys dist-package (/usr/local/lib/python3.11/dist-packages) into a new distroless container (deploy)
That way you have one a container that only has your app with its dependencies - no build tools. Hope this helps
@ding-ma Could you provide simple example Dockerfile for this implementation?
ARG PYTHON_VERSION=3.11
FROM python:${PYTHON_VERSION}-slim AS requirements-stage
ARG POETRY_VERSION=1.7.1
WORKDIR /tmp
RUN pip install --no-cache-dir "poetry==${POETRY_VERSION}"
COPY ./pyproject.toml ./poetry.lock* /tmp/
RUN poetry export -f requirements.txt --output requirements.txt --without-hashes \
&& pip install --no-cache-dir --upgrade -r requirements.txt
&& chmod 0755 /usr/local/bin/uvicorn
FROM gcr.io/distroless/python3-debian12:nonroot
COPY --from=requirements-stage /usr/local/lib/python${PYTHON_VERSION}/site-packages /usr/local/lib/python${PYTHON_VERSION}/site-packages
COPY --from=requirements-stage /usr/local/bin/uvicorn /app/uvicorn
COPY . /app
WORKDIR /app
CMD ["/app/uvicorn", "app:app", "--host", "0.0.0.0", "--port", "9090"]
ENV PYTHONPATH=/usr/local/lib/python${PYTHON_VERSION}/site-packages
...
ARG PYTHON_VERSION=3.11
FROM golang as builder
- download pip
FROM gcr.io/distroless/python3-debian12:latest as py-build
- user root:root (need root to build)
- copy over pip
- RUN ["python", "/tmp/get-pip.py"]
- RUN ["pip", "install", "--no-cache-dir","poetry"]
- RUN ["poetry", "config", "virtualenvs.create", "false"]
- RUN ["poetry", "install", "--no-cache"] --- poetry install rest of your deps
- NOTE: you can't chain them since there is no shell. You have to run them in the vector form show above
FROM gcr.io/distroless/python3-debian12:nonroot
# poetry installs under dist-packages
COPY --from=py-build /usr/local/lib/python${PYTHON_VERSION}/dist-packages /usr/local/lib/python${PYTHON_VERSION}/dist-packages
COPY --from=py-build /usr/local/bin/uvicorn /app/uvicorn
COPY . /app
WORKDIR /app
CMD ["/app/uvicorn", "app:app", "--host", "0.0.0.0", "--port", "9090"]
ENV PYTHONPATH=/usr/local/lib/python${PYTHON_VERSION}/site-packages
Hope that helps :) let me know if you have any other questions
Hello,
I’ve been using official Docker images for python (eg.
python:3.11-slim-bookworm
) in my projects and I wanted to use multi stage build approach to package the final image into distroless one.I’ve found an instruction of how to do it in this repo - https://github.com/GoogleContainerTools/distroless/tree/main/examples/python3-requirements but I wonder if it would be possible to use an official python docker image instead of installing an apt-based python distro from debian repos.
My attempt so far was like this:
However, the virtualenv produced by official python image does not work, because python in that image is compiled, not sourced from official Debian repositories (it has an additional benefit of being able to deliver most recent python version, without waiting for Debian maintainers).
So the python binary is located in
/usr/local/bin/python3.11
in this case. However, on the distoless image, the python binary is located in/usr/bin/python3.11
. As an effect, the container does not boot because the binary path inside the virtualenv is incorrect. This is because the virtualenv configuration:I’ve tried to work around it and add a symlink into the final image, it worked fine in the debug image in interactive shell:
But after adding it into the Dockerfile:
It produces the following build error:
Is there a way to use the official python base image and later on carry over the virtualenv from this image into a distroless base? In my opinion it will bring a lot of benefits and allow to use most recent python versions in distroless (even in my case - official python image has 3.11.8 while the debian-repo-based distroless has 3.11.2 - both use Debian 12 bookworm)