LoginSignup
25
9

More than 3 years have passed since last update.

Python with poetry での Dockerfile の効率的な書き方の模索

Posted at

Pythonの機械学習用Docker imageのサイズ削減方法の紹介 という大変有益な M3 blog を twitter で見かけたので、便乗して自分が使っている Dockerfile との違いを簡単に書いてみようと思う。こちらは dashboard 用 Dockerfile であり機械学習用ではないので参考扱い程度に見てもらえればと。なお以下の内容が優れているとは思えないので better idea ある方にツッコミもらえれば幸いです。そしていつもながらインターネットの向こうの誰か1人に役に立ってもらえればも。なお、streamlit は大変便利。

結論

同じ部分

  • poetry で version 管理
  • multi-stage build を使う
  • docker build は dev, prod で cache が効く

違う部分

  • builder にて apt install を使わないなので builder も slim image を使う
  • poetry install は使わず poetry export を使う(実行イメージにはpoetry入れない)。そして requirements.txt と requirements-dev.txt を作成。
  • docker-compose.yml で dev, prod 切り替え
  • vscode を使い remote-container で開けば、開発環境側に python が不要。

code

build

少し前は .env 内で STAGE= と環境変数を定義していたが、書き換えがめんどくさいのでやめた。

# dev build
STAGE=dev docker-compose build
# prod build
docker-compose up build

Dockerfile

FROM python:3.8.5-slim as builder

WORKDIR /work/src
RUN pip install --upgrade pip && pip install poetry
COPY pyproject.toml poetry.lock ./
RUN poetry export --without-hashes -f requirements.txt > requirements.txt
RUN poetry export --without-hashes --dev -f requirements.txt > requirements-dev.txt
RUN pip install -r requirements.txt

### for dev. 
FROM python:3.8.5-slim as dev
ENV PYTHONUNBUFFERED=1
WORKDIR /work/src
COPY --from=builder /usr/local/lib/python3.8/site-packages /usr/local/lib/python3.8/site-packages
# need to copy if python package is installed in /usr/local/bin
COPY --from=builder /usr/local/bin/streamlit /usr/local/bin/streamlit
COPY src/ ./
# for dev packages
COPY --from=builder /work/src/requirements-dev.txt requirements-dev.txt
RUN pip install -r requirements-dev.txt
COPY tests/ ./
EXPOSE 8501  
CMD ["streamlit", "run", "hello.py"]

### for prod
FROM python:3.8.5-slim as prod
ENV PYTHONUNBUFFERED=1
WORKDIR /work/src
COPY --from=builder /usr/local/lib/python3.8/site-packages /usr/local/lib/python3.8/site-packages
# need to copy if python package is installed in /usr/local/bin
COPY --from=builder /usr/local/bin/streamlit /usr/local/bin/streamlit
COPY src/ ./
EXPOSE 8501  
CMD ["streamlit", "run", "hello.py"]

docker-compose.yml

version: '3'

services:
  app:
    build: 
      context: .
      target: ${STAGE:-prod}
    image: "internal-dashboard_app_${STAGE:-prod}"
    container_name: "internal-dashboard_${STAGE:-prod}"
    volumes:
      - ./src:/work/src
    ports:
      - "8501:8501"
    restart: always
    command: ["streamlit", "run", "hello.py"]

感想

tests の path 問題をどう対処するかいつも悩んでます。
以上。

25
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
9