コンテンツへスキップ

Dockerを使用したコンテナの構築

Pythonコードをコンテナに配置したい場合、PyPIや他のレジストリに提出しないサーバーコードがある可能性があります。その場合は、読み進めてください。そうでない場合は、次のセクションにスキップしてください。

このガイドでは、DockerとDockerfileに関するある程度の知識が必要です。

ソースからのコンテナ作成

  1. プロジェクトが仮想プロジェクトとして設定されていることを確認してください。つまり、インストールできず、依存関係としてマークされません。プロジェクトをインストール可能にする必要がある場合は、次のセクションに進んでください。

    • pyproject.toml[tool.rye]セクションにvirtual = trueが含まれている必要があります。含まれていない場合は、追加してrye syncを実行してください。
    • プロジェクトを新規に設定する場合は、rye initではなくrye init --virtualを実行してください。
  2. uvを使用して、次の内容を含むDockerfileをプロジェクトルートに作成します。

    FROM python:slim
    
    RUN pip install uv
    
    WORKDIR /app
    COPY requirements.lock ./
    RUN uv pip install --no-cache --system -r requirements.lock
    
    COPY src .
    CMD python main.py
    

    または、pipを使用します。

    FROM python:slim
    
    WORKDIR /app
    COPY requirements.lock ./
    RUN PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -r requirements.lock
    
    COPY src .
    CMD python main.py
    
  3. これで、次のようにイメージをビルドできます。

    docker build .
    

Dockerfileの調整

このガイドのDockerfileは例です。必要に応じて調整する可能性のある項目を以下に示します。

  • コマンド(CMD python src/main.py)は、スクリプトを指している必要があります。
  • ベースイメージ(FROM python:slim)を調整します。
  • .python-versionファイルのものと一致するタグ付きバージョンを使用することをお勧めします(例:FROM python:3.12.0-slim)。
  • -slimバリアントは、一般的にイメージサイズと互換性のバランスが良く、ほとんどのワークロードで問題なく動作します。しかし、より小さなイメージ(ただし互換性の問題が発生する可能性があります)には-alpineを使用することも、より多くのシステムツールを含むものにはサフィックスなしを使用することもできます。
  • 追加のシステムパッケージが必要な場合は、ソースコードのコピー前、つまりCOPY src .行の前にインストールします。Debianベースのイメージ(つまり-slimまたはサフィックスなしのバリアント)を使用する場合は、次のようになります。
RUN apt-get update \
    && apt-get install -y --no-install-recommends some-dependency another-dependency \
    && rm -rf /var/lib/apt/lists/*

Pythonパッケージからのコンテナ作成

コードがインストール可能なパッケージの場合は、最初にビルドしてから、Dockerイメージ内にインストールすることをお勧めします。これにより、イメージがユーザーインストールと完全に同じであることを確認できます。

uvを使用したDockerfileの例を以下に示します。

FROM python:slim
RUN pip install uv
RUN --mount=source=dist,target=/dist uv pip install --no-cache /dist/*.whl
CMD python -m my_package

Dockerイメージをビルドするには、最初に次のようにホイールをビルドする必要があります。

rye build --wheel --clean
docker build . --tag your-image-name

このアプローチでは、依存関係とコードが単一レイヤーにバンドルされます。これはパフォーマンスの点で有利ですが、すべての依存関係が毎回のイメージビルド時に再インストールされることを意味し、異なるバージョンでは依存関係のディスクスペースが共有されません。

前のセクションのDockerfileの調整が適用されます。

解説

Ryeのロックファイル標準は、pip(およびuvで使用される)のrequirements.txt形式であるため、依存関係をインストールするためにコンテナ内にryeを実際に必要とすることはありません。これにより、Dockerfileがはるかにシンプルになり、小さなイメージが必要な場合は複数ステージのビルドが不要になります。

pipuvにそれぞれ渡される--no-cache-dir--no-cacheパラメーターは、一時ファイルを書き込まないことでイメージサイズを小さくします。キャッシングは後続のビルドを高速化できますが、イメージは一度ビルドされてから何度も使用されるコンテナでは必要ありません。

同様に、PYTHONDONTWRITEBYTECODE=1環境変数は、コンテナでは必要のない.pycファイルの書き込みを回避するために設定されています。(uvはデフォルトで.pycファイルの書き込みをスキップします。)