Poetry in Docker creates venv despite `poetry env use system`

59 Views Asked by At

Dockerfile:

FROM python:3.12-bookworm

# Configure Poetry
ENV POETRY_VERSION=1.8.1
ENV POETRY_HOME=/opt/poetry
ENV POETRY_VENV=/opt/poetry-venv
ENV POETRY_CACHE_DIR=/opt/.cache

# Install Poetry isolated from the system
RUN python -m venv $POETRY_VENV \
    && $POETRY_VENV/bin/pip install -U pip setuptools \
    && $POETRY_VENV/bin/pip install poetry==${POETRY_VERSION}

# Add Poetry to PATH
ENV PATH="${PATH}:${POETRY_VENV}/bin"

WORKDIR /usr/src/app

COPY poetry.lock pyproject.toml ./

# Configure Poetry to install project dependencies system-wide
RUN poetry env use system && poetry install

COPY . .

EXPOSE 8000

CMD ["uvicorn", "djadja.asgi:application"]

When I do docker run -it bash ... and inspect the container, everything looks and works exactly as expected (pip list, poetry env info, which uvicorn).

But when I run with a simple compose.yml (nothing there, just build .) it outputs the error:

web-1 | Creating virtualenv djadja-VA82Wl8V-py3.12 in /opt/.cache/virtualenvs
web-1 | Command not found: uvicorn

I've tried:

poetry config virtualenvs.create false

poetry config virtualenvs.in-project false

CMD ["/usr/local/bin/python", "-m", "uvicorn", ...]

CMD ["poetry", "run", "uvicorn", ...]

Please don't suggest workarounds like installing poetry directly to the system, using venv for the project dependencies, or using multi-stage builds.

1

There are 1 best solutions below

1
datawookie On BEST ANSWER

Assuming that your project looks like this:

├── djadja
│   └── asgi.py
├── Dockerfile
└── pyproject.toml

Dockerfile (Not convinced that we need a virtual environment in the image, so going without! See below for implementation using virtual environment.)

FROM python:3.12-bookworm

ENV POETRY_VERSION=1.8.1

RUN pip install -U pip setuptools && \
    pip install poetry==${POETRY_VERSION}

WORKDIR /usr/src/app

COPY pyproject.toml .

RUN poetry config virtualenvs.create false && poetry install --no-root

COPY . .

EXPOSE 8000

CMD ["uvicorn", "djadja.asgi:application", "--host", "0.0.0.0", "--port", "8000"]

Not sure what your pyproject.toml has in it, so using --no-root option to poetry to install dependencies.

pyproject.toml

[tool.poetry]
name = "example-project"
version = "0.1.0"
description = "A minimal example project with Poetry."
authors = ["Your Name <[email protected]>"]

[tool.poetry.dependencies]
python = "^3.8"
fastapi = "^0.65.2"
uvicorn = "^0.13.4"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

enter image description here

Dockerfile (Using virtual environment.)

FROM python:3.12-bookworm

WORKDIR /usr/src/app

ENV POETRY_VERSION=1.8.1
ENV POETRY_VENV=/usr/src/app/.venv

ENV PATH="${POETRY_VENV}/bin:${PATH}:"

RUN python -m venv $POETRY_VENV && \
    pip install -U pip setuptools && \
    pip install poetry==${POETRY_VERSION}

COPY pyproject.toml poetry.lock* ./

RUN poetry config virtualenvs.in-project true && \
    poetry install --no-root

COPY . .

EXPOSE 8000

CMD uvicorn djadja.asgi:application --host 0.0.0.0 --port 8000