Last active
November 9, 2024 02:20
-
-
Save usr-ein/c42d98abca3cb4632ab0c2c6aff8c88a to your computer and use it in GitHub Desktop.
Optimal multistaged Dockerfile for poetry
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# syntax=docker/dockerfile:1 | |
# Keep this syntax directive! It's used to enable Docker BuildKit | |
# Based on https://github.com/python-poetry/poetry/discussions/1879?sort=top#discussioncomment-216865 | |
# but I try to keep it updated (see history) | |
################################ | |
# PYTHON-BASE | |
# Sets up all our shared environment variables | |
################################ | |
FROM python:3.9-slim as python-base | |
# python | |
ENV PYTHONUNBUFFERED=1 \ | |
# prevents python creating .pyc files | |
PYTHONDONTWRITEBYTECODE=1 \ | |
\ | |
# pip | |
PIP_DISABLE_PIP_VERSION_CHECK=on \ | |
PIP_DEFAULT_TIMEOUT=100 \ | |
\ | |
# poetry | |
# https://python-poetry.org/docs/configuration/#using-environment-variables | |
POETRY_VERSION=1.3.2 \ | |
# make poetry install to this location | |
POETRY_HOME="/opt/poetry" \ | |
# make poetry create the virtual environment in the project's root | |
# it gets named `.venv` | |
POETRY_VIRTUALENVS_IN_PROJECT=true \ | |
# do not ask any interactive question | |
POETRY_NO_INTERACTION=1 \ | |
\ | |
# paths | |
# this is where our requirements + virtual environment will live | |
PYSETUP_PATH="/opt/pysetup" \ | |
VENV_PATH="/opt/pysetup/.venv" | |
# prepend poetry and venv to path | |
ENV PATH="$POETRY_HOME/bin:$VENV_PATH/bin:$PATH" | |
################################ | |
# BUILDER-BASE | |
# Used to build deps + create our virtual environment | |
################################ | |
FROM python-base as builder-base | |
RUN apt-get update \ | |
&& apt-get install --no-install-recommends -y \ | |
# deps for installing poetry | |
curl \ | |
# deps for building python deps | |
build-essential | |
# install poetry - respects $POETRY_VERSION & $POETRY_HOME | |
# The --mount will mount the buildx cache directory to where | |
# Poetry and Pip store their cache so that they can re-use it | |
RUN --mount=type=cache,target=/root/.cache \ | |
curl -sSL https://install.python-poetry.org | python3 - | |
# copy project requirement files here to ensure they will be cached. | |
WORKDIR $PYSETUP_PATH | |
COPY poetry.lock pyproject.toml ./ | |
# install runtime deps - uses $POETRY_VIRTUALENVS_IN_PROJECT internally | |
RUN --mount=type=cache,target=/root/.cache \ | |
poetry install --without=dev | |
################################ | |
# DEVELOPMENT | |
# Image used during development / testing | |
################################ | |
FROM python-base as development | |
ENV FASTAPI_ENV=development | |
WORKDIR $PYSETUP_PATH | |
# copy in our built poetry + venv | |
COPY --from=builder-base $POETRY_HOME $POETRY_HOME | |
COPY --from=builder-base $PYSETUP_PATH $PYSETUP_PATH | |
# quicker install as runtime deps are already installed | |
RUN --mount=type=cache,target=/root/.cache \ | |
poetry install --with=dev | |
# will become mountpoint of our code | |
WORKDIR /app | |
EXPOSE 8000 | |
CMD ["uvicorn", "--reload", "main:app"] | |
################################ | |
# PRODUCTION | |
# Final image used for runtime | |
################################ | |
FROM python-base as production | |
ENV FASTAPI_ENV=production | |
COPY --from=builder-base $PYSETUP_PATH $PYSETUP_PATH | |
COPY ./app /app/ | |
WORKDIR /app | |
CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", "main:app"] |
What's the use of PIP_DISABLE_PIP_VERSION_CHECK
and PIP_DEFAULT_TIMEOUT
if this is entirely based on Poetry?
What's the use of
PIP_DISABLE_PIP_VERSION_CHECK
andPIP_DEFAULT_TIMEOUT
if this is entirely based on Poetry?
@sn0opy Poetry is basically a wrapper around pip.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice image, but I have a question. What is a sense use stage after set ENVs(https://gist.github.com/usr-ein/c42d98abca3cb4632ab0c2c6aff8c88a#file-dockerfile-L47) ? Finally, we will use prod or dev part