コンテンツにスキップ

pex でマルチステージビルドを行う

マルチステージビルドとは

マルチステージビルドとは、Dockerfile のビルドステージを複数に分けることでビルドに必要なものと実行に必要なものを分けることできたり、最終的なイメージサイズを小さくしたりキャッシュを効きやすくできるビルド手法のこと。

pex でマルチステージビルドを行う

pex は、Python の依存パッケージを含めた実行可能な単一ファイルを作成するツールである。 pex を構築する際に、ソースコードと 3rd party パッケージを分けることで、マルチステージビルドを行うことができる。 このマルチステージビルドを行うことで、キャッシュが効きやすくなり、ビルド時間の短縮が期待できる。

Pants を使った次のようなディレクトリ構成を想定する。

1
2
3
4
5
.
├── Dockerfile
├── requirements.txt
├── BUILD
└── main.py

次のように pex を構築することでソースと 3rd party パッケージを分けることができる。

BUILD
pex_binary(
    name="binary-deps",
    execution_mode="venv",
    entry_point="main.py",
    layout="packed",
    include_sources=False,
    include_tools=True,
)

pex_binary(
    name="binary-srcs",
    execution_mode="venv",
    entry_point="main.py",
    layout="packed",
    include_requirements=False,
    include_tools=True,
)
BUILD
docker_image(
    name="img-deps",
    registries=["foo"],
    repository="deps",
    image_tags=[
        "latest",
    ],
    instructions=[
        "FROM python:3.11-slim",
        "COPY binary-deps.pex /binary-deps.pex",
        "RUN PEX_TOOLS=1 python3.11 /binary-deps.pex venv --scope=deps --compile /bin/app",
    ],
)

docker_image(
    source=None,
    name="img-srcs",
    registries=["foo"],
    repository="srcs",
    image_tags=[
        "latest",
    ],
    instructions=[
        "FROM python:3.11-slim",
        "COPY binary-srcs.pex /binary-srcs.pex",
        "RUN PEX_TOOLS=1 python3.11 /binary-srcs.pex venv --scope=srcs --compile /bin/app",
    ],
)

docker_image(
    source="Dockerfile",
    name="final-image",
    registries=["foo"],
    repository="bar",
    image_tags=["latest"],
    dependencies=[
        ":img-srcs",
        ":img-deps",
    ],
)
Dockerfile
1
2
3
4
FROM python:3.11-slim
COPY --from=foo/deps:latest /bin/app /bin/app
COPY --from=foo/srcs:latest /bin/app /bin/app
ENTRYPOINT ["/bin/app/pex"]

上記のコードを使ってコンテナイメージをビルドするとキャッシュが効きやすくなり、ビルド時間の短縮が期待できる。

注意点

ビルド時と実行時で、Python のパスが違うと動かない場合がある。その場合は pex 構築のオプションでshebang を指定するか、シンボリックリンクを張るなどの対応が必要。