🌼

uv × DockerでのPython開発環境構築方法

に公開

松尾研究所では、Python開発における標準ツールとしてuvを推奨しています。uvはPythonのパッケージ管理ツールで、依存関係の管理や仮想環境の構築を自動化し、高速で再現性のある開発を可能にすることが特長です。

Pythonパッケージだけでなく、Node.jsやブラウザ周りのツールなど他の依存も扱うときには、uvとDockerを併用するケースもあるかと思います。Dockerのコンテナ上でuvを使用する方法について社内で話題になったとき、調べたところいくつか方法があることが分かったので、それぞれの方法の違いと松尾研究所推奨の環境構築方法についてまとめました。

推奨方針まとめ

  • Python開発はuvを標準とする
  • Docker運用はAstral公式のuv+pythonイメージの使用を推奨
  • Astral公式のuvイメージ、または公式インストーラ(install.sh)によるuvの直接インストールは補足的手段とする

パターン1(推奨): 公式のuv+pythonイメージを使用

uv+Pythonが同梱されたAstral公式イメージを利用する方式です。タグでuvとPythonのバージョンを指定できます。Dockerfileをシンプルにできるのが特長です。以下はDockerfileの最小限のコード例です。

FROM ghcr.io/astral-sh/uv:0.9.2-python3.12-bookworm-slim

WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen

COPY . .
CMD ["uv", "run", "python", "app.py"]

参考:uv公式サイト Reproducible examples

パターン2: 公式のuvのみが入ったイメージを使用

uvバイナリのみが入った公式イメージを利用して、任意のベースイメージにuvをコピーする方式です。

ベースとなるイメージ(例:python:3.12-slimなど)が既にある場合や、Pythonのバージョン・環境を自分で管理したい場合にはこちらを選んでも良いと思います。

FROM python:3.12-slim

# uv バイナリをコピー
COPY --from=ghcr.io/astral-sh/uv:0.9.2 /uv /usr/local/bin/uv

WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen

COPY . .
CMD ["uv", "run", "python", "app.py"]

パターン3: uvを公式インストーラで直接インストール

install.shを利用してuvをインストールする方式です。

開発の標準インストール方法で、開発環境と環境構築方法を統一できる点と何をしているか一目で分かるのがメリットです。ただ、固定バージョンのuvを手軽にインストールするには、パターン1or2の方が良いかと思います。

FROM python:3.12-slim

# curlをインストールしてuvをインストール
RUN apt-get update && apt-get install -y --no-install-recommends curl && \
    curl -fsSL https://astral.sh/uv/install.sh | sh && \
    apt-get remove -y curl && apt-get autoremove -y && rm -rf /var/lib/apt/lists/*
ENV PATH="/root/.local/bin:$PATH"

WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen

COPY . .
CMD ["uv", "run", "python", "app.py"]

まとめ

Docker上でuvを使う方法について、3パターンの方法とそれぞれの特長を説明しました。松尾研究所では、公式のuv+pythonイメージを使用する方法を推奨として、テンプレートとして社内専用のcookiecutter(外部非公開)も整備しています。

今回のまとめた知見が、読者の皆様や、皆様の組織でなにかの参考になれば幸いです。

参考リンク

uv公式サイト

Pythonパッケージ管理 [uv] 完全入門

Pythonの環境をuvへ移行する方法

Dockerで構築する機械学習環境【2024年版】

松尾研究所テックブログ

Discussion