nvidia-dockerをdocker-composeで動かす(ver3系)

## はじめに

docker-composeでGPUコンテナを動かしたいが、
公式の通りに書くときちんと読み込んでくれず、、
現状ググるとver2系の書き方ばかりでver3系は全く無く、、
と割と詰まったので、他の人が詰まらないようここに共有。

- 動作環境
    - OS: Ubuntu 20.04.2 LTS (focal)
    - GPU: GeForce GTX 960
- 前提
    - GPUドライバはインストール済み
        - 参考: [ubuntu20.04にNVIDIA GPUドライバをインストール](https://qiita.com/routerman/items/99083317a69fd846c54f)
    - docker, docker-composeはインストール済み
    - nvidia-docker-runtimeはインストール済み
        - 参考: [Ubuntu20.04にnvidia-docker runtimeをインストールする](https://qiita.com/routerman/items/327df977402f0cede0cc)

## docker-compose.yamlの書き方例（ver3系）

```docker-compose.yaml
version: '3.8'
services:
  sample:
    image: nvidia/cuda:11.2.1-base
    command: nvidia-smi
    deploy:
      resources:
        reservations:
          devices:
           - driver: nvidia
             capabilities: [utility, compute, video]
```

各パラメータの詳細は公式を参考に.

https://docs.docker.com/compose/gpu-support/

## 動作確認

```terminal
$ docker-compose version
docker-compose version 1.28.5, build unknown
:
$ docker-compose up
Starting sample_sample_1 ... done
Attaching to sample_sample_1
sample_1  | Mon Mar 15 10:05:43 2021       
sample_1  | +-----------------------------------------------------------------------------+
sample_1  | | NVIDIA-SMI 460.39       Driver Version: 460.39       CUDA Version: 11.2     |
sample_1  | |-------------------------------+----------------------+----------------------+
sample_1  | | GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
sample_1  | | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
sample_1  | |                               |                      |               MIG M. |
sample_1  | |===============================+======================+======================|
sample_1  | |   0  GeForce GTX 960     Off  | 00000000:0E:00.0 Off |                  N/A |
sample_1  | | 30%   53C    P2    38W / 130W |    652MiB /  4042MiB |     46%      Default |
sample_1  | |                               |                      |                  N/A |
sample_1  | +-------------------------------+----------------------+----------------------+
sample_1  |                                                                                
sample_1  | +-----------------------------------------------------------------------------+
sample_1  | | Processes:                                                                  |
sample_1  | |  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
sample_1  | |        ID   ID                                                   Usage      |
sample_1  | |=============================================================================|
sample_1  | +-----------------------------------------------------------------------------+
sample_sample_1 exited with code 0
```

## docker-composeのバージョンに注意

docker-composeのバージョンが古い場合、以下のようなエラーが出る.

```terminal
$ docker-compose version
docker-compose version 1.25.0, build unknown
:
$ docker-compose up
ERROR: The Compose file './docker-compose.yaml' is invalid because:
services.sample.deploy.resources.reservations value Additional properties are not allowed ('devices' was unexpected)
```

[docker-composeのGitHub](https://github.com/docker/compose/releases/tag/1.28.0) によると、1.28から上の書き方に対応した模様.

(作者はaptで入れたら1.25だったので、とりあえずpipで入れなおしました)

## ver2系（おまけ）

ちなみに、ver2系では以下のように書く.

```docker-compose.yaml
version: '2.4'
services:
  sample:
    image: nvidia/cuda:11.2.1-base
    command: nvidia-smi
    runtime: nvidia
    environment:
      NVIDIA_VISIBLE_DEVICES: all
      NVIDIA_DRIVER_CAPABILITIES: utility,compute,video
```

ただし、ver2系ではreplicas等がサポートされていない.
あと、コンテナのために環境変数 NVIDIA_* を入れるのも気持ち悪い（個人の感想です）.
なので、どんどんver3形式で書いていきましょう.