NVIDIAが入っているPCにおいてdocker上でopenGLなプログラムを起動して手元で見る．nvidia-dockerのversion1と2の両方に対応．

| nvidia-dockerのversion | xeyes | glxgears |
| --- | --- | --- |
| ver 1 | ![image.png](https://qiita-image-store.s3.amazonaws.com/0/25325/f118f169-c2ea-55ee-b664-4628af37c877.png) | ![image.png](https://qiita-image-store.s3.amazonaws.com/0/25325/bb1c0428-01dd-d046-b8f5-86a63888eaad.png) |
| ver 2 | ![image.png](https://qiita-image-store.s3.amazonaws.com/0/25325/404a000f-ba6a-df7d-4fdf-a7e8df3a23c3.png) | ![image.png](https://qiita-image-store.s3.amazonaws.com/0/25325/4fa86ac1-d328-e3b2-da96-ee40e46ba655.png) |

docker上でGUIを起動して手元で確認したいときにハマった＋最小限構成で動くやり方が見当たらなかったのでメモ．

OpenGLが入ってくるか来ないかで話は変わる．
また，NVIDIAがインストールされていないPCであれば簡単だったらしい．

## TL;DR

#### nvidia-dockerのversionが2の場合

```dockerfile:Dockerfile
FROM ubuntu:18.04

# nvidia-container-runtime
ENV NVIDIA_VISIBLE_DEVICES ${NVIDIA_VISIBLE_DEVICES:-all}
ENV NVIDIA_DRIVER_CAPABILITIES ${NVIDIA_DRIVER_CAPABILITIES:+$NVIDIA_DRIVER_CAPABILITIES,}graphics

# install GLX-Gears
RUN apt update && apt install -y --no-install-recommends mesa-utils x11-apps && rm -rf /var/lib/apt/lists/*
```

#### nvidia-dockerのversionが1の場合
```dockerfile:Dockerfile
FROM ubuntu:18.04

LABEL com.nvidia.volumes.needed="nvidia_driver"
ENV PATH /usr/local/nvidia/bin:${PATH}
ENV LD_LIBRARY_PATH /usr/local/nvidia/lib:/usr/local/nvidia/lib64:${LD_LIBRARY_PATH}

RUN apt-get update && apt-get install -y --no-install-recommends mesa-utils x11-apps \
&& rm -rf /var/lib/apt/lists/*
```

```bash
xhost +
sudo docker build -t gl_test .

# nvidia-dockerがversion 1の場合
# nvidia-docker run --rm -it --env="DISPLAY" --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" gl_test glxgears

# nvidia-dockerがversion 2の場合
docker run --runtime=nvidia --rm -it --env="DISPLAY" --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" gl_test glxgears
```

これでOK．
nvidia-dockerというのを使うらしい．

---
以下詳細
---

2018/09/26 追記

nvidia-dockerのversionが1か2かで大分話が変わってしまう＋最近移行期なので，version1を入れている人もいれば2を入れている人もいる．知らないと結構ハマる．2がオススメ．
2だとvolumeとかがなくなる．

2のインストール方法および1が入っている環境から2に移行する方法は

- https://github.com/nvidia/nvidia-docker/wiki/Installation-(version-2.0)

に載っている．

## `xeyes`だけなら簡単

これはnvidia-dockerは要らなくて，普段と変わって必要なことは

- 環境変数`DISPLAY`をセットしてあげる
- `/tmp/.X11-unix`をマウントしてあげる
   -  unix-domain socketというらしい
   -  https://unix.stackexchange.com/questions/196677/what-is-tmp-x11-unix

という変更だけでOK．
Dockerfileも至って普通で良くて

```dockerfile:Dockerfile
FROM ubuntu:18.04

RUN apt-get update && apt-get install -y --no-install-recommends mesa-utils x11-apps && rm -rf /var/lib/apt/lists/*
```
でOK

## `glxgears`が難しかった

`xeyes`のときみたくやろうとすると，

```bash
libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
Error: couldn't get an RGB, Double-buffered visual
```
と怒られてしまう．

ググるといろいろ出てくるが，どれも上手く行かず，ようやくたどり着いたROS wikiが正解だった．

- http://wiki.ros.org/docker/Tutorials/Hardware%20Acceleration

`xeyes`のときと比べて，

- `nvidia-docker`を使う必要がある
- Dockerfileに以下の3行が必要
 
```dockerfile
LABEL com.nvidia.volumes.needed="nvidia_driver"
ENV PATH /usr/local/nvidia/bin:${PATH}
ENV LD_LIBRARY_PATH /usr/local/nvidia/lib:/usr/local/nvidia/lib64:${LD_LIBRARY_PATH}
```

という2つの変更が必要だった．
`nvidia-docker`を使うと，`/usr/local/nvidia/lib`などがコンテナ内に出来上がって，それを`PATH`や`LD_LIBRARY_PATH`に追加してあげる必要があった．
ただし，これはnvidia-dockerのversionが1の場合に限る．

nvidia-dockerのversionが2の場合は

- ``nvidia-docker``ではなくて``docker run --runtime=nvidia``とする
- 以下の2行を追加する．

```dockerfile
ENV NVIDIA_VISIBLE_DEVICES ${NVIDIA_VISIBLE_DEVICES:-all}
ENV NVIDIA_DRIVER_CAPABILITIES ${NVIDIA_DRIVER_CAPABILITIES:+$NVIDIA_DRIVER_CAPABILITIES,}graphics
```

```bash
docker run --runtime=nvidia --rm -it --env="DISPLAY" --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" gl_test_v2 glxgears
```
でnvidia-docker version 2で動く．

# nvidia-dockerをdocker-composeから使う

http://tech.wonderpla.net/entry/2017/11/14/110000 が詳しい

```yaml:docker-compose.yml
version: '3'
services:
  aho:
    command: /bin/bash
    build:
      context: ./
    environment:
      - DISPLAY=${DISPLAY}
    volumes:
      - /tmp/.X11-unix:/tmp/.X11-unix
      - nvidia_driver_396.37:/usr/local/nvidia:ro
    devices:
      - /dev/nvidiactl
      - /dev/nvidia-uvm
      - /dev/nvidia0
volumes:
  nvidia_driver_396.37:
    external: true
```

``docker-compose run --rm aho``でOK

ただしこれはnvidia-dockerのversionが1の場合で，
2の場合は以下になる．だいぶシンプルになった．

```yaml:docker-compose.yml
version: '2.3'
services:
    aho:
      command: /bin/bash
      build:
        context: ./
        dockerfile: Dockerfile
      runtime: nvidia
      environment:
        - DISPLAY=${DISPLAY}
      volumes:
        - /tmp/.X11-unix:/tmp/.X11-unix
```