uv on Docker環境でFastAPI + Lambda Web Adapter(LWA)アプリをマルチステージビルドする
本記事はPython Advent Calendar 2025の2日目の記事です。
はじめに
こんにちは、がんがんです。
以前の記事で FastAPI + Lambda Web Adapter(LWA) 用のコンテナを作成しました。
この記事ではパッケージの管理をrequirements.txt、pyenvで実施していました。
最近のPython開発ではuvをメインで利用しており、uv版のコンテナを作成を試みました。
uvを用いたPythonコンテナの作成方法は複数あります。今回紹介していない方法は以下の記事で詳しくまとめられていました。
複数の選択肢については以下の記事を合わせてご覧ください。
まとめ
最終的なDockerfile、pyproject.tomlはこちらです。
ARG APP_DIR="/api"
FROM ghcr.io/astral-sh/uv:0.9.11 AS uv
# Base image
FROM python:3.13.9-slim-bookworm AS base
WORKDIR /app
ENV TZ=Asia/Tokyo
ARG APP_DIR
COPY /lambda-adapter /opt/extensions/lambda-adapter
# Build stage
FROM base AS builder
ENV UV_COMPILE_BYTECODE=1 \
UV_NO_INSTALLER_METADATA=1 \
UV_LINK_MODE=copy
RUN \
uv sync --frozen --no-dev
# Production stage
FROM base AS prod
COPY /app/.venv/lib/python3.13/site-packages /usr/local/lib/python3.13/site-packages
COPY ${APP_DIR}/app/ .
# NOTE: FastAPI CLIではなくuvicornを利用しています
ENTRYPOINT ["python", "-m", "uvicorn"]
CMD ["main:app", "--host", "0.0.0.0", "--port", "8080"]
[project]
name = "exp-fastapi-app-example"
version = "0.1.0"
description = "experiment app"
requires-python = ">=3.13.0"
dependencies = [
"fastapi==0.121.0",
"pydantic==2.12.3",
"pydantic-settings==2.11.0",
"uvicorn==0.38.0",
]
[tool.uv]
required-version = ">=0.9.0"
今回は以下のようなディレクトリ構成でFastAPI App.を構築しています。FastAPIの詳細については今回深く触れません。お好きな構成を採用してください。
.
├── api/
│ ├── app/
│ │ ├── __init__.py
│ │ ├── dependencies.py
│ │ ├── main.py
│ │ └── settings.py
│ ├── .env
│ ├── .env.example
│ ├── pyproject.toml
│ └── uv.lock
├── api.Dockerfile # 本記事のメインファイル
├── api.Dockerfile.dockerignore
└── README.md
Dockerfileの書き方
1. uvを一時的に利用する
アプリケーションコンテナは可能な限り軽量に作成することが推奨されています。Dockerfileのベストプラクティスにもマルチステージビルドの利用、不要なパッケージをインストールしないことが推奨されています。
uvはライブラリのインストールのみで利用するためデプロイステージでは不要となります。そこでDockerのbindマウントを用いてuvを一時的に利用します。
RUN \
uv sync --frozen --no-dev
uvの一時的な利用は公式ドキュメントでも紹介されています。
2. pyproject.toml、uv.lockもbindマウントで利用する
uvと同じようにpyproject.toml、uv.lockもbindマウントで利用します。pyproject.toml、uv.lockもデプロイステージでは不要ですので可能であれば削りたいです。
2024年版のDockerfileの考え方&書き方の記事でも記載されていますがbindマウントはrequirements.txt方式や別言語でも有効なアプローチです。積極的に使っていきたいですね
3. LWA (Lambda Web Adapter)を利用する
LWAの利用は前回の記事と同じです。LWAの詳細は前回の記事を参照ください。
まとめ
今回はuv + FastAPI + LWAを利用したPythonコンテナを作成しました。
uvやruffなどAstral製のものは使い勝手が良いものが多いです。uvは公式ドキュメントのサポートが手厚いことも魅力的です。
本記事では利用していませんがUsing uv in Dockerのページでuv + Dockerコンテナの作成方法がまとめられていました。
uvを利用するユーザーが増えている一方、技術記事などの情報があまり多くないというデメリットもあります。自分用のメモとして適宜残していきたいですね。
Discussion