2026年7月29日
2026年7月29日
DockerでNVIDIA GPUを使う方法|Container Toolkitの導入・–gpus・Composeの書き方とエラー対処
DockerのコンテナからNVIDIA GPUを使うには、ホストにNVIDIAドライバーと「NVIDIA Container Toolkit」を入れ、docker run --gpus all のようにGPUを渡して起動します。コンテナの中にドライバーを入れる必要はありません。この記事では、Linuxサーバーでの導入手順、GPUを指定して起動する方法、Docker Composeでの書き方、よく出るエラーの読み方と直し方を順に説明します。
内容はUbuntu系のLinuxとDocker Engine、NVIDIA Container Toolkitの安定版(2026年10月現在)を前提にしています。パッケージのリポジトリや細かい手順は変わることがあるため、実際に作業するときはNVIDIAの公式ドキュメント(NVIDIA Container Toolkitのインストールガイド)もあわせて確認してください。
仕組みを先に押さえる
GPUを使うコンテナでつまずく原因の多くは、「どこに何が入っている必要があるか」の取り違えです。役割は次のように分かれています。
- ホストのNVIDIAドライバー:GPUを動かす本体です。コンテナはホストのドライバーを共有して使います。
- NVIDIA Container Toolkit:コンテナ起動時に、ホストのドライバーのライブラリやデバイスファイルをコンテナへ受け渡す仕組みです。
- コンテナイメージ内のCUDAライブラリ:CUDAのランタイムやcuDNN、PyTorchなどのフレームワークはイメージ側に入れます。
ホストにCUDA Toolkitを入れる必要は基本的にありません。逆に、イメージの中にNVIDIAドライバーを入れるのは誤りで、ホストのドライバーと食い違って動かなくなる原因になります。
手順1:ホストでGPUとドライバーを確認する
まずホストそのものでGPUが見えているかを確かめます。ここで失敗する場合、Docker側の設定をいくら直しても動きません。
nvidia-smi
GPUの名前、ドライバーのバージョン、右上に「CUDA Version」が表示されれば準備ができています。この「CUDA Version」は、そのドライバーが対応できるCUDAの上限を示しています。後でイメージを選ぶときの基準になるので控えておきます。
nvidia-smi が見つからない、または「NVIDIA-SMI has failed」と出る場合は、ドライバーが入っていないか読み込まれていません。Ubuntuでは ubuntu-drivers コマンドや、NVIDIAが配布するパッケージで導入します。ドライバーの更新後は再起動が必要です。
手順2:NVIDIA Container Toolkitを入れる
NVIDIAのリポジトリを登録して、nvidia-container-toolkit パッケージをインストールします。以下は公式ガイドに沿ったapt系の例です。
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
| sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
| sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \
| sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
続いて、DockerがNVIDIAのランタイムを使えるように設定し、Dockerを再起動します。
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
nvidia-ctk runtime configure は /etc/docker/daemon.json にNVIDIAランタイムの設定を書き加えます。すでに独自の daemon.json を使っている場合は、実行前にファイルをバックアップし、実行後に中身を確認しておくと安心です。本番サーバーで作業する場合は、動いているコンテナがDockerの再起動で止まる点にも注意してください(restart ポリシーを付けていないコンテナは自動では戻りません)。
手順3:動作確認のコンテナを起動する
公式ガイドの確認方法は、普通のUbuntuイメージで nvidia-smi を実行するものです。Container Toolkitが nvidia-smi とドライバーのライブラリをコンテナに渡すため、CUDA入りのイメージでなくても表示されます。
sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi
ホストで実行したときと同じGPUの一覧が出れば成功です。--runtime=nvidia は環境によっては省略しても動きますが、うまくいかないときの切り分けとして付けておくと分かりやすくなります。
GPUの指定方法
--gpus には、渡すGPUの数や番号を指定できます。
# すべてのGPU
docker run --rm --gpus all ubuntu nvidia-smi
# 2枚だけ(どれが選ばれるかは指定しない)
docker run --rm --gpus 2 ubuntu nvidia-smi
# 番号で指定(カンマ区切りは引用符の二重化が必要)
docker run --rm --gpus device=0 ubuntu nvidia-smi
docker run --rm --gpus '"device=0,1"' ubuntu nvidia-smi
複数枚の番号を指定するときに引用符を二重にするのは、カンマがオプションの区切りと解釈されないようにするためです。ここを1重にすると「invalid argument」系のエラーになります。
番号は構成によっては期待と違う並びに見えることがあります。どのGPUが渡ったかは、コンテナ内で nvidia-smi -L を実行してUUIDで確かめます。
Docker Composeでの書き方
Composeでは、サービスの deploy.resources.reservations.devices にGPUを書きます。
services:
ollama:
image: ollama/ollama
ports:
- "127.0.0.1:11434:11434"
volumes:
- ollama:/root/.ollama
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all # 1 にすると1枚だけ
capabilities: [gpu]
restart: unless-stopped
volumes:
ollama:
特定のGPUを使う場合は count の代わりに device_ids: ["0"] を書きます。count と device_ids は同時には指定できません。capabilities は省略するとエラーになるため、[gpu] を明記します。新しめのComposeではサービス直下に gpus を書く短い形式も使えるようになっていますが、対応するバージョンが限られるため、互換性を重視するなら上の書き方が無難です。
この例はローカルLLMを動かすOllamaです。WordPressの記事下書きやタグ付けの補助にローカルLLMを使う構成で、よく見かける組み合わせです。ポートを 127.0.0.1: 付きで公開しているのは、認証のないAPIをインターネットに開けないためです。外部から使う場合は、リバースプロキシで認証やアクセス元の制限をかけてください。
よくあるエラーと対処
エラーメッセージを読めば、どの層で止まっているかがおおむね判断できます。起きやすい順に挙げます。
could not select device driver “” with capabilities: [[gpu]]
DockerがGPUを渡す仕組みを見つけられていません。Container Toolkitが入っていないか、入れた後にDockerを再起動していないのが主な原因です。dpkg -l | grep nvidia-container-toolkit でパッケージを確認し、手順2の nvidia-ctk runtime configure と再起動をやり直します。Docker Desktop(Linux版)やSnap版のDockerなど、標準とは別の場所でデーモンが動いている場合は、設定ファイルの場所が異なるため公式ドキュメントでそれぞれの手順を確認します。
Failed to initialize NVML: Driver/library version mismatch
ホストのドライバーを更新したのに再起動していないときによく出ます。読み込まれているカーネルモジュールと、ディスク上のライブラリのバージョンが食い違っている状態です。ホストを再起動すれば直ることがほとんどです。自動更新でドライバーが上がることもあるため、GPUサーバーではドライバーのパッケージを固定しておく運用も検討します。
CUDA driver version is insufficient for CUDA runtime version
イメージに入っているCUDAが、ホストのドライバーが対応する上限より新しい場合に出ます。手順1で控えた「CUDA Version」と、イメージのCUDAのバージョン(nvidia/cuda イメージならタグに含まれます)を比べてください。対処は、ドライバーを上げるか、対応範囲内のCUDAを使ったイメージに変えるかのどちらかです。
起動直後は動くが、しばらくするとGPUが見えなくなる
コンテナの中で nvidia-smi が「Failed to initialize NVML: Unknown Error」を返すようになる現象は、ホストで systemctl daemon-reload などが実行されたときにデバイスの権限が外れることで起きる既知の問題として報告されています。Container Toolkitの更新や、CDI(Container Device Interface)方式への切り替えで解消できる場合があります。対処法はバージョンによって変わるため、NVIDIAのドキュメントのトラブルシューティングの項目を確認してください。rootlessモードのDockerも別の設定が必要なので、まず通常のDockerで動作を確かめてから移ると切り分けが楽です。
Windows(WSL 2)とmacOSの場合
WindowsではDocker DesktopのWSL 2バックエンドでNVIDIA GPUを使えます。このときドライバーはWindows側に入れ、WSL 2のLinuxの中にはLinux用のNVIDIAドライバーを入れません。WSLの中でLinux用ドライバーを入れると、Windows側から提供されるライブラリを上書きして動かなくなることがあります。
macOSのDocker DesktopはLinuxの仮想マシンの上で動くため、NVIDIA GPUをコンテナに渡す使い方はできません。
運用で気をつけること
- **GPUメモリは
--memoryでは制限されない**:--memoryや--cpusはホストのメモリとCPUの上限で、GPUのメモリ(VRAM)は対象外です。1枚のGPUを複数のコンテナで共有すると、VRAMの取り合いで片方が落ちることがあります。用途ごとにGPUを分けるのが分かりやすい方法です。 - イメージのサイズ:CUDA入りのイメージは数GBになることがあります。実行だけなら
devel系よりruntime系やbase系が小さく済みます。 - ドライバー更新は計画的に:ドライバーを上げると再起動が必要で、対応するCUDAの範囲も変わります。検証環境で先に試してから本番に適用します。
まとめ
- コンテナでGPUを使うには、ホストのNVIDIAドライバーとNVIDIA Container Toolkitが必要で、コンテナにはドライバーを入れない。
nvidia-ctk runtime configure --runtime=dockerの後にDockerを再起動し、docker run --rm --gpus all ubuntu nvidia-smiで確認する。- GPUの指定は
--gpus all、--gpus 2、--gpus '"device=0,1"'。Composeではdeploy.resources.reservations.devicesにdriver: nvidiaとcapabilities: [gpu]を書く。 - エラーは「Toolkitの未導入・未再起動」「ドライバー更新後の未再起動」「CUDAとドライバーの不一致」の順に疑う。
- 認証のないAPI(Ollamaなど)は
127.0.0.1に限定して公開する。