Pythonプロジェクトで使える、venv, poetryを用いたDockerfileについて書きます。
目次
venvを使った軽量なコンテナを作るDockerfile
multistage buildを利用してなるべく必要最小限にしています。
https://matsuand.github.io/docs.docker.jp.onthefly/develop/develop-images/multistage-build/
また、以下の部分でaptのキャッシュ削除でイメージサイズを減らすことができます。
rm -rf /var/lib/apt/lists/*
https://docs.docker.jp/engine/articles/dockerfile_best-practice.html#run
Pythonプロジェクトのルートで以下のコマンドでビルド・実行してみてください。
docker build -t "image name" .
docker run --name "container name" -it "image name"
# ビルド・ランタイム共通のPythonバージョン
ARG PYTHON_VERSION="3.9"
# ビルド用
FROM python:${PYTHON_VERSION} as build-env
# Pythonスクリプトをローカルからコピー
COPY . /app
WORKDIR /app
# venvのセットアップ・ライブラリインストール
RUN python -m venv ./venv
RUN . venv/bin/activate && pip install -U pip && pip install -r requirements.txt
# ランタイム
FROM python:${PYTHON_VERSION}-slim
ENV PYTHONBUFFERED=1
# venvのpythonを使用するようにする
ENV PATH /venv/bin:$PATH
# venv含めてPythonスクリプトをビルド用環境からコピー
COPY --from build-env /app /
# ランタイムで必要なライブラリインストール
RUN apt-get update && apt-get install -y \
必要なライブラリ \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["python", "起動したいスクリプト"]
poetryを使った軽量なコンテナを作るDockerfile
poetryを使っているプロジェクトの場合は以下のようになります。
poetryをインストールして、poetry exportでrequirements.txtを出力してからは同じ感じです。
without-hashesを指定していますが、export時に全パッケージにhashを指定してくれず、pip install時にhashつけるなら全てにつけろみたいなエラーで怒られるためです。
# ビルド・ランタイム共通のPYTHONバージョン
ARG PYTHON_VERSION="3.9"
# ビルド用
FROM python:${PYTHON_VERSION} as build-env
# Pythonスクリプトのコピー
COPY . /app
WORKDIR /app
# poetryからrequirements.txtをexport
RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
RUN . $HOME./poetry/env && poetry export -f requirements.txt -o requirements.txt --whitout-hashes
RUN python -m venv ./venv
RUN . venv/bin/activate && pip install -U pip && pip install -r requirements.txt
# ランタイム
FROM python:${PYTHON_VERSION}-slim
#
ENV PYTHONBUFFERED=1
# venvのpythonを使用するようにする
ENV PATH /venv/bin:$PATH
COPY --from build-env /app /
# ランタイムで必要なライブラリインストール
RUN apt-get update && apt-get install -y \
必要なライブラリ
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["python", "起動したいスクリプト"]
poetry上で動かすためのDockerfile
poetryで動かしたい場合は以下の感じになります。
FROM python:3.9-slim
WORKDIR /app
ADD . /app/ # poetryプロジェクトをコピー
RUN apt-get update && apt-get install -y gcc \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN pip install poetry
RUN poetry install
ENTRYPOINT ["poetry", "run", "実行したいスクリプト"]