【Docker/環境】Docker ComposeでAI開発環境を一括構築!よくあるエラーと解決法

問題の概要:Docker ComposeによるAI環境構築で発生する典型的な課題

AI開発、特に機械学習や深層学習のプロジェクトでは、Pythonバージョン、CUDA/cuDNN、各種ライブラリ(TensorFlow, PyTorch, scikit-learnなど)の依存関係が複雑で、環境構築に多くの時間を要します。Docker Composeを用いることで、複数のサービス(JupyterLab, PostgreSQL, Redisなど)を含む統合開発環境を一括で構築できますが、その過程で以下のようなエラーに遭遇することが頻繁にあります。

  • ERROR: Couldn't connect to Docker daemon at http+docker://localhost - is it running?
  • ERROR: for web Cannot start service web: driver failed programming external connectivity on endpoint ...: Bind for 0.0.0.0:8888 failed: port is already allocated
  • ビルド中のERROR: Failed to build PyTorch: Could not find a version that satisfies the requirement torch==1.9.0 のようなパッケージインストールエラー
  • GPUがコンテナ内で認識されない(torch.cuda.is_available()がFalseを返す)
  • ボリュームマウントによるパーミッションエラー:Permission denied: '/home/jovyan/work'

これらの問題は、Dockerの基本設定、ネットワーク競合、イメージのビルド設定、GPUドライバの互換性など、様々な要因に起因します。本記事では、実用的なdocker-compose.ymlテンプレートを基に、これらの課題を体系的に解決する方法を解説します。

原因の解説:なぜエラーが発生するのか?

上記のエラーは、主に以下の4つのカテゴリに分類され、それぞれ根本原因が異なります。

1. Dockerデーモン関連エラー

Dockerエンジン(デーモン)が起動していない、またはユーザーがdockerグループに所属していないために発生します。Dockerはクライアント・サーバーアーキテクチャを採用しており、docker-composeコマンドはクライアントとしてデーモンと通信します。

2. ポート・ネットワーク競合

ホストマシン(ローカルPC)の特定のポート(例: 8888, 5432)が既に他のプロセス(以前のコンテナ、ローカルサーバーなど)によって使用されている場合、新しいコンテナはそのポートにバインドできません。

3. イメージビルド時の依存関係解決失敗

Dockerfile内のRUN pip install ...コマンドで、指定したバージョンのパッケージが存在しない、または互換性のないバージョンのPythonやOS環境に対してビルドを試みている場合に発生します。特に、CUDAバージョンとPyTorch/TensorFlowバージョンの組み合わせは厳密です。

4. GPU認識とボリュームパーミッション問題

NVIDIA Container Toolkitが適切にインストール・設定されていない、またはdocker-compose.ymlでGPUリソースの宣言が不足していると、コンテナ内からGPUを利用できません。また、ホストOSとコンテナ内のユーザーID(UID)・グループID(GID)が一致しないと、マウントしたディレクトリへの書き込み権限でエラーが発生します。

解決方法:ステップバイステップでの環境構築とトラブルシューティング

ステップ1: 事前準備とDockerデーモンの確認

まず、Docker EngineとDocker Composeがインストールされていることを確認します。さらに、GPUを使用する場合はNVIDIA Container Toolkitのインストールが必須です。

# Dockerデーモンの状態確認と起動
sudo systemctl status docker
# 起動していない場合
sudo systemctl start docker
# ユーザーをdockerグループに追加(現在のセッションにはログアウト/再ログインが必要)
sudo usermod -aG docker $USER

# Docker Compose バージョン確認
docker-compose --version
# または Docker Compose V2
docker compose version

# NVIDIA Container Toolkit 確認(GPU利用時)
nvidia-ctk --version

ステップ2: プロジェクト構成とdocker-compose.ymlの作成

以下のようなディレクトリ構成を前提に、AI開発環境用のdocker-compose.ymlDockerfileを作成します。

my-ai-project/
├── docker-compose.yml
├── Dockerfile
├── requirements.txt
└── workspace/  # ホストとコンテナで共有する作業ディレクトリ

Dockerfile (例):

FROM nvidia/cuda:12.1.1-cudnn8-runtime-ubuntu22.04

# システムパッケージのインストールとユーザー作成
RUN apt-get update && apt-get install -y 
    python3-pip 
    python3-dev 
    git 
    curl 
    && rm -rf /var/lib/apt/lists/* 
    && useradd -m -u 1000 -s /bin/bash ai-user

WORKDIR /app
USER ai-user

# 依存関係のコピーとインストール
COPY --chown=ai-user:ai-user requirements.txt .
RUN pip3 install --no-cache-dir --upgrade pip 
    && pip3 install --no-cache-dir -r requirements.txt

# 作業ディレクトリ設定
WORKDIR /home/ai-user/workspace

docker-compose.yml (テンプレート):

version: '3.8'

services:
  ai-lab:
    build: .
    container_name: my-ai-lab
    # ポートマッピング (ホスト:コンテナ)。競合時は左側を変更(e.g., "8890:8888")
    ports:
      - "8888:8888"
    # ボリュームマウント。ホストの./workspaceをコンテナ内にマウント
    volumes:
      - ./workspace:/home/ai-user/workspace
      - ~/.gitconfig:/home/ai-user/.gitconfig:ro # Git設定の共有(オプション)
    # GPUサポートの有効化(NVIDIA Container Toolkit必須)
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
    # 環境変数(JupyterLab用)
    environment:
      - JUPYTER_ENABLE_LAB=yes
      - GRANT_SUDO=yes
    # コンテナ起動時のデフォルトコマンド(JupyterLab)
    command: jupyter lab --ip=0.0.0.0 --port=8888 --no-browser --allow-root --NotebookApp.token=''
    # ホストと同じネットワークを利用(コンテナ名でサービス間通信可能に)
    networks:
      - ai-network

  # 必要に応じて追加サービス(例: PostgreSQL)
  # db:
  #   image: postgres:15
  #   environment:
  #     POSTGRES_PASSWORD: example
  #   volumes:
  #     - postgres_data:/var/lib/postgresql/data
  #   networks:
  #     - ai-network

# 名前付きボリュームとネットワークの定義
# volumes:
#   postgres_data:
networks:
  ai-network:
    driver: bridge

requirements.txt (例):

jupyterlab==4.0.10
numpy==1.24.3
pandas==2.0.3
scikit-learn==1.3.0
matplotlib==3.7.2
seaborn==0.12.2
# PyTorch (CUDA 12.1用)
torch==2.1.0+cu121 --index-url https://download.pytorch.org/whl/cu121
torchvision==0.16.0+cu121 --index-url https://download.pytorch.org/whl/cu121
torchaudio==2.1.0+cu121 --index-url https://download.pytorch.org/whl/cu121
# または TensorFlow
# tensorflow[and-cuda]==2.13.0

ステップ3: ビルドと起動、およびエラー対応

実際に環境を構築し、発生する可能性のあるエラーに対処します。

# 1. イメージのビルド
docker-compose build
# エラー例: `ERROR: Could not find a version that satisfies the requirement torch==x.x.x`
# → requirements.txt内のパッケージバージョンやインデックスURLを確認。PyTorch公式の互換性表を参照。

# 2. サービスの起動
docker-compose up -d
# エラー例: `Bind for 0.0.0.0:8888 failed: port is already allocated`
# → ホストのポート8888が使用中。以下のいずれかで解決。
#    a) 使用中のプロセスを停止: `sudo lsof -i:8888` でプロセスを確認し、killする。
#    b) docker-compose.ymlのports設定を変更: `"8890:8888"`など別ポートに変更。

# 3. ログの確認(起動に失敗した場合)
docker-compose logs ai-lab

# 4. コンテナ内でのGPU確認
docker-compose exec ai-lab python3 -c "import torch; print(torch.cuda.is_available())"
# Falseが返る場合:
# - ホストのGPUドライバ、NVIDIA Container Toolkitを再確認。
# - `docker-compose.yml`の`deploy`セクションが正しく記述されているか確認。
# - ベースイメージのCUDAバージョンとホストドライバの互換性を確認。

# 5. ボリュームのパーミッションエラー対応
# コンテナ内ユーザー(UID=1000)とホストのワークスペース所有者が異なる場合、書き込み不可になることがある。
# 解決策: ホスト側でワークスペースの所有者を変更、またはDockerfileの`useradd`のUIDをホストユーザーのUIDに合わせる。
sudo chown -R 1000:1000 ./workspace

ステップ4: 日常的な操作コマンド

# サービスの状態確認
docker-compose ps

# サービス停止(コンテナ削除)
docker-compose down

# 停止したコンテナ、未使用のイメージ、キャッシュを削除(ディスククリーンアップ)
docker-compose down --rmi all --volumes
docker system prune -a

# コンテナ内でインタラクティブシェルを実行
docker-compose exec ai-lab /bin/bash

まとめ・補足情報

Docker Composeを用いたAI開発環境の一括構築は、再現性、依存関係の分離、チーム間での環境統一に極めて有効です。本記事で紹介したテンプレートとトラブルシューティング手順は、多くの一般的な問題をカバーしています。

重要な補足ポイント:

  • ベースイメージの選択: nvidia/cudaイメージはタグでCUDA/cuDNNバージョンとOSを指定します。軽量な-runtimeか開発用の-develかを用途で選択しましょう。
  • セキュリティ: 本記事の例では簡便さのためJupyterのトークンを無効化していますが、本番環境やインターネットに公開する場合は、強力なパスワードやトークンの設定、リバースプロキシとの連携が必須です。
  • パフォーマンス: ボリュームマウントは開発時のコード編集に便利ですが、大量の小ファイル読み書きではオーバーヘッドが発生する場合があります。学習用データセットなどは、コンテナ内にコピーするか、別途最適化されたデータボリュームを検討しましょう。
  • 拡張性: docker-compose.override.ymlファイルを作成することで、開発用と本番用の設定を分離して管理できます。

このテンプレートを出発点として、プロジェクト固有のサービス(データベース、メッセージキュー、MLflowなどの実験管理ツール)を追加し、自分だけの最適なAI開発環境を構築してください。Docker Composeは、複雑なAIスタックの管理を単純化する強力なツールです。

この記事は役に立ちましたか?