How do I install poetry in my image? (should I use pip?)
Which version of poetry should I use?
Do I need a virtual environment?
There are many examples and opinions in the wild which offer different solutions.
Install poetry with pip, configure virtualenv, install dependencies, run your app.
FROM python:3.10
ENV POETRY_VERSION=1.1.13
RUN python3 -m pip install poetry==$POETRY_VERSION
WORKDIR /my_app
COPY poetry.lock pyproject.toml ./
RUN poetry config virtualenvs.in-project true --local
RUN poetry install --no-dev
COPY . .
CMD [ "poetry", "run", "python", "-c", "print('hello world')" ]
How do I install poetry in my image? (should I use
pip?)
# Set Poetry Version
ENV POETRY_VERSION=1.1.13
# Install Poetry
RUN curl -sSL https://install.python-poetry.org | python3 - --version $POETRY_VERSION
# Add poetry install location to PATH
ENV PATH=/root/.local/bin:$PATH
pipUsing pip to install poetry is somewhat discouraged.
Be aware that it will also install Poetry’s dependencies which might cause conflicts with other packages.
ENV POETRY_VERSION=1.1.13
RUN python3 -m pip install poetry==$POETRY_VERSION
Which version of poetry should I use?
Specify the latest stable version explicitly in your installation.
Forgetting to specify POETRY_VERSION will result in undeterministic builds, as the installer will always install the latest version - which may introduce breaking changes
Do I need a virtual environment?
Yes, and you need to configure it a bit.
RUN poetry config virtualenvs.in-project true --local
The reasons for this are somewhat off topic:
By default, poetry creates a virtual environment in $HOME/.cache/pypoetry/virtualenvs to isolate the system interpreter from your application. This is the desired behavior for most development scenarios. When using a container, the $HOME variable may be changed by certain runtimes, so creating the virutal environment within your project solves any reproducibility issues that may arise.
To use poetry in a docker image you need to:
poetry run python ... to run your applicationThis is a minimal flask project managed with poetry.
You can copy these contents to your machine to test it out (expect for poerty.lock)
python-poetry-docker/
|- Dockerfile
|- app.py
|- pyproject.toml
|- poetry.lock
DockerfileFROM python:3.10 as poetry-base
RUN apt-get update && apt-get install -y curl
# https://python-poetry.org/docs/master/#installation
ENV POETRY_VERSION=1.1.13
RUN curl -sSL https://install.python-poetry.org | python3 - --version "$POETRY_VERSION"
# See "Add Poetry to your PATH" in https://python-poetry.org/docs/master/#installing-with-the-official-installer
ENV PATH="/root/.local/bin:$PATH"
FROM poetry-base as example-app
WORKDIR /app
COPY poetry.lock pyproject.toml ./
# Configure virtualenv location inside project
RUN poetry config virtualenvs.in-project true --local
RUN poetry install --no-dev
COPY . /app
EXPOSE 5000
CMD [ "poetry", "run", "python", "-m", "flask", "run", "--host=0.0.0.0" ]
app.pyfrom flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, Docker!'
pyproject.toml[tool.poetry]
name = "python-poetry-docker-example"
version = "0.1.0"
description = ""
authors = ["Someone <someone@example.com>"]
[tool.poetry.dependencies]
python = "^3.10"
Flask = "^2.1.2"
[tool.poetry.dev-dependencies]
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
poetry.lock[[package]]
name = "click"
version = "8.1.3"
description = "Composable command line interface toolkit"
category = "main"
optional = false
python-versions = ">=3.7"
... more lines ommitted
Full contents in gist.