4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Streamlit on uv + Docker 開発スタック

Last updated at Posted at 2024-12-11

はじめに

最近は Python での環境構築に uv を気に入って使っている。
そこで、Streamlit で作成した Web サービスを Docker に囲って出す際に、uv をベースとしたバージョン管理をしつつ公開する方法はどうすればいいかを実際に手を動かしながらやるということをまとめてみる。

uv プロジェクトの作成

まずは uv プロジェクトを作成するところから。

プロジェクト作成

uv init streamlit-uv-docker

streamlit の追加

Streamlit を依存関係に追加する。

uv add streamlit

開発用のモジュールの追加

こちらは、Docker でリリース環境として扱う際には含まないもの。
例えば、フォーマッタやリンタ、テストツールなどをこちらの方にインストールする。

uv add --dev ruff

結果の確認

pyprpoject.toml

pyproject.toml の中は次のようになっていると思う。

pypyroject.toml
[project]
name = "streamlit-uv-docker"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.10"
dependencies = [
    "streamlit>=1.40.2",
]

[dependency-groups]
dev = [
    "ruff>=0.8.1",
]

Streamlit の起動確認

uv run streamlit hello

2024-12-01 17.19.18 localhost fc6bfcbaeadc.png

アプリの作成

それではベースとなるアプリを作成していく。
uv のデフォルト環境は hello.py がおかれているだけ。
ここに実際に記述していってもいいが、ファイルの増加やファイル名がそもそも適切でないことから階層を作り直す。

root
  ├─ .venv
  ├─ .python-version
  ├─ app
  │  └─ app.py
  ├─ pyproject.toml
  ├─ README.md
  └─ uv.lock
__init__.py
from . import main

main.main()
main.py
import streamlit as st

def main():
    st.title("Python + uv + Streamlit + Docker!")

さて、ではこの構成で起動してみる。

uv run streamlit run app\app.py

2024-12-01 18.04.50 localhost 6a1d06233935.png

Docker 環境の構築

uv 側は、uv インストール済みの Docker イメージを公開してくれている。
まずはこれを利用することを考える。

Dockerfile の作成

Dockerfile
FROM python:3.12-slim-bookworm

COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

ADD . /app

WORKDIR /app

RUN uv sync --frozen

CMD ["uv", "run", "streamlit", "run", "app.py"]

uv を地でインストールする
通常のインストールプロセスと同様に uv をインストールする方法もある。
通常の Python 環境等の Dcoker イメージを使用した場合は、以下を上記の COPY 部分の代わりに記述する。

Docker
FROM python:3.12-slim-bookworm

# レポジトリ情報を更新 && curl をインストールして有効にしておく
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates

# 最新のインストーラーをダウンロード
ADD https://astral.sh/uv/install.sh /uv-installer.sh

# インストーラーを使ってインストールし、インストーラーを削除
RUN sh /uv-installer.sh && rm /uv-installer.sh

# PATH 環境変数にパスが通ってるかを確認
ENV PATH="/root/.local/bin/:$PATH"

.dockerignore で同期不要なものに対する対応

上記までローカルで作業していたため 別環境の .venv 環境 が作成されてしまっているので、Docker 処理でそれごとコピーされてしまうのを .dockerignore ファイルを作成することによって防ぐ。

.dockerignore
# Ignore the virtual environment
.venv

TROUBLESHOOT: .venv を ignore しないと?
次のようなエラーが発生する。.venv は、プラットフォームの依存も含めた仮想環境なのを忘れずに対処をしよう。

 => ERROR [stage-0 5/5] RUN uv sync --frozen                                                                                                               0.3s
------
 > [stage-0 5/5] RUN uv sync --frozen:
0.247 error: Project virtual environment directory `/app/.venv` cannot be used because it is not a valid Python environment (no Python executable was found)
------
Dockerfile:9
--------------------
   7 |     WORKDIR /app
   8 |
   9 | >>> RUN uv sync --frozen
  10 |
  11 |     CMD ["uv", "run", "streamlit", "run", "main.py"]
--------------------
ERROR: failed to solve: process "/bin/sh -c uv sync --frozen" did not complete successfully: exit code: 2

Docker イメージのビルド

Docker イメージをビルドする。
今回はわかりやすい様に、タグ (-t) を streamlit-uv として打った。

docker build . -t streamlit-uv

実際に動かしてみる

Streamlit はデフォルトポートは、8501 となっているので、必要に応じてポートフォワーディングする。Ex) -p 80:8501
起動するコンテナ名 (--name) は st-uv として名付けて起動。

docker run -p 80:8501 --name "st-uv" streamlit-uv

実行すると、次の様に Docker コンテナが動作する。

image.png

localhostlocalhost:80 等でアクセスする事で、次の様にアクセスできる事が確認できる。

2024-12-12 01.44.01 localhost b257a1ecd2f4.png

ついでに Docker Compose も用意

実際に環境をデプロイする場合は Docker Compose もまとめて用意する事も多い。
さらには、開発環境もデプロイ環境の Docker 内を直接書き換えながら開発したいと思うので、次のように項目を追加しておく。

compose.yaml
services:
  example:
    build: .
    ports:
      - 80:8501

開発環境の Docker Compose 設定も追加

compose.yaml
# 省略
    develop:
      watch:
        - action: sync
          path: .
          target: /app
          ignore:
            - .venv/

        - action: rebuild
          path: ./pyproject.toml

すると、

docker compose watch

コマンドを実行する事で、ローカル環境のファイルの変更を同期しながら開発できる。

さいごに

意外と、uv ってどう入れるんやろうな?uv 周りとか自分で Docker イメージ作る時の配慮とか必要なのかな?という疑問だけがあったが、それもこうして一通りやってみたら、めちゃくちゃちゃんとサポートされてる!という気付きがあった。

とりあえず、uv で管理しているプロジェクトも、問題なくデプロイ環境への導入はいけそうだ。
動作も警戒なので、今後も更新を注視したい。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?