Looking for faster Python builds? We recommend using UV instead of Poetry for
significantly faster dependency installation and better caching. UV supports Poetry projects natively and can speed up
your builds by 10-100x while maintaining full compatibility with your pyproject.toml
and poetry.lock
files.
Below is an example Dockerfile
that we recommend at Depot for building Docker images for Python applications that use poetry
as their package manager.
# syntax=docker/dockerfile:1
FROM python:3.13-slim AS build
ENV POETRY_VERSION=2.2.1 \
PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=off \
PIP_DISABLE_PIP_VERSION_CHECK=on \
PIP_DEFAULT_TIMEOUT=100 \
POETRY_HOME="/opt/poetry" \
POETRY_VIRTUALENVS_IN_PROJECT=true \
POETRY_NO_INTERACTION=1 \
PYSETUP_PATH="/opt/pysetup" \
VENV_PATH="/opt/pysetup/.venv"
ENV PATH="$POETRY_HOME/bin:$VENV_PATH/bin:$PATH"
RUN pip install "poetry==$POETRY_VERSION"
WORKDIR $PYSETUP_PATH
COPY poetry.lock pyproject.toml ./
RUN --mount=type=cache,target=/root/.cache/pypoetry \
poetry install --no-root
COPY . .
FROM python:3.13-slim AS runtime
ENV VENV_PATH="/opt/pysetup/.venv" \
PATH="/opt/pysetup/.venv/bin:$PATH"
RUN groupadd -g 1001 appgroup && \
useradd -u 1001 -g appgroup -m -d /home/appuser -s /bin/bash appuser
WORKDIR /app
COPY --from=build --chown=appuser:appgroup /opt/pysetup/.venv /opt/pysetup/.venv
COPY --from=build --chown=appuser:appgroup /opt/pysetup/ ./
USER appuser
ENTRYPOINT ["python", "-m", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]
This Dockerfile uses an optimized approach for Python applications using Poetry, featuring multi-stage builds and security optimizations.
At a high level, here are the things we're optimizing in our Docker build for a Python application with Poetry:
FROM python:3.13-slim AS build
FROM python:3.13-slim AS build
ENV POETRY_VERSION=2.2.1 \
PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=off \
PIP_DISABLE_PIP_VERSION_CHECK=on \
PIP_DEFAULT_TIMEOUT=100 \
POETRY_HOME="/opt/poetry" \
POETRY_VIRTUALENVS_IN_PROJECT=true \
POETRY_NO_INTERACTION=1 \
PYSETUP_PATH="/opt/pysetup" \
VENV_PATH="/opt/pysetup/.venv"
ENV PATH="$POETRY_HOME/bin:$VENV_PATH/bin:$PATH"
We start with Python 3.13 slim for a smaller base image and configure Poetry with specific environment variables:
POETRY_VERSION=2.2.1
pins the Poetry version for reproducible buildsPOETRY_VIRTUALENVS_IN_PROJECT=true
creates virtual environments inside the projectPOETRY_NO_INTERACTION=1
disables interactive promptsPYTHONUNBUFFERED=1
ensures logs are output in real-timeRUN --mount=type=cache,target=/root/.cache \
pip install "poetry==$POETRY_VERSION"
We install Poetry using pip with cache mounts for efficiency.
WORKDIR $PYSETUP_PATH
COPY poetry.lock pyproject.toml ./
RUN --mount=type=cache,target=/root/.cache/pypoetry \
poetry install --no-root
We copy the Poetry configuration files and install dependencies without installing the project itself first.
COPY . .
After dependencies are installed, we copy the source code.
FROM python:3.13-slim AS runtime
FROM python:3.13-slim AS runtime
ENV VENV_PATH="/opt/pysetup/.venv" \
PATH="/opt/pysetup/.venv/bin:$PATH"
RUN groupadd -g 1001 appgroup && \
useradd -u 1001 -g appgroup -m -d /home/appuser -s /bin/bash appuser
WORKDIR /app
COPY --from=build --chown=appuser:appgroup /opt/pysetup/.venv /opt/pysetup/.venv
COPY --from=build --chown=appuser:appgroup /opt/pysetup/ ./
USER appuser
ENTRYPOINT ["python", "-m", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]
The runtime stage starts with a clean slim image and creates a non-root user for security. We copy the virtual environment and project files from the build stage and set proper ownership.
Cache mounts are one of the most powerful features for optimizing Docker builds with Depot. This Dockerfile uses multiple cache mounts:
RUN --mount=type=cache,target=/root/.cache \
pip install "poetry==$POETRY_VERSION"
RUN --mount=type=cache,target=/root/.cache/pypoetry \
poetry install --no-root
type=cache
: Specifies this is a cache mount that persists across builds.target=/root/.cache
: Mount point for pip's cache directory when installing Poetry.target=/root/.cache/pypoetry
: Mount point for Poetry's cache directory where downloaded dependencies are stored.For more information regarding Poetry cache mounts, please visit the official Poetry documentation.