-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using official Python base images and packaging into distroless later on #1543
Comments
I made it worked this way
That way you have one a container that only has your app with its dependencies - no build tools. |
@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 |
For anyone looking for a solution without poetry, I adapted @cstruck's implementation and got it working with: ARG PYTHON_VERSION=3.11
FROM python:${PYTHON_VERSION}-slim AS builder
WORKDIR /tmp
RUN apt-get update && pip install --upgrade pip
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
FROM gcr.io/distroless/python3-debian12:nonroot
ARG PYTHON_VERSION=3.11
COPY --from=builder /usr/local/lib/python${PYTHON_VERSION}/site-packages /usr/local/lib/python${PYTHON_VERSION}/site-packages
COPY . /app
WORKDIR /app
ENV PYTHONPATH=/usr/local/lib/python${PYTHON_VERSION}/site-packages
CMD ["main.py"]
|
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:
RUN mkdir -p /usr/local/bin && ln -s /usr/bin/python3 /usr/local/bin/python3 && ln -s /usr/bin/python3 /usr/local/bin/python3.11
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)
The text was updated successfully, but these errors were encountered: