# `python-base` sets up all our shared environment variables FROM python:3.11-slim as python-base # python ENV PYTHONUNBUFFERED=1 \ # prevents python creating .pyc files PYTHONDONTWRITEBYTECODE=1 \ \ # pip PIP_NO_CACHE_DIR=off \ PIP_DISABLE_PIP_VERSION_CHECK=on \ PIP_DEFAULT_TIMEOUT=100 \ \ # poetry # https://python-poetry.org/docs/configuration/#using-environment-variables # 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` stage is 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 RUN 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 poetry install --no-dev # `production` image used for runtime FROM python-base as production ENV FASTAPI_ENV=production COPY --from=builder-base $PYSETUP_PATH $PYSETUP_PATH COPY alembic.ini /usr/src/ COPY ./alembic /usr/src/alembic COPY ./app /usr/src/app WORKDIR /usr/src CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:8000", "app.main:app"]