問題の概要:Docker ComposeによるAI環境構築で発生する典型的な課題
AI開発、特に機械学習や深層学習のプロジェクトでは、Pythonバージョン、CUDA/cuDNN、各種ライブラリ(TensorFlow, PyTorch, scikit-learnなど)の依存関係が複雑で、環境構築に多くの時間を費やしてしまいます。DockerとDocker Composeを使えば、これらの環境をコード(Dockerfileとdocker-compose.yml)で定義し、一括で再現可能な環境を構築できます。
しかし、特に初心者や中級者の方がこのテンプレートを利用する際、以下のようなエラーや課題に直面することが少なくありません。
- ビルドエラー:
docker-compose up --build実行時にDockerfile内のコマンドが失敗する。 - ポート競合: Jupyter NotebookやTensorBoard用のポートが既に使用されていてコンテナが起動しない。
- GPU認識エラー: NVIDIA Dockerの設定が不十分で、コンテナ内からGPUが利用できない。
- ボリュームマウントの問題: ホストマシンのコードやデータがコンテナ内で見えない、またはパーミッションエラーが発生する。
- メモリ不足: コンテナが起動直後に
Killedステータスで終了する。
本記事では、これらの課題を解決し、スムーズにAI開発環境を構築するための実践的なトラブルシューティングガイドを提供します。
原因の解説:なぜこれらの問題が起こるのか?
上記の問題は、主に以下の原因から発生します。
1. ベースイメージと依存関係の不整合
Dockerfileで指定するベースイメージ(例: nvidia/cuda:12.1.1-cudnn8-runtime-ubuntu22.04)と、その中でインストールしようとするPythonパッケージのバージョンに互換性がない場合、pip installが失敗します。特に、CUDAバージョンとPyTorch/TensorFlowのバージョンは厳密な対応関係があります。
2. ホスト環境のリソース制限と設定
Dockerデーモンはホストマシンのリソース(CPU、メモリ、GPU)を利用します。デフォルトのリソース制限が低すぎたり、NVIDIA Container Toolkitが正しくインストールされていなかったりすると、コンテナは期待通りに動作しません。
3. ネットワークとボリュームの設定ミス
docker-compose.yml内のports設定で既に使用中のホストポートを指定すると競合が発生します。また、volumes設定で相対パスを指定した場合、docker-composeを実行するディレクトリによってマウントされるパスが変わり、混乱の元となります。
解決方法:ステップバイステップで安定した環境を構築
ステップ1: プロジェクト構造の作成
まず、以下のような標準的なプロジェクト構造を作成します。これがテンプレートの基礎となります。
your_ai_project/
├── docker-compose.yml
├── Dockerfile
├── requirements.txt
├── scripts/ # エントリポイントスクリプトなど
├── src/ # アプリケーションコード
├── data/ # データセット(.gitignore対象)
└── notebooks/ # Jupyter Notebooks
ステップ2: Dockerfileの作成と依存関係の固定
互換性のあるバージョンを明示的に指定したDockerfileを作成します。
# Dockerfile
# CUDA 12.1 + PyTorch 2.1 互換のベースイメージを選択
FROM nvidia/cuda:12.1.1-cudnn8-runtime-ubuntu22.04
# システムパッケージのインストールとタイムゾーン設定
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y
python3-pip
python3-dev
git
curl
&& rm -rf /var/lib/apt/lists/*
&& ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# 作業ディレクトリの設定
WORKDIR /workspace
# 依存関係を先にコピーしてキャッシュを効かせる
COPY requirements.txt .
# pipのアップグレードと依存関係のインストール
RUN pip3 install --no-cache-dir --upgrade pip
&& pip3 install --no-cache-dir -r requirements.txt
# ソースコードをコピー
COPY src/ ./src
COPY notebooks/ ./notebooks
# Jupyter Labのデフォルトポートを公開
EXPOSE 8888
# コンテナ起動時のデフォルトコマンド(docker-compose.ymlで上書き可能)
CMD ["jupyter", "lab", "--ip=0.0.0.0", "--port=8888", "--no-browser", "--allow-root", "--NotebookApp.token=''"]
ポイント: requirements.txtではバージョンを固定します。
# requirements.txt
torch==2.1.2+cu121 --index-url https://download.pytorch.org/whl/cu121
torchvision==0.16.2+cu121 --index-url https://download.pytorch.org/whl/cu121
tensorflow==2.15.0
jupyterlab==4.0.11
pandas==2.2.0
scikit-learn==1.4.0
matplotlib==3.8.2
ステップ3: docker-compose.ymlの設定とリソース制限
サービス、ボリューム、ネットワーク、リソース制限を定義します。
# docker-compose.yml
version: '3.8'
services:
ai-dev:
build: .
container_name: ai_development_env
# ホストマシンのコードやデータをコンテナにマウント
volumes:
- ./src:/workspace/src
- ./notebooks:/workspace/notebooks
- ./data:/workspace/data
ports:
- "8888:8888" # Jupyter Lab
- "6006:6006" # TensorBoard (必要に応じて)
# 環境変数
environment:
- PYTHONPATH=/workspace/src
- TZ=Asia/Tokyo
# コンテナ内でroot以外のユーザーで実行したい場合(ファイルパーミッション問題対策)
# user: "${UID}:${GID}"
# リソース制限の設定(メモリ不足対策)
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
limits:
memory: 8G
cpus: '4.0'
# コンテナ起動後、インタラクティブシェルを維持
stdin_open: true
tty: true
# ホストマシンが再起動してもコンテナを自動起動(任意)
# restart: unless-stopped
ステップ4: ビルドと起動、およびトラブルシューティング
実際に環境を構築し、問題に対処します。
1. ビルド実行:
# プロジェクトルートで実行
docker-compose up --build
エラー例1: ERROR: Could not find a version that satisfies the requirement torch==x.x.x
解決策: requirements.txtのPyTorch/TensorFlowのバージョンとCUDAバージョンの互換性を確認します。PyTorchの公式サイトで正しい--index-urlを確認・修正してください。
エラー例2: Ports are not available: listen tcp 0.0.0.0:8888: bind: address already in use
解決策: ホスト側のポート8888を使用しているプロセスを終了するか、docker-compose.ymlのポートマッピングを変更します(例: "8899:8888")。
# ポート8888を使用しているプロセスを確認
sudo lsof -i:8888
# プロセスを終了(PIDを指定)
kill -9 [PID]
エラー例3: docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]].
解決策: NVIDIA Container Toolkitがインストールされていません。以下のコマンドでインストールと設定を行います。
# NVIDIA Container Toolkitのインストール(Ubuntu例)
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker
# インストール確認
docker run --rm --gpus all nvidia/cuda:12.1.1-base-ubuntu22.04 nvidia-smi
エラー例4: コンテナ起動後、すぐにKilled状態になる。
解決策: コンテナのメモリ制限がホストの空きメモリを超えているか、docker-compose.ymlのdeploy.resources.limits.memory設定が大きすぎます。ホストの空きメモリを確認し、制限値を下げてみてください。
# ホストのメモリ使用状況を確認
free -h
# docker-compose.ymlのmemory設定を4Gなどに減らす
ステップ5: 環境の確認と使用
無事に起動したら、以下のコマンドで環境を確認・使用します。
# 起動中のコンテナに入ってシェルを実行(別ターミナルで)
docker-compose exec ai-dev bash
# コンテナ内でPythonを実行し、GPUとライブラリを確認
python3 -c "import torch; print(torch.__version__); print(torch.cuda.is_available())"
python3 -c "import tensorflow as tf; print(tf.__version__); print(tf.config.list_physical_devices('GPU'))"
# コンテナのログを確認
docker-compose logs -f ai-dev
# 環境を停止
docker-compose down
# 停止し、ボリュームも含めて完全にクリーンアップ(データは消えるので注意)
docker-compose down -v
まとめ・補足情報
Docker Composeを使ったAI開発環境のテンプレート構築は、最初の設定に少し手間がかかりますが、一度正しく構築してしまえば、チームメンバー全員が全く同じ環境を瞬時に再現でき、依存関係の問題から解放されます。本記事で紹介したテンプレートとトラブルシューティング手順は、多くのプロジェクトで応用可能な基本形です。
さらに発展させるためのヒント:
- マルチステージビルド: 最終的なランタイムイメージを軽量化するために、ビルド用と実行用のイメージを分離できます。
- 環境変数ファイル:
.envファイルを作成し、docker-compose.yml内で${変数名}として参照することで、設定の切り替え(開発/本番)を容易にします。 - 複数サービス: Jupyter Lab用、APIサーバー用、データベース用など、複数のサービスを
docker-compose.yml内で定義し、連携させることができます。 - Dockerキャッシュの活用:
Dockerfileでは変更頻度の低いレイヤー(システムパッケージインストール)を上に、頻度の高いレイヤー(ソースコードコピー)を下に配置することで、ビルド時間を短縮できます。
このテンプレートをベースに、プロジェクトの要件に合わせてカスタマイズを加え、効率的でストレスのないAI開発環境を構築してください。