deploy以下が何を示しているか?
docker-compose.yml にある
services:
test:
image: nvidia/cuda:12.9.0-base-ubuntu22.04
command: nvidia-smi
environment:
- NVIDIA_DISABLE_REQUIRE=1
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
この deploy 以下が何をしているのかを、背景と設計意図を交えて解説します。読み終えたら、GPU を使うサービス定義を自信を持って書ける状態が目標です。
なぜ deploy セクションなのか
もともと deploy は Docker Swarm(オーケストレーション)向けの設定ブロックでした。ただし Compose 仕様では、リソース制御やデバイス予約は deploy.resources に集約・規定されています。現在の Docker Compose(v2 系 CLI)では、単体の Compose 実行でも deploy.resources.reservations.devices が解釈され、GPU 予約に使えるようになっています。
逆に、
deploy内でも Swarm 固有 の項目(replicasなど)は、通常のdocker compose upでは無視されます。GPU 予約は効くが、スケールや配置戦略は効かない——という切り分けを覚えておくと混乱しません。
ツリーの意味(粒度順に)
-
deploy:デプロイ時の振る舞いをまとめる箱。 -
resources:その中で リソース制御(上限limits/最低保証reservations)。 -
reservations:起動時に「これだけは確保して」と プラットフォームに伝える領域。 -
devices:予約したい デバイスのリスト。GPU のような“特殊リソース”をここで要求します。
この構造により、Compose は「CPU/メモリはこのくらい、デバイス(GPU)はこういう条件で」と一括で宣言できます。
devices エントリの各フィールド
devices は配列なので複数種類のデバイスを並べられます。GPU 1 種類なら 1 要素でOK。
-
capabilities: [gpu](必須)- 「GPU という能力を持つデバイスが欲しい」という 抽象条件。これがないと予約が成立しません。
- ベンダー固有能力(例:
["nvidia-compute"])を指定することもできますが、通常は[gpu]で十分です。
-
driver: nvidia- どのドライバ系でそのデバイスを扱うかを指示。NVIDIA GPU なら文字通り
nvidia。 - Docker デーモン側で NVIDIA Container Toolkit が導入済みであることが前提です(
docker infoにRuntimes: ... nvidiaが見える状態)。
- どのドライバ系でそのデバイスを扱うかを指示。NVIDIA GPU なら文字通り
-
count: 1- 予約する GPU の数。整数(1, 2, …)か、
allを指定可能。 - 省略時は実装により “すべて” 振る舞いになるケースがありますが、明示的に書く方が安全です(将来の仕様差異やバグ回避のため)。
- 予約する GPU の数。整数(1, 2, …)か、
-
device_ids(省略中)- どの GPU を使うか ID(0, 1, 2…)でピン留めする方法。
countと 排他 で、同時に書けません。 - 例:
device_ids: ["0", "3"](特定の 2 枚を使う)。
- どの GPU を使うか ID(0, 1, 2…)でピン留めする方法。
-
options(省略中)- ドライバ固有の追加オプション。通常は不要です。
実際に起きていること:Compose は要求に合う GPU を選定し、NVIDIA ランタイム経由で *必要なデバイスノード(/dev/nvidia)やライブラリ**をコンテナへ渡すよう Docker に指示します。
reservations と limits の違い
-
reservationsは「最低限確保」の宣言。GPU のように“有るか無いか”のリソースは、まずここで確保します。 -
limitsは「上限」。CPU やメモリで使いますが、GPU の 性能上限を絞る手段ではない ことに注意(GPU は個数や ID で管理するのが基本)。
代替・旧来の書き方
-
runtime: nvidia(サービス直下)- 古いやり方。動く環境もありますが、細かい指定(複数 GPU の選択等)ができず、将来性も低め。
-
環境変数(
NVIDIA_VISIBLE_DEVICESなど)- ランタイム層が解釈するトグルですが、Compose 的には
devicesでの宣言が第一級。補助的に使う程度が無難です。
- ランタイム層が解釈するトグルですが、Compose 的には
NVIDIA_DISABLE_REQUIRE=1 は何者?
environment のこの変数は ドライバ要件チェック(requirement check)を無効化します。たとえば、コンテナが CUDA 12.9 を要求しているのに、ホストドライバが 12.8 相当しか満たさない場合、本来はエラーで止まります。そこで一時的にこのチェックを外すと、起動だけはできる——という裏技です。
- ベストプラクティスは 使わない こと。実アプリで CUDA 依存 API を叩いた瞬間に落ちたり、未定義動作になる恐れがあります。
- 正道は ホストのドライバを上げるか、コンテナの CUDA バージョンを下げる(ドライバが満たす最小要件以下に合わせる)ことです。
実務 Tips(ハマりどころ回避)
-
デーモン準備:
nvidia-container-toolkit導入後にsudo nvidia-ctk runtime configure --runtime=docker→ Docker 再起動。docker infoにnvidiaが必ず見える状態で。 -
capabilities は必ず指定:
capabilities: [gpu]を忘れると予約できません。 -
countとdevice_idsは排他:両方書くとエラー。どちらかに統一。 -
CUDA 互換を意識:
nvidia-smiの “CUDA Version”(ホスト側の上限)≧ コンテナの CUDA。ズレるならイメージタグを見直す。 -
Compose と Swarm の境界:
deployに書いても、Swarm 専用の項目はdocker compose upでは効きません。GPU 予約は効く——この二層構造を理解しておく。
まとめ
-
最小構成は本記事の例そのまま:
-
driver: nvidia/capabilities: [gpu]/count: 1
-
-
特定 GPU を使いたいなら
device_ids: ["0"](countは外す)。 -
複数枚使いたいなら
count: N。台数が可変ならallでもよいが、再現性の観点では 固定数 or ID 指定が安心。 -
互換エラーを踏み抜かない:ホストのドライバを上げる or コンテナの CUDA を下げる。
NVIDIA_DISABLE_REQUIRE=1は最終手段のスモークテスト用。
これで deploy.resources.reservations.devices の意図と効果が掴めたはず。あとはあなたのワークロード(PyTorch / TensorRT / OpenCV など)に合わせて、イメージタグと GPU 個数・ID を調整していきましょう。