python-containers について
Python の Dockerfile と依存関係を扱う開発者向けに、Python コンテナイメージの構築と最適化を支援するスキルです。slim ベースイメージ、多段階ビルド、仮想環境、パッケージ管理に加え、Alpine やインタープリター不一致に伴う問題を扱います。
主な機能
- 01Python slim ベースイメージの指針
- 02パッケージ管理を使う多段階ビルド
- 03仮想環境の最適化
- 04コンパイル拡張と libc の考慮
- 05イメージ実行と依存関係の検証
活用シーン
- 01Python Docker イメージのサイズ削減
- 02uv、poetry、pip を使ったイメージ構築
- 03Alpine や musl 関連の問題調査
- 04インタープリターと仮想環境の互換性確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ laurigates/ claude-plugins --skill python-containersインストール後、Claude Code で/python-containersを入力して読み込まれたか確認します。
同梱ファイルREFERENCE.md
詳細
Python コンテナーの最適化
スリムなベースイメージ、仮想環境、最新のパッケージマネージャー(uv、poetry)、マルチステージビルドのパターンを活用して、最適化された Python コンテナーイメージを構築するための専門知識です。
このスキルを使用する場面
| 次の場合はこのスキルを使用します… | 次の場合は代わりに container-development を使用します… |
|---|---|
| Python に特化した Dockerfile を構築する | 一般的なマルチステージビルドのパターンを使用する |
| Python イメージのサイズを最適化する | 言語に依存しないコンテナーセキュリティを扱う |
| コンテナー内で pip/poetry/uv を扱う | Docker Compose の設定を行う |
| musl/glibc の問題に対処する | Python 以外のコンテナーを最適化する |
主な専門知識
Python コンテナーの課題:
- 不要なパッケージを含む大きなベースイメージ(約 1 GB)
- 重要:Alpine は Python に問題を引き起こします(musl と glibc の違い)
- 複雑な依存関係管理(pip、poetry、pipenv、uv)
- ビルドツールが必要なコンパイル済み C 拡張機能
- コンテナー内での仮想環境の取り扱い
主な機能:
- slim ベースのイメージ(Python では Alpine を使用しません)
- 最新のツール(uv を推奨)を使ったマルチステージビルド
- 仮想環境の最適化
- コンパイル済み拡張機能の取り扱い
- 非 root ユーザーの設定
Python で Alpine を使用しない理由
Python コンテナーには Alpine ではなく slim を使用します。Alpine は musl libc を使用しているため、次の問題が発生します。
- 多くの wheel が動作しません(numpy、pandas、scipy)
- ソースからのコンパイルが必要になります(ビルドが遅くなります)
- ビルドツールが必要になるため、最終イメージが大きくなります
- ネイティブ拡張機能で実行時エラーが発生します
最適化された Dockerfile のパターン(uv)
推奨パターンでは、約 80~120 MB のイメージを実現できます。
# Both stages MUST share this interpreter version — see below.
ARG PYTHON_VERSION=3.11
# Build stage
FROM python:${PYTHON_VERSION}-slim AS builder
WORKDIR /app
RUN pip install --no-cache-dir uv
# Copy dependency files
COPY pyproject.toml uv.lock ./
# Install dependencies with uv (much faster than pip)
RUN uv sync --frozen --no-dev
COPY . .
# Runtime stage
FROM python:${PYTHON_VERSION}-slim
WORKDIR /app
# Install only runtime dependencies (if needed)
RUN apt-get update && \
apt-get install -y --no-install-recommends \
libpq5 \
&& rm -rf /var/lib/apt/lists/*
# Create non-root user
RUN addgroup --gid 1001 appgroup && \
adduser --uid 1001 --gid 1001 --disabled-password appuser
# Copy only what's needed
COPY --from=builder --chown=appuser:appgroup /app/.venv /app/.venv
COPY --chown=appuser:appgroup app/ /app/app/
COPY --chown=appuser:appgroup pyproject.toml /app/
ENV PATH="/app/.venv/bin:$PATH" \
PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1
USER appuser
EXPOSE 8000
HEALTHCHECK --interval=30s CMD python -c "import requests; requests.get('http://localhost:8000/health')" || exit 1
CMD ["python", "-m", "app"]
インタープリターのバージョンを両ステージで一致させる
上記のパターンでは、仮想環境をステージ間でコピーします。
COPY --from=builder /app/.venv /app/.venv
この venv は 異なる Python マイナーバージョン間では移植できません。パッケージは
/app/.venv/lib/python<X.Y>/site-packages に格納され、その中のコンパイル済み拡張機能には
該当バージョンの ABI タグが付与されています。異なるマイナーバージョンで実行すると、
インタープリターは存在しないディレクトリを参照するため、venv 全体が
sys.path から 完全に除外されます。パッケージが 1 つ見つからないのではなく、
すべてのパッケージが見つからなくなります。
runtime python : 3.14.7
venv libdirs : python3.12
sys.path : ['', '/usr/local/lib/python314.zip',
'/usr/local/lib/python3.14',
'/usr/local/lib/python3.14/lib-dynload']
この場合、エントリーポイントが最初にインポートする標準ライブラリ以外のモジュールで
ModuleNotFoundError が発生します。そのため、インタープリターのバージョン不一致ではなく、
依存関係の不足を調べてしまうことがよくあります。
例のように、両方の FROM 行で 1 つの ARG を使います。Renovate は FROM で使われる
ARG のデフォルト値を更新するため、バージョンを更新可能な状態に保ちつつ、
ステージ間で不一致が起きないようにできます。
ボットによってステージ間に不一致が生じる理由
Renovate はイメージ名を基準に一致を判定します。両方のステージで同じイメージ名を指定している場合、
まとめて更新します。一方、異なるイメージ名を指定している場合、たとえば
ghcr.io/astral-sh/uv:python3.12-alpine のようなビルダーと
python:3.12-alpine のランタイムを組み合わせていると、Python のルールは後者にしか一致せず、
そちらだけが更新されます。差分を見ても、ステージ間の連携が壊れたことに気付けません。
ビルダーで uv を使う必要がある場合は、ベースイメージを切り替えるのではなく、
バイナリをコピーします。そうすれば両方のステージで同じ python: ベースを使い続けられます。
ARG PYTHON_VERSION=3.12
FROM ghcr.io/astral-sh/uv:0.12.7 AS uv
FROM python:${PYTHON_VERSION}-slim AS build
COPY --from=uv /uv /uvx /bin/
FROM python:${PYTHON_VERSION}-slim AS runtime
COPY --from=build /app/.venv /app/.venv
検証し、チェックが確実に機能するようにする
docker build が成功しても、レイヤーが組み立てられたことが分かるだけで、イメージが
起動できることは証明されません。公開前にイメージを実行し、単に何かをインポートするのではなく、
venv がパスに含まれていることを確認します。
docker run --rm -i "$IMAGE" /app/.venv/bin/python - <<'EOF'
import sys
assert [p for p in sys.path if "/app/.venv/" in p], sys.path
print("ok", sys.version.split()[0])
EOF
-i は不可欠です。これがないと docker は標準入力を転送せず、python - は
空のスクリプトを読み込みます。その結果、チェックは何も検証せずに終了コード 0 を返し、
壊れたイメージを含むすべてのイメージで成功してしまいます。このようなゲートは、
意図的にバージョンを不一致にしたビルドに対して実行し、失敗することを確認してください。
パッケージマネージャーの概要
| マネージャー | 速度 | コマンド | 備考 |
|---|---|---|---|
| uv | 10~100倍高速 | uv sync --frozen --no-dev | 推奨 |
| poetry | 標準 | poetry install --only=main | POETRY_VIRTUALENVS_IN_PROJECT=1 を設定します |
| pip | 標準 | pip install --no-cache-dir --prefix=/install -r requirements.txt | マルチステージでは --prefix を使用します |
パフォーマンスへの影響
| 指標 | フル(1GB) | スリム(400MB) | マルチステージ(150MB) | 最適化済み(100MB) |
|---|---|---|---|---|
| イメージサイズ | 1GB | 400MB | 150MB | 100MB |
| プル時間 | 4分 | 1分30秒 | 35秒 | 20秒 |
| ビルド時間(pip) | 5分 | 4分 | 3分 | 3分 |
| ビルド時間(uv) | - | - | 45秒 | 30秒 |
| メモリ使用量 | 600MB | 350MB | 200MB | 150MB |
セキュリティへの影響
| イメージの種類 | 脆弱性 | サイズ | リスク |
|---|---|---|---|
| python:3.11(フル) | 50~70 CVE | 1GB | 高 |
| python:3.11-slim | 12~18 CVE | 400MB | 中 |
| マルチステージのスリムイメージ | 8~12 CVE | 150MB | 低 |
| Distroless Python | 4~6 CVE | 140MB | 非常に低 |
エージェント向け最適化
| コンテキスト | コマンド | 目的 |
|---|---|---|
| クイックビルド | DOCKER_BUILDKIT=1 docker build -t app . | キャッシュを使って高速にビルドします |
| サイズ確認 | docker images app --format "table {{.Repository}}\t{{.Size}}" | イメージサイズを確認します |
| レイヤー分析 | docker history app:latest --human | head -20 | サイズの大きなレイヤーを特定します |
| インポートのテスト | docker run --rm app python -c "import app" | インポートが機能することを確認します |
| 依存関係の一覧 | docker run --rm app pip list --format=freeze | インストール済みパッケージを確認します |
| セキュリティスキャン | docker run --rm app pip-audit | 脆弱性を確認します |
ベストプラクティス
- Python では
alpineではなくslimを使用します - 最速のビルドには uv を使用します(pip より10~100倍高速)
- マルチステージビルドを使用します
PYTHONUNBUFFERED=1とPYTHONDONTWRITEBYTECODE=1を設定します- root 以外のユーザーで実行します
- 仮想環境を使用し、ロックファイルで依存関係のバージョンを固定します
- pip では
--no-cache-dirを使用します
詳しい例、高度なパターン、ベストプラクティスについては、REFERENCE.md を参照してください。
関連スキル
container-development- 一般的なコンテナのパターン、マルチステージビルド、セキュリティgo-containers- Go 固有のコンテナ最適化nodejs-containers- Node.js 固有のコンテナ最適化