Should I be running Poetry inside Docker, or should I be using pip, pipx, or something similar instead?
Should I be building wheels, or tarballs and passing them into the Docker container instead of running pip or poetry inside the Docker container?
Here’s an example of one of the Dockerfiles that I tried, but never got to work – the environment is broken, and I have no idea why:
FROM python:3.10
# Configure Poetry
ENV POETRY_VERSION=1.2.0
ENV POETRY_HOME=/opt/poetry
ENV POETRY_VENV=/opt/poetry-venv
ENV POETRY_CACHE_DIR=/opt/.cache
# Install poetry separated from system interpreter
RUN python3 -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 /app
# Install dependencies
COPY poetry.lock pyproject.toml ./
RUN poetry install
# Run your app
COPY . /app
ENTRYPOINT [ "./entrypoint.sh" ]
entrypoint.sh
contains:
poetry run blah
In this case, the problem is that the virtualenv is broken, and I have no idea why:
$ docker run blah/blah:latest
The virtual environment found in /app/.venv seems to be broken.
Recreating virtualenv blah-9TtSrW0h-py3.10 in /opt/.cache/virtualenvs/blah-9TtSrW0h-py3.10
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/local/lib/python3.10/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
File "<frozen importlib._bootstrap>", line 992, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 883, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
...
import dateutil.parser
ModuleNotFoundError: No module named 'dateutil'
Should I even be using Poetry within Docker? Should I use pip or pipx instead?
What are you supposed to do when you want to run a Python application in a container? Are wheels the answer? Is something else the answer?
2
Answers
I've come up with an approach that seems to work:
requirements.txt
file:requirements.txt
rather than using Poetry:Where
entrypoint.sh
contains:To ensure that my
requirements.txt
is in sync withpoetry.lock
I build the container using a Makefile which has been simplified to:This translates
poetry.lock
into arequirements.txt
file at build time when thebuild
Makefile goal is called and ensures that the two files are in sync when building container images.From the error,
poetry
detect a virtual env in/app/.venv
, i guess your app not have.dockerignore
to exclude.venv
from docker build context,.venv
on your local also copied into image byCOPY . .
You can use
poetry
to install dependencies in image also usepoetry
created virtual env as you app interpretor in image as following:poetry.toml
, ispoetry
setting for project.dockerignore
Dockerfile