uv + Ruff + mypyで構築する超軽量Python開発環境 – イメージサイズ削減・型安全性確保を実現

はじめに

ども!前回「DevContainer と uv で構築する爆速 Python 開発環境」という記事を書いた龍ちゃんです。

この記事を社内で報告したところ、上司から「リンターとフォーマッターは何を使っているの?」という質問をいただきました。確かに、せっかくパッケージマネージャーに uv を採用しているなら、同じ Astral 社が開発している Ruff で統一した方が良いですよね!

ということで今回は、uv + Ruff で統一した Python 開発環境を構築してみました。さらに、ベースイメージも見直すことで、イメージサイズを 83%削減(1.63GB → 273MB)することに成功しています。

Streamlit を使ったデータ分析アプリをサンプルとして作成していますが、もちろん Streamlit 以外のプロジェクトでも利用可能です。リポジトリは公開しているので、必要な方はクローンして使ってみてください!

リポジトリ: https://github.com/Ryunosuke-Tanaka-sti/uv-single-devcontianer.git

4 つの最適化ポイント

前回の環境から、大きく 4 つのポイントを最適化しました。それぞれ詳しく見ていきましょう。

① ベースイメージの変更による劇的な軽量化

前回はmcr.microsoft.com/devcontainers/python:3.11という Microsoft 公式の DevContainer 用イメージを使用していました。このイメージの利点は、デフォルトでvscodeユーザーが作成されていることと、Python 開発に必要なツールがプリインストールされていることです。

しかし、今回は軽量性を重視してpython:3.12-slimに変更しました。結果は驚くべきもので、イメージサイズが 1.63GB から 273MB へと 83%も削減されました!

項目Microsoft 公式今回の環境
ベースイメージmcr.microsoft.com/devcontainers/python:3.11python:3.12-slim
イメージサイズ1.63GB273MB
削減率83%削減

軽量化の理由は明確で、Microsoft 公式イメージには Python 開発用のツールが豊富にプリインストールされています(git、Black、Flake8、mypy、isort など)。これらは便利ですが、今回は uv と Ruff で統一するため不要です。python:3.12-slimは最小限の Python 環境(119MB)のみを含んでおり、必要なツールだけを追加することで無駄のない環境を構築できました。

イメージサイズの内訳:

  • python:3.12-slim(ベース): 119MB
  • git + curl のインストール: 101MB
  • uv のインストール: 53.6MB
  • 合計: 273MB

②Ruff へのツール統合でシンプルに

前回は Black、Flake8、isort と複数のツールを使用していましたが、今回はRuff 1 つに統合しました。

役割前回今回
フォーマッターBlackRuff
リンターFlake8Ruff
インポート整列isortRuff
ツール数3 つ1 つ
実行速度通常10-100 倍高速

Ruff は、Rust で実装された超高速リンター・フォーマッターで、Black、Flake8、isort、pyupgrade などの機能を統合しています。設定もpyproject.toml内で完結するため、非常にシンプルです。

注意: 型チェック(mypy)は Ruff に含まれていません。型チェックが必要な場合は、引き続き mypy や Pyright などの型チェッカーを併用してください。Ruff は型アノテーションの書き方に関するリントルールを提供しますが、静的型解析は行いません。

③ ユーザー管理の工夫

python:3.12-slimにはvscodeユーザーが存在しないため、devcontainer.jsonfeatures機能を使って自動作成します。これにより、ホストの UID/GID と一致させることができ、パーミッション問題を回避できます。

④ 型チェック(mypy)の統合で型安全性を確保

Python の型安全性を高めるため、mypy による型チェックを開発環境に統合しました。

項目従来の環境今回の環境
型チェックなし / 手動セットアップmypy 統合済み
VS Code 連携手動設定が必要自動で有効化
実行個別にコマンド実行保存時に自動チェック
設定の複雑さ複数ファイルに分散pyproject.toml に集約

注意: Ruff は型チェッカーを置き換えるものではありません。Ruff が提供するのは、リント(コード品質チェック)とフォーマットのみです。型安全性を確保したいプロジェクトでは、mypy や pyright などの型チェッカーを別途追加することを強く推奨します。

mypy を使うことで、以下のメリットが得られます:

  • バグの早期発見: 実行前に型の不整合を検出
  • リファクタリング安全性: 型情報を元に安全にコード変更
  • ドキュメント効果: 型ヒントが生きたドキュメントに
  • IDE サポート強化: より正確なコード補完と型推論

セットアップ手順

それでは、実際にこの環境を使ってみましょう。セットアップは驚くほど簡単です!

前提条件

  • Visual Studio Code
  • Docker Desktop
  • Dev Containers 拡張機能

手順

1. リポジトリのクローン

git clone https://github.com/Ryunosuke-Tanaka-sti/uv-single-devcontianer.git
cd uv-single-devcontianer

2. DevContainer で開く

  • VS Code でフォルダを開く
  • コマンドパレット(Ctrl+Shift+P / Cmd+Shift+P)
  • 「Dev Containers: Reopen in Container」を選択

3. 自動セットアップ完了

コンテナが起動すると、uv syncが自動実行され、依存関係がインストールされます。初回は数分かかりますが、2 回目以降はキャッシュが効いて数秒で起動します。

4. Streamlit アプリを実行

uv run streamlit run src/main.py

http://localhost:8501 にアクセスすると、データ分析デモアプリが起動します!

ディレクトリ構成

リポジトリをクローンすると、以下のような構成になっています。シンプルで分かりやすい構成ですね。

uv-single-devcontianer/
├── .devcontainer/
│   ├── Dockerfile           # 開発環境のDockerイメージ定義
│   └── devcontainer.json    # VS Code DevContainer設定
├── src/
│   └── main.py             # Streamlitアプリケーション(サンプル)
├── pyproject.toml          # Pythonプロジェクト設定(uv + Ruff設定)
├── uv.lock                 # uvの依存関係ロックファイル
├── README.md               # プロジェクト説明
└── .gitignore              # Git除外設定

各ファイルの役割:

  • .devcontainer/: DevContainer 関連の設定ファイルを格納
  • src/: アプリケーションコードを配置(今回は Streamlit のサンプル)
  • pyproject.toml: プロジェクトの依存関係と Ruff 設定を記述
  • uv.lock: 依存関係のバージョンを固定(再現性確保)

この構成は、Streamlit 以外のプロジェクトにも応用できます。例えば、FastAPI や Flask など、別のフレームワークを使う場合でも、pyproject.tomldependenciesを変更するだけで対応可能です。

設定ファイル解説

ここからは、各設定ファイルの詳細を見ていきます。コードは全文掲載しているので、コピペして使ってください。

Dockerfile

FROM python:3.12-slim

# 必要最小限のシステムパッケージをインストール
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
       git \
       curl \
    && rm -rf /var/lib/apt/lists/*

# uvのインストール(公式スクリプト使用)
RUN curl -LsSf https://astral.sh/uv/install.sh | sh \
    && mv /root/.local/bin/uv /usr/local/bin/uv

WORKDIR /workspace

# Streamlit用のポートを公開
EXPOSE 8501

ポイント解説:

  • python:3.12-slim: Debian ベースの軽量 Python イメージ(119MB)
  • --no-install-recommends: 推奨パッケージを除外して軽量化
  • rm -rf /var/lib/apt/lists/*: apt キャッシュを削除してサイズ削減
  • uv は公式スクリプトで最新版を自動取得

devcontainer.json

{
  "name": "Python Dev (uv + Ruff + mypy)",
  "build": {
    "dockerfile": "Dockerfile"
  },
  "features": {
    "ghcr.io/devcontainers/features/common-utils:2": {
      "username": "vscode",
      "userUid": "automatic",
      "userGid": "automatic",
      "installZsh": false
    }
  },
  "remoteUser": "vscode",
  "forwardPorts": [8501],
  "customizations": {
    "vscode": {
      "extensions": ["charliermarsh.ruff", "ms-python.python"],
      "settings": {
        "": {
          "editor.defaultFormatter": "charliermarsh.ruff",
          "editor.formatOnSave": true,
          "editor.codeActionsOnSave": {
            "source.fixAll.ruff": "explicit",
            "source.organizeImports.ruff": "explicit"
          }
        },
        "ruff.nativeServer": true,
        "python.linting.mypyEnabled": true,
        "python.linting.enabled": true,
        "python.analysis.typeCheckingMode": "basic"
      }
    }
  },
  "postCreateCommand": "uv sync"
}

ポイント解説:

  • features: vscode ユーザーを自動作成(UID/GID はホストと一致)
  • editor.formatOnSave: ファイル保存時に自動フォーマット
  • source.fixAll.ruff: Ruff のリント修正を自動適用
  • python.linting.mypyEnabled: mypy による型チェックを有効化
  • python.analysis.typeCheckingMode: Pylance の型チェックモードを設定
  • postCreateCommand: コンテナ作成時に依存関係を自動インストール

pyproject.toml

[project]
name = "my-streamlit-project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
    "streamlit>=1.39.0",
    "pandas>=2.2.0",
    "numpy>=2.0.0",
    "matplotlib>=3.10.7",
]

[dependency-groups]
dev = [
    "ruff>=0.7.0",
    "pytest>=8.0.0",
    "mypy>=1.18.2",
]

[tool.ruff]
line-length = 88
target-version = "py312"

[tool.ruff.lint]
select = [
    "E",   # pycodestyle errors
    "W",   # pycodestyle warnings
    "F",   # pyflakes
    "I",   # isort
    "N",   # pep8-naming
    "UP",  # pyupgrade
    "B",   # flake8-bugbear
]
ignore = []

[tool.ruff.lint.isort]
known-first-party = ["my_project"]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"

[tool.mypy]
python_version = "3.12"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = false
check_untyped_defs = true
ignore_missing_imports = true

Ruff 設定のポイント:

  • line-length = 88: Black と同じ行長(推奨)
  • select: 有効にするルールセット(PEP 8 準拠)
  • quote-style = "double": ダブルクォート使用
  • 設定が 1 ファイルに集約されてシンプル

mypy 設定のポイント:

  • python_version = "3.12": Python 3.12 の型システムを使用
  • warn_return_any = true: Any 型の返り値に警告
  • disallow_untyped_defs = false: 型ヒントなし関数も許可(段階的導入向け)
  • check_untyped_defs = true: 型ヒントなし関数も内部チェック
  • ignore_missing_imports = true: サードパーティライブラリの型スタブがなくてもエラーにしない

型チェックを実行するには:

# mypy で型チェック実行
uv run mypy src/

# VS Code では保存時に自動チェック

2 環境の徹底比較

最後に、2 つの環境パターンを比較してみましょう。

項目Microsoft 公式今回(uv + Ruff + mypy)
イメージサイズ1.63GB273MB
ツール統合Black, Flake8 等(3 つ)Ruff 1 つ
型チェック手動セットアップmypy 統合済み
実行速度通常10-100 倍高速
セットアップ簡単簡単
カスタマイズ性低い高い

選択の指針:

  • すぐ使いたい → Microsoft 公式イメージ: プリインストール済みで設定不要
  • 軽量・高速重視 → 今回の環境: バランスが良く、実用性が高い

今回の環境は、軽量性と実用性のバランスが取れているため、多くのプロジェクトで活用できると思います。

まとめ

今回は、uv + Ruff + mypy で統一した Python 開発環境を構築し、以下の成果を得ることができました:

  • イメージサイズ 83%削減(1.63GB → 273MB)
  • ツールを 3 つから 1 つに統合(Black + Flake8 + isort → Ruff)
  • 実行速度 10-100 倍高速化(Rust ベースの恩恵)
  • 設定がシンプルに(pyproject.toml 内で完結)
  • 型チェック統合(mypy で型安全性を確保)

前回の記事で構築した uv 環境をさらに最適化し、軽量・高速・シンプル・型安全の四拍子が揃った開発環境になりました。Astral 社のツール(uv + Ruff)で統一し、mypy で型安全性を追加することで、実用的かつ堅牢な開発環境を実現しています。

注意事項:
この環境は開発用途を想定しています。本番環境での使用には、追加のセキュリティ対策が必要です。型チェックの厳格さは、プロジェクトの要件に応じて pyproject.toml で調整できます

本番環境への展開を検討されている方へ

今回構築した開発環境は、開発体験の向上に焦点を当てています。本番環境(Production)にデプロイする際は、以下の追加対策が必要になります:

セキュリティ対策

  • non-root ユーザーでの実行: コンテナを root 以外のユーザーで実行
  • 脆弱性スキャン: Trivy 等のツールでイメージをスキャン
  • 多段階ビルド: ビルドツールと実行環境を分離してさらに軽量化

CI/CD パイプライン統合

  • GitHub Actions / GitLab CI: 自動テスト・型チェック・デプロイ
  • 自動リント・型チェック: Pull Request 時の自動チェック
  • イメージレジストリへの push: Docker Hub / GitHub Container Registry への自動デプロイ

これらの本番環境向け設定については、次回の記事で詳しく解説予定です。多段階ビルドによる本番用 Dockerfile の作成方法や、GitHub Actions を使った CI/CD パイプラインの構築手順を、実際に動くサンプルとともにお届けします!

続編記事もお楽しみに!


リポジトリは公開しているので、ぜひクローンして試してみてください。Streamlit 以外のプロジェクトでも、pyproject.tomldependenciesを変更するだけで利用できます。

皆さんも、ぜひ軽量で高速な Python 開発環境を体験してみてください!

リポジトリ: https://github.com/Ryunosuke-Tanaka-sti/uv-single-devcontianer.git

前回記事: DevContainer と uv で構築する爆速 Python 開発環境


参考リンク

この記事で紹介したツールの公式ドキュメントとリポジトリをまとめました。さらに詳しく知りたい方はこちらをご参照ください。

開発ツール

uv(パッケージマネージャー)

Ruff(リンター・フォーマッター)

mypy(型チェッカー)

開発環境

VS Code Dev Containers

アプリケーションフレームワーク

Streamlit

その他の参考資料

Docker 公式

PEP(Python Enhancement Proposals)

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です