Python Poetry for Building Docker Images

jun 13, 2022

We have been using Poetry for version pinning of Lambda Functions. This time we are looking at how to use Poetry in building Docker Images while minimizing the size of the resulting image. As an example Python application, we take the Sanic OpenAPI Example. You can find the full final code for this example setup in our GitHub repository.


Since we are looking at building Docker Images, the only interesting place to look is the Dockerfile (assuming you already have a Poetry-based project).

In an effort to reduce the size of the final image, we are using three build stages in the Dockerfile:

  • The python stage is used just to provide a common basis for the poetry and runtime stages.
  • The poetry stage installs Poetry, and uses it to install the Python application and its dependencies in a virtual environment.
  • The runtime stage builds the final Docker Image by copying and configuring the virtual environment from the poetry stage.

Poetry and its dependencies are only installed in the poetry stage and are not included in the final runtime image. This approach is heavily inspired by this comment by Dylan Praul on GitHub.

FROM python:3-slim as python

FROM python as poetry
ENV POETRY_HOME=/opt/poetry
RUN python -c 'from urllib.request import urlopen; print(urlopen("").read().decode())' | python -
COPY . ./
RUN poetry install --no-interaction --no-ansi -vvv

FROM python as runtime
ENV PATH="/app/.venv/bin:$PATH"
COPY --from=poetry /app /app
CMD somerandomap

Image Size

The goal of the multi-stage build strategy is to reduce the size of the final image. Below we show the size (and increase compared to the base (python:3-slim) image) for the images.

  • python:3-slim 117 MB (base image)
  • python 117 MB (0 MB increase)
  • poetry 194 MB (77 MB increase)
  • poetry (with application) 278 MB (161 MB increase)
  • runtime 179 MB (62 MB increase)

The final runtime image has a size increase of 62 MB from the base image, compared to the increase of 161 MB for the image that contains both the application and poetry we are saving 99MB.

(Curiously, these numbers do not add up. If the application adds 62 MB and poetry adds 77 MB, we would expect the sum of these to add 139 MB while, in fact, it adds 161 MB… What would be taking the additional 22 MB?)

Cloud Consultant with a passion for everything Cloud. Likes to automate all the things. Believes security is everyone's responsibility!
Share this article: Tweet this post / Post on LinkedIn