Poetry.lockとpyproject.tomlから必要なすべてのパッケージをDockerから自分のイメージ/コンテナーにインストールできるDockerfileの例を教えてください。
poetry
をdocker
と一緒に使用する場合、留意すべき点がいくつかあります。
poetry
をインストールする公式の方法は次のとおりです:
curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python
この方法により、poetry
とその依存関係を依存関係から分離できます。しかし、私の観点では、次の2つの理由からあまり良いことではありません。
poetry
バージョンは更新を取得する可能性があり、ビルドが中断します。この場合、POETRY_VERSION
環境変数を指定できます。インストーラーはそれを尊重しますそこで、pip install 'poetry==$POETRY_VERSION'
を使用します。ご覧のとおり、バージョンを固定することをお勧めします。
また、pyproject.toml
にもこのバージョンを固定します:
[build-system]
# Should be the same as `$POETRY_VERSION`:
requires = ["poetry==0.12.11"]
build-backend = "poetry.masonry.api"
ローカル環境とdocker
環境間のバージョンの不一致から保護します。
要件をキャッシュし、pyproject.toml
またはpoetry.lock
ファイルが変更された場合にのみ再インストールします。そうしないと、ビルドが遅くなります。作業キャッシュレイヤーを実現するには、以下を配置する必要があります。
COPY poetry.lock pyproject.toml /code/
poetry
がインストールされた後、他のファイルが追加される前。
次に留意することは、virtualenv
の作成です。 docker
では必要ありません。すでに分離されています。したがって、poetry config settings.virtualenvs.create false
設定を使用してオフにします。
私と同じDockerfile
を開発と本番の両方に使用する場合、いくつかの環境変数に基づいて異なる依存関係のセットをインストールする必要があります。
poetry install $(test "$YOUR_ENV" == production && echo "--no-dev")
このように、$YOUR_ENV
は、どの依存関係セットをインストールするかを制御します:all(デフォルト)または--no-dev
フラグを使用した実動のみ。
より良い体験のために、いくつかのオプションを追加することもできます。
--no-interaction
インタラクティブな質問をしない--no-ansi
フラグを使用すると、出力のログがよりわかりやすくなります次のような結果になります。
FROM python:3.6.6-Alpine3.7
ARG YOUR_ENV
ENV YOUR_ENV=${YOUR_ENV} \
PYTHONFAULTHANDLER=1 \
PYTHONUNBUFFERED=1 \
PYTHONHASHSEED=random \
PIP_NO_CACHE_DIR=off \
PIP_DISABLE_PIP_VERSION_CHECK=on \
PIP_DEFAULT_TIMEOUT=100 \
POETRY_VERSION=0.12.11
# System deps:
RUN pip install "poetry==$POETRY_VERSION"
# Copy only requirements to cache them in docker layer
WORKDIR /code
COPY poetry.lock pyproject.toml /code/
# Project initialization:
RUN poetry config settings.virtualenvs.create false \
&& poetry install $(test "$YOUR_ENV" == production && echo "--no-dev") --no-interaction --no-ansi
# Creating folders, and files for a project:
COPY . /code
完全に動作する実際の例をここで見つけることができます: wemake-Django-template
それは私のために働く最小限の構成です:
FROM python:3.7
ENV PIP_DISABLE_PIP_VERSION_CHECK=on
RUN pip install poetry
WORKDIR /app
COPY poetry.lock pyproject.toml /app/
RUN poetry config settings.virtualenvs.create false
RUN poetry install --no-interaction
COPY . /app
@ sobolevnの設定 ほど安全ではないことに注意してください。
トリビアとして、それを追加します 編集可能なインストールがpyproject.toml
プロジェクト 、1行または2行を削除できます。
FROM python:3.7
ENV PIP_DISABLE_PIP_VERSION_CHECK=on
WORKDIR /app
COPY poetry.lock pyproject.toml /app/
RUN pip install -e .
COPY . /app
Poetryとvenvを使用したマルチステージDockerビルド
Virtualenvの作成を無効にしないでください。 VirtualenvはDockerビルドで目的を果たします 。これは、マルチステージビルドを活用するエレガントな方法を提供するためです。簡単に言うと、ビルドステージはすべてをvirtualenvにインストールし、最後のステージではvirtualenvを小さなイメージにコピーします。
Poetryプレリリースの使用を気にしない場合は、コードをコピーする前に、poetry export
を使用し、固定された要件を最初にインストールできます。これにより、Dockerビルドキャッシュを使用でき、コードの行を変更しただけで依存関係を再インストールすることはできません。
poetry install
を使用してコードをインストールしないでください。編集可能なインストールが実行されるためです。代わりに、poetry build
を使用してホイールを構築し、それをvirtualenvにpipインストールします。 ( PEP 517 のおかげで、このプロセス全体は単純なpip install .
でも実行できますが、 build isolation により、詩の別のコピーをインストールすることになります)
以下は、Postgresに依存する、AlpineイメージにFlaskアプリをインストールするDockerfileの例です。この例では、エントリーポイントスクリプトを使用してvirtualenvをアクティブにします。 CMD
命令の/venv/bin/python
でPythonバイナリを参照するだけでよいためです。
Dockerfile
FROM python:3.7.4-Alpine3.10 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.0b1
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()
以下は、最初に依存関係を持つレイヤー(これらが変更されたときにのみビルドされる)と、次に完全なソースコードを持つレイヤーがイメージに追加されるストリップされた例です。 poetry
を設定してグローバルにインストールするsite-packages
は、削除できる構成アーティファクトを残します。
FROM python:Alpine
WORKDIR /app
COPY poetry.lock pyproject.toml ./
RUN pip install --no-cache-dir --upgrade pip \
&& pip install --no-cache-dir poetry \
\
&& poetry config settings.virtualenvs.create false \
&& poetry install --no-dev \
\
&& pip uninstall --yes poetry \
COPY . ./