Closed7

uvをDockerでも使う

kun432kun432

uvはDockerイメージも提供している。

https://github.com/astral-sh/uv/pkgs/container/uv

イメージには2種類ある。

  • OS含まないディストロレス: uv以外含まれない
  • OS含む派生イメージ: uvがプリインストールされたオペレーティングシステム

OSを含む派生イメージは、Alpine、Debian、Pythonなどのベースイメージがベースになっている。

ディストロレスを試してみる。

docker run --rm ghcr.io/astral-sh/uv:0.7.15 --version
出力
uv 0.7.15

次にdebianベースのもの

 docker run --rm -ti ghcr.io/astral-sh/uv:bookworm-slim bash
root@fde219352445:/# which uv
/usr/local/bin/uv
root@fde219352445:/# uv --version
uv 0.7.15

なので使い方としては、OSを含む派生イメージをビルドイメージとして使って、ディストロレスイメージでランタイム環境を作る、みたいな感じになるのではなかろうか。

kun432kun432

シンプルなFastAPIのAPIサーバのプロジェクトを作ってやってみる。

uv init -p 3.12 sample-fastapi-docker && cd sample-fastapi-docker
uv add fastapi[standard] uvicorn
main
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

とりあえず実行

uv run uvicorn main:app --reload
出力
INFO:     Will watch for changes in these directories: ['/Users/kun432/work/sample-fastapi-docker']
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [24244] using WatchFiles
INFO:     Started server process [24246]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

curlで確認

curl -s -X GET http://127.0.0.1:8000 | jq -r .
出力
{
  "Hello": "World"
}

ではこれをコンテナ化する。まずはOS入りのイメージで。

Dockerfile
FROM ghcr.io/astral-sh/uv:0.7.15-debian-slim

WORKDIR /app

COPY pyproject.toml uv.lock .python-version ./
RUN uv sync --locked

COPY main.py .

CMD ["uv", "run", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

ビルド

docker build -t sample-fastapi-docker .

コンテナ起動

docker run --rm -p 8000:8000 sample-fastapi-docker
出力
INFO:     Started server process [10]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

アクセスしてみる

curl -s -X GET http://127.0.0.1:8000 | jq -r .
出力
{
  "Hello": "World"
}
kun432kun432

最適化のための設定やフラグがある

--compile-bytecode / UV_COMPILE_BYTECODE

Pythonコードをあらかじめバイトコードにコンパイルしておくことができる。コンテナ起動時のインポートなどが高速化され、起動時間が速くなる。

RUN uv sync --compile-bytecode
ENV UV_COMPILE_BYTECODE=1
RUN uv sync

キャッシュ

FROM ghcr.io/astral-sh/uv:0.7.15-debian-slim

WORKDIR /app

# 依存関係のインストール --> (1)
RUN --mount=type=cache,target=/root/.cache/uv \
    --mount=type=bind,source=uv.lock,target=uv.lock \
    --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
    uv sync --locked --no-install-project

# プロジェクトファイルのコピー
COPY main.py pyproject.toml uv.lock .python-version .

# プロジェクトの同期 --> (2)
RUN --mount=type=cache,target=/root/.cache/uv \
    uv sync --locked

CMD ["uv", "run", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

ビルド

BUILDKIT=1 docker build -t sample-fastapi-docker .

通常は(1)で依存関係のみがインストールされるが、ここでキャッシュを生成して、例えばその後でアプリケーションのソースコードなどを変更した場合でも、それ以降の再ビルドではその手前のキャッシュが有効になる、ということみたい。ここはちゃんとまだ理解ができていない・・・もう少し調べる。

kun432kun432

まだまだ理解が足りないなぁ・・・

このスクラップは2ヶ月前にクローズされました