Can you give me an example of a Dockerfile
in which I can install all the packages I need from poetry.lock
and pyproject.toml
into my imag
I have been able to set up poetry
for a Django
project using postgres
. After doing some research, I ended up with the following Dockerfile
:
FROM python:slim
# Keeps Python from generating .pyc files in the container
ENV PYTHONDONTWRITEBYTECODE 1
# Turns off buffering for easier container logging
ENV PYTHONUNBUFFERED 1
# Install and setup poetry
RUN pip install -U pip \
&& apt-get update \
&& apt install -y curl netcat \
&& curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python
ENV PATH="${PATH}:/root/.poetry/bin"
WORKDIR /usr/src/app
COPY . .
RUN poetry config virtualenvs.create false \
&& poetry install --no-interaction --no-ansi
# run entrypoint.sh
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
This is the content of entrypoint.sh
:
#!/bin/sh
if [ "$DATABASE" = "postgres" ]
then
echo "Waiting for postgres..."
while ! nc -z $SQL_HOST $SQL_PORT; do
sleep 0.1
done
echo "PostgreSQL started"
fi
python manage.py migrate
exec "$@"
Some points to notice:
I have decide to use slim
instead of alpine
as tag for the python
image because even though alpine
images are supposed to reduce the size of Docker images and speed up the build, with Python, you can actually end up with a bit larger image and that takes a while to build (read this article for more info).
Using this configuration builds containers faster than using the alpine image because I do not need to add some extra packages to install Python packages properly.
I am installing poetry
directly from the URL provided in the documentation. I am aware of the warnings provided by sobolevn
. However, I consider that it is better in the long term to use the lates version of poetry
by default than relying on an environment variable that I should update periodically.
Updating the environment variable PATH
is crucial. Otherwise, you will get an error saying that poetry was not found.
Dependencies are installed directly in the python interpreter of the container. It does not create poetry
to create a virtual environment before installing the dependencies.
In case you need the alpine
version of this Dockerfile
:
FROM python:alpine
# Keeps Python from generating .pyc files in the container
ENV PYTHONDONTWRITEBYTECODE 1
# Turns off buffering for easier container logging
ENV PYTHONUNBUFFERED 1
# Install dev dependencies
RUN apk update \
&& apk add curl postgresql-dev gcc python3-dev musl-dev openssl-dev libffi-dev
# Install poetry
RUN pip install -U pip \
&& curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python
ENV PATH="${PATH}:/root/.poetry/bin"
WORKDIR /usr/src/app
COPY . .
RUN poetry config virtualenvs.create false \
&& poetry install --no-interaction --no-ansi
# run entrypoint.sh
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
Notice that the alpine
version needs some dependencies postgresql-dev gcc python3-dev musl-dev openssl-dev libffi-dev
to work properly.