flowchart TB
    subgraph Local["💻 ローカル開発"]
        PYENV[pyenv + venv]
        HB[Homebrew Python]
        DOCKER[Docker]
    end

    subgraph Purpose["🎯 用途"]
        DEV[日常の開発]
        TOOL[CLIツール実行]
        REPRO[本番再現]
    end

    subgraph Cloud["☁️ Cloud/AI"]
        LAMBDA[Lambda/Cloud Functions]
        ECS[ECS/Cloud Run]
        ML[ML Training]
    end

    PYENV --> DEV
    HB --> TOOL
    DOCKER --> REPRO

    DEV --> LAMBDA
    REPRO --> ECS
    REPRO --> ML

    style Local fill:#e3f2fd
    style Purpose fill:#fff3e0
    style Cloud fill:#e8f5e9
  

「また Python が動かない」問題

macOS で Python 開発をしていると、こんな経験がないだろうか。

    $ python --version
Python 2.7.18  # え、まだ 2.7?

$ pip install tensorflow
ERROR: Could not find a version that satisfies the requirement...

$ brew upgrade
# Python がアップデートされて、今まで動いてたものが壊れた
  

あるいは、AI 開発でこんな地獄を見たことは?

    $ pip install torch torchvision
# 30分かかってビルドエラー

$ pip install cuda-toolkit
# macOS には CUDA がない(そもそも NVIDIA GPU がない)

$ python train.py
# ローカルでは動くのに、AWS で動かない
  

なぜ、こんなに環境構築で苦労するのか?

答えは単純だ。pyenv、Homebrew、Docker は、それぞれ解決しようとしている問題が違うからだ。

目的が違うツールを混ぜて使うから、混乱が起きる。

この記事では、各ツールの「思想」を理解し、Cloud・AI 開発で本当に使える環境構築のベストプラクティスを解説する。


混乱の原因:3つのツールが解決する問題は全く違う

根本的な思想の違い

ツール 解決したい問題 思想
pyenv 「複数の Python バージョンを切り替えたい」 言語バージョン管理
Homebrew 「macOS にパッケージを簡単にインストールしたい」 OS パッケージ管理
Docker 「どの環境でも同じように動かしたい」 環境の完全再現

この違いを理解せずに「とりあえず brew install python」「とりあえず Docker で」とやるから、環境が壊れる。


pyenv系の役割:Python バージョンの切り替え

pyenv とは

    # 複数バージョンをインストール
pyenv install 3.9.18
pyenv install 3.11.7
pyenv install 3.12.1

# プロジェクトごとにバージョンを指定
cd ~/project-a
pyenv local 3.11.7

cd ~/project-b
pyenv local 3.12.1
  

pyenv の仕事は**「Python 本体のバージョンを管理すること」**だけだ。

pyenv + venv の組み合わせ

    # 1. pyenv でバージョンを指定
pyenv local 3.11.7

# 2. venv で仮想環境を作成
python -m venv .venv

# 3. 仮想環境を有効化
source .venv/bin/activate

# 4. パッケージをインストール
pip install -r requirements.txt
  

この組み合わせが、ローカル Python 開発の王道だ。

pyenv が向いているケース

    ✅ 複数プロジェクトで異なる Python バージョンが必要
✅ 新しい Python バージョンを試したい
✅ pip でインストールするライブラリ中心の開発
✅ 軽量に開発を始めたい
  

pyenv が向かないケース

    ❌ システムライブラリ(OpenCV、CUDA等)に依存する開発
❌ 本番環境と完全に同じ環境を再現したい
❌ チームメンバー全員の環境を揃えたい
  

pyenv のインストールと設定

    # Homebrew でインストール(これは OK)
brew install pyenv

# シェル設定に追加(~/.zshrc)
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

# Python のビルド依存関係をインストール
brew install openssl readline sqlite3 xz zlib
  

Homebrew の役割:システムツールの管理

Homebrew の本来の用途

Homebrew は macOS のパッケージマネージャーだ。

    # CLI ツールをインストール
brew install git
brew install jq
brew install awscli
brew install terraform
  

Homebrew で Python 開発環境を構築するのは、本来の用途ではない。

なぜ brew install python は危険か

    $ brew install python@3.11
$ brew upgrade  # 半年後...

# Python 3.11 → 3.12 に勝手にアップグレード
# 今まで動いてたスクリプトが壊れる
# pip でインストールしたパッケージも消える
  

Homebrew は「最新版を使いたい」思想で設計されている。バージョンを固定したい開発には向かない。

Homebrew Python が適切なケース

    ✅ aws-cli や git など、Python製 CLI ツールの実行環境として
✅ システム全体で使う汎用スクリプト用
✅ 一時的な検証や、バージョンにこだわらない用途
  

Homebrew Python を避けるべきケース

    ❌ プロジェクト開発(バージョン固定が必要)
❌ AI/ML 開発(依存関係が複雑)
❌ チーム開発(環境の再現性が必要)
  

Homebrew と pyenv の共存

    # pyenv の Python を優先させる設定
# ~/.zshrc に追加
export PATH="$PYENV_ROOT/shims:$PATH"

# Homebrew の Python を直接使いたい場合は絶対パス
/opt/homebrew/bin/python3 script.py
  

Docker の役割:環境の完全再現

Docker が解決する問題

Docker は「私のマシンでは動く」問題を解決する。

    # Dockerfile
FROM python:3.11-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .
CMD ["python", "main.py"]
  
    # どの環境でも同じように動く
docker build -t myapp .
docker run myapp
  

Docker が本当に必要なケース

    ✅ 本番環境と同じ環境でローカル開発したい
✅ システムライブラリ(OpenCV、FFmpeg等)に依存する
✅ チーム全員の環境を完全に揃えたい
✅ CI/CD と同じ環境でテストしたい
✅ GPU + CUDA 環境が必要(nvidia-docker)
  

Docker のオーバーヘッドを理解する

    ⚠️ Docker のデメリット

- macOS での I/O パフォーマンス低下(volume mount が遅い)
- メモリ・CPU リソースの消費
- ファイル変更の反映にラグがある場合がある
- デバッグが複雑になる
- 学習コスト
  

Docker が向かないケース

    ❌ 小規模なスクリプト開発
❌ 依存関係がシンプルなプロジェクト
❌ 高速なイテレーションが必要な開発初期
❌ Docker の学習コストをかけられない状況
  

比較表:どのツールを使うべきか

機能比較

機能 pyenv + venv Homebrew Docker
Python バージョン管理
パッケージ分離 ○ (venv) ×
環境の再現性 ×
起動速度
I/O パフォーマンス △ (macOS)
システムライブラリ対応
学習コスト 中〜高
CI/CD 連携

用途別の推奨

用途 推奨 理由
Web API 開発 pyenv + venv 軽量、高速なイテレーション
AI/ML 開発(CPU) pyenv + venv pip でほぼ完結
AI/ML 開発(GPU) Docker CUDA 環境の再現が必要
データ分析 pyenv + venv Jupyter との相性
マイクロサービス Docker 本番環境との一致
CLI ツール開発 pyenv + venv 軽量、デバッグしやすい
レガシー Python 2.x pyenv バージョン固定

Cloud・AI 開発での具体的な使い分け

パターン1:AWS Lambda / Cloud Functions

    ローカル: pyenv + venv で開発
デプロイ: requirements.txt + ランタイム指定
  
    # ローカル開発
pyenv local 3.11.7
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

# テスト
python -m pytest tests/

# デプロイ(SAM の場合)
sam build
sam deploy
  

Docker は不要。 Lambda ランタイムと Python バージョンを合わせれば動く。

パターン2:ECS / Cloud Run

    ローカル: Docker で開発
デプロイ: 同じ Docker イメージを使用
  
    # Dockerfile
FROM python:3.11-slim

WORKDIR /app

# 依存関係を先にインストール(キャッシュ効率化)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
  
    # docker-compose.yml(ローカル開発用)
services:
  app:
    build: .
    ports:
      - "8000:8000"
    volumes:
      - .:/app  # ホットリロード用
    environment:
      - DEBUG=true
  

パターン3:AI/ML 開発(ローカル CPU)

    ローカル: pyenv + venv で開発
学習: クラウド GPU インスタンス or Docker
  
    # ローカルでモデル開発
pyenv local 3.11.7
python -m venv .venv
source .venv/bin/activate

pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
pip install transformers datasets

# 小さいデータで動作確認
python train.py --debug --max-samples 100
  

パターン4:AI/ML 開発(GPU 学習)

    ローカル: pyenv + venv(CPU で動作確認)
学習: Docker + nvidia-docker
  
    # Dockerfile.gpu
FROM nvidia/cuda:12.1-cudnn8-runtime-ubuntu22.04

RUN apt-get update && apt-get install -y python3 python3-pip

WORKDIR /app
COPY requirements-gpu.txt .
RUN pip3 install --no-cache-dir -r requirements-gpu.txt

COPY . .
CMD ["python3", "train.py"]
  
    # GPU インスタンスで実行
docker run --gpus all -v $(pwd)/data:/app/data myapp-gpu
  

パターン5:データパイプライン(Airflow / Prefect)

    ローカル: Docker Compose で Airflow を起動
開発: pyenv + venv で DAG を開発
デプロイ: マネージドサービス or Kubernetes
  
    # docker-compose.yml
services:
  airflow:
    image: apache/airflow:2.7.3-python3.11
    volumes:
      - ./dags:/opt/airflow/dags
    ports:
      - "8080:8080"
  
    # DAG の開発は pyenv で
pyenv local 3.11.7
python -m venv .venv
pip install apache-airflow

# 単体テスト
python -m pytest dags/tests/
  

初心者がやりがちな失敗パターン

失敗1:システム Python を直接使う

    # ❌ 絶対にやってはいけない
sudo pip install package-name
pip install --user package-name  # これも危険
  

システム Python は OS が使う。 壊すと macOS の機能に影響する。

    # ✅ 正解
python -m venv .venv
source .venv/bin/activate
pip install package-name
  

失敗2:Homebrew Python でプロジェクト開発

    # ❌ バージョンが勝手に変わる
brew install python@3.11
pip install -r requirements.txt

# 半年後...
brew upgrade  # Python 3.12 になって環境崩壊
  
    # ✅ pyenv でバージョンを固定
pyenv install 3.11.7
pyenv local 3.11.7
python -m venv .venv
  

失敗3:何でも Docker にする

    # ❌ 簡単なスクリプトに Docker は過剰
docker run -v $(pwd):/app python:3.11 python /app/hello.py
  
    # ✅ venv で十分
python -m venv .venv && source .venv/bin/activate
python hello.py
  

失敗4:requirements.txt のバージョン未指定

    # ❌ バージョン未指定
requests
pandas
numpy
  
    # ✅ バージョンを固定
requests==2.31.0
pandas==2.1.4
numpy==1.26.3
  

さらに良い方法:

    # pip-tools で依存関係を管理
pip install pip-tools

# requirements.in(直接依存のみ)
echo "requests" > requirements.in
echo "pandas" >> requirements.in

# requirements.txt を自動生成(推移的依存も含む)
pip-compile requirements.in
  

失敗5:Docker の volume mount を理解していない

    # ❌ パフォーマンスが悪い
volumes:
  - .:/app  # 全ファイルを同期
  
    # ✅ node_modules / .venv 等は除外
volumes:
  - .:/app
  - /app/.venv  # 無名ボリュームで除外
  - /app/node_modules
  

ベストプラクティス:この構成を覚えておけば迷わない

推奨構成

    .
├── .python-version      # pyenv 用(3.11.7)
├── .venv/               # 仮想環境(git ignore)
├── requirements.in      # 直接依存
├── requirements.txt     # 固定バージョン(pip-compile で生成)
├── Dockerfile           # 本番用(必要な場合のみ)
├── docker-compose.yml   # ローカル開発用(必要な場合のみ)
└── src/
    └── ...
  

プロジェクト開始時のテンプレート

    #!/bin/bash
# setup.sh

# Python バージョンを設定
pyenv install -s 3.11.7
pyenv local 3.11.7

# 仮想環境を作成
python -m venv .venv
source .venv/bin/activate

# pip-tools をインストール
pip install --upgrade pip pip-tools

# 依存関係をインストール
if [ -f requirements.txt ]; then
    pip install -r requirements.txt
fi

echo "環境構築完了: $(python --version)"
  

.gitignore

    # Python
.venv/
__pycache__/
*.py[cod]
*.egg-info/
dist/
build/

# IDE
.vscode/
.idea/

# 環境変数
.env
.env.local
  

使い分け早見表

意思決定フローチャート

    Q1: システムライブラリ(CUDA, OpenCV等)に依存する?
    Yes → Docker
    No  → Q2

Q2: 本番環境と完全に同じ環境が必要?
    Yes → Docker
    No  → Q3

Q3: チーム開発で環境を揃える必要がある?
    Yes(厳密に) → Docker
    Yes(Python版のみ) → pyenv + venv
    No  → Q4

Q4: 複数の Python バージョンを使い分ける?
    Yes → pyenv + venv
    No  → pyenv + venv(それでも推奨)
  

一覧表

状況 pyenv + venv Docker
新規プロジェクト開始
Web API 開発
AI/ML 開発(CPU)
AI/ML 開発(GPU)
データ分析・Jupyter
マイクロサービス
CI/CD パイプライン
レガシーシステム

まとめ:この考え方を覚えておけば迷わない

3つのツールの役割

  1. pyenv = Python バージョン管理

    • 複数バージョンの切り替え
    • プロジェクトごとのバージョン固定
  2. Homebrew = システムツール管理

    • CLI ツールのインストール
    • Python 開発環境としては非推奨
  3. Docker = 環境の完全再現

    • 本番との一致が必要な場合
    • システムライブラリ依存がある場合

基本方針

    1. 迷ったら pyenv + venv から始める
2. 本番環境の再現が必要になったら Docker を導入
3. Homebrew Python は CLI ツール実行用と割り切る
  

Cloud・AI 開発での現実解

    - Lambda / Cloud Functions → pyenv + venv で十分
- ECS / Cloud Run → Docker
- ML 開発(CPU) → pyenv + venv で開発、必要なら Docker でビルド
- ML 開発(GPU) → Docker(nvidia-docker)
  

環境構築で時間を浪費するのは、エンジニアとして最も避けたいことだ。

ツールの思想を理解して、適材適所で使い分ける。

これができれば、「また Python が動かない」問題から解放される。


設計判断の背景

「全部 Docker にすれば統一できる」という意見もあるが、それは理想論だ。macOS での Docker の I/O オーバーヘッド、学習コスト、デバッグの複雑さを考えると、すべてを Docker にするのは現実的ではない。特に高速なイテレーションが必要な開発初期は、pyenv + venv の軽量さが大きなアドバンテージになる。

現場での判断基準

新しいプロジェクトを始めるとき、まず「本番環境で何が動くか」を確認する。Lambda なら pyenv + venv で十分。ECS/Cloud Run なら最初から Docker。この判断を最初にすることで、後から環境を作り直す手間が省ける。

見るべきポイント

他のエンジニアの環境を見るとき、「なぜその構成にしたか」を聞くようにしている。理由なく Homebrew Python を使っていたり、必要ないのに Docker を使っていたりする場合は、ツールの思想を理解していないサインであることが多い。