CUDA 10.xのDockerイメージをローカルでビルドする

## 1. はじめに

<https://hub.docker.com/r/nvidia/cuda>を見るとわかるようにEOLとなったCUDAバージョンのDockerイメージが削除されています。ただし、Web上にある公開実装ではCUDA 10.x系のDockerイメージを使っていることがあり、これらの動作確認をするときに困ります。

幸いにもDockerイメージ作成環境は<https://gitlab.com/nvidia/container-images/cuda>にて公開されているため、ここでは以下のDockerイメージをローカルでビルドすることを試みます。

- nvidia/cuda:10.2-base-ubuntu18.04
- nvidia/cuda:10.2-runtime-ubuntu18.04
- nvidia/cuda:10.2-devel-ubuntu18.04
- nvidia/cuda:10.2-cudnn8-devel-ubuntu18.04

また、今回試すDockerイメージのターゲットCPUアーキテクチャはx86_64とします（aarch64は未確認です）。

**【2023/10/14追記】**<https://qiita.com/dandelion1124/items/31a3452b05510097daa0#comment-d91729d962b247d4378e>でコメント頂いたのですがNGCのカタログ(<https://catalog.ngc.nvidia.com/orgs/nvidia/containers/cuda>)には古いCUDAバージョンのイメージが置いてあるようです。

## 2. 動作確認環境

以下の環境で動作確認しました。

- OS: Ubuntu 22.04
- Docker Engine: 23.0.4
- nvidia-container-toolkit: 1.13.2
- NVIDIA driver: 530.30.02

## 3. CUDAありDockerイメージ作成

ここではCUDAありのDockerイメージをビルドします。まずはじめにGitリポジトリをクローンします。

```shell
git clone https://gitlab.com/nvidia/container-images/cuda.git
```

そのままだと<https://gitlab.com/nvidia/container-images/cuda/-/issues/213>にある問題が起きてしまったのでビルドスクリプト（`build.sh`）に以下の変更を加えます。

```diff
-        run_cmd docker buildx build --pull ${LOAD_ARG} ${PUSH_ARG} ${PLATFORM_ARG} \
+        run_cmd docker build ${LOAD_ARG} ${PUSH_ARG} ${PLATFORM_ARG} \
             -t "${IMAGE_NAME}:${CUDA_VERSION}-base-${OS}${OS_VERSION}${IMAGE_SUFFIX:+-${IMAGE_SUFFIX}}" \
             "${BASE_PATH}/${OS_PATH_NAME}/base"
 
-        run_cmd docker buildx build --pull ${LOAD_ARG} ${PUSH_ARG} ${PLATFORM_ARG} \
+        run_cmd docker build ${LOAD_ARG} ${PUSH_ARG} ${PLATFORM_ARG} \
             -t "${IMAGE_NAME}:${CUDA_VERSION}-runtime-${OS}${OS_VERSION}${IMAGE_SUFFIX:+-${IMAGE_SUFFIX}}" \
             --build-arg "IMAGE_NAME=${IMAGE_NAME}" \
             "${BASE_PATH}/${OS_PATH_NAME}/runtime"
 
-        run_cmd docker buildx build --pull ${LOAD_ARG} ${PUSH_ARG} ${PLATFORM_ARG} \
+        run_cmd docker build ${LOAD_ARG} ${PUSH_ARG} ${PLATFORM_ARG} \
             -t "${IMAGE_NAME}:${CUDA_VERSION}-devel-${OS}${OS_VERSION}${IMAGE_SUFFIX:+-${IMAGE_SUFFIX}}" \
             --build-arg "IMAGE_NAME=${IMAGE_NAME}" \
```

また、<https://gitlab.com/nvidia/container-images/cuda/-/commit/5d080f35a0e9324007c3b007539afe47f2da5c84>のコミットにてEOLとなったCUDAバージョンのファイルが`dist/end-of-life`ディレクトリに退避されたので`dist`ディレクトリにコピーします。

```shell
cp -r dist/end-of-life/10.2 dist/
```

ここまでで準備ができたのでビルドスクリプト（`build.sh`）を用いてDockerイメージをビルドします。

```shell
./build.sh -d --image-name nvidia/cuda --cuda-version 10.2 --os ubuntu --os-version 18.04 --arch x86_64 --load
```

正常に実行されると以下のDockerイメージが生成されます。

- nvidia/cuda:10.2-base-ubuntu18.04
- nvidia/cuda:10.2-runtime-ubuntu18.04
- nvidia/cuda:10.2-devel-ubuntu18.04

## 4. CUDA+cuDNNありDockerイメージ作成

ここでは「3. CUDAありDockerイメージ作成」ができている前提でcuDNNありのDockerイメージをビルドします。ただし、<https://gitlab.com/nvidia/container-images/cuda/-/issues/210#note_1469139165>に

> Our build script currently does not support cudnn.

とあり、現時点のビルドスクリプト（`build.sh`）ではcuDNNまで面倒見てくれないようです。そのため、リポジトリ内にあるDockerfileを用いて対応します。

```shell
cd dist/10.2/ubuntu1804/devel/cudnn8
docker build -t nvidia/cuda:10.2-cudnn8-devel-ubuntu18.04 --build-arg IMAGE_NAME=nvidia/cuda --build-arg TARGETARCH=amd64 .
```

正常に実行されると以下のDockerイメージが生成されます。

- nvidia/cuda:10.2-cudnn8-devel-ubuntu18.04