Integrating Python Poetry with Docker

后端 未结 7 502
轻奢々
轻奢々 2021-01-29 17:51

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

7条回答
  •  误落风尘
    2021-01-29 18:21

    Multi-stage Docker build with Poetry and venv

    Do not disable virtualenv creation. Virtualenvs serve a purpose in Docker builds, because they provide an elegant way to leverage multi-stage builds. In a nutshell, your build stage installs everything into the virtualenv, and the final stage just copies the virtualenv over into a small image.

    Use poetry export and install your pinned requirements first, before copying your code. This will allow you to use the Docker build cache, and never reinstall dependencies just because you changed a line in your code.

    Do not use poetry install to install your code, because it will perform an editable install. Instead, use poetry build to build a wheel, and then pip-install that into your virtualenv. (Thanks to PEP 517, this whole process could also be performed with a simple pip install ., but due to build isolation you would end up installing another copy of Poetry.)

    Here's an example Dockerfile installing a Flask app into an Alpine image, with a dependency on Postgres. This example uses an entrypoint script to activate the virtualenv. But generally, you should be fine without an entrypoint script because you can simply reference the Python binary at /venv/bin/python in your CMD instruction.

    Dockerfile

    FROM python:3.7.6-alpine3.11 as base
    
    ENV PYTHONFAULTHANDLER=1 \
        PYTHONHASHSEED=random \
        PYTHONUNBUFFERED=1
    
    WORKDIR /app
    
    FROM base as builder
    
    ENV PIP_DEFAULT_TIMEOUT=100 \
        PIP_DISABLE_PIP_VERSION_CHECK=1 \
        PIP_NO_CACHE_DIR=1 \
        POETRY_VERSION=1.0.5
    
    RUN apk add --no-cache gcc libffi-dev musl-dev postgresql-dev
    RUN pip install "poetry==$POETRY_VERSION"
    RUN python -m venv /venv
    
    COPY pyproject.toml poetry.lock ./
    RUN poetry export -f requirements.txt | /venv/bin/pip install -r /dev/stdin
    
    COPY . .
    RUN poetry build && /venv/bin/pip install dist/*.whl
    
    FROM base as final
    
    RUN apk add --no-cache libffi libpq
    COPY --from=builder /venv /venv
    COPY docker-entrypoint.sh wsgi.py ./
    CMD ["./docker-entrypoint.sh"]
    

    docker-entrypoint.sh

    #!/bin/sh
    
    set -e
    
    . /venv/bin/activate
    
    while ! flask db upgrade
    do
         echo "Retry..."
         sleep 1
    done
    
    exec gunicorn --bind 0.0.0.0:5000 --forwarded-allow-ips='*' wsgi:app
    

    wsgi.py

    import your_app
    
    app = your_app.create_app()
    

提交回复
热议问题