ROSの公式インストール手順をcudaglベースのDockerファイルで再現したら案外苦戦した

## 環境
- Ubuntu 20.04
- Docker 20.10.6

## やりたかったこと
タイトルの通り、cudaglをベースイメージにしたROS Noeticインストール済みのDocker Imageを作ろうと思ってました。ROSを使うことだけが目的であれば、Docker HubにあるROSが元から入っているイメージをベースイメージにすればいいのですが、OpenGLやCUDAを使いたい場合、cudaglをベースにしてROSを入れた方が楽だと思い、今回のDockerfileを書いてました。

## ビルドが成功したDockerfile
最初に試行錯誤の末に書いたDockerfileを載せます。これ以降の章では、このDockerfileを書く際に詰まった箇所を説明します。

```bash
# base image
FROM nvidia/cudagl:11.3.0-devel-ubuntu20.04
ENV DEBIAN_FRONTEND=noninteractive

# Setup basic packages
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    git \
    curl \
    vim \
    pkg-config \
    wget \
    zip \
    unzip \
    tzdata \
    lsb-release \
    && rm -rf /var/lib/apt/lists/* \
    && apt-get autoclean

# Installl ROS noetic
# http://wiki.ros.org/noetic/Installation/Ubuntu
# Add the package keys.
RUN sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
# Update the package list.
RUN curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | apt-key add -
# Install 'ros-noetic-desktop-full' packages
RUN apt-get update && apt-get install -y --no-install-recommends \
    ros-noetic-desktop-full \
    && rm -rf /var/lib/apt/lists/* \
    && apt-get autoclean

```

## 失敗例
### 失敗の要因1：lsb-releaseをインストールする必要があった
[公式インストール手順](http://wiki.ros.org/noetic/Installation/Ubuntu)をDockerファイルでそのまま再現したらエラーが出ました。具体的には、以下のようなものをDockerファイルに書きました。
```bash
# Add the package keys.
RUN sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
# Update the package list.
RUN curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | apt-key add -
# Install 'ros-noetic-desktop-full' packages
RUN apt-get update　# ここでエラーが出る
```
すると下記のようなエラーが出ました。
```bash
E: Malformed entry 1 in list file /etc/apt/sources.list.d/ros-latest.list (Component)
E: The list of sources could not be read.
```

同じような問題に言及している記事がありましたので、そちらを参考にしました。
参考：[MacのDockerでUbuntu+ROSを動かす](https://qiita.com/atsuto/items/e9dc01166be52b181d90)

上記の記事では、既存のros-latest.listを削除したり、公開鍵を直打ちで入れたりしていますが、今回の問題はlsb-releaseが入ってないことが原因でした。そのため、Dockerfileに`apt install lsb-release`を追加することで解決しました。

```bash
# 実際に追加したもの
RUN apt-get update && apt-get install -y --no-install-recommends \
    lsb-release \
    && rm -rf /var/lib/apt/lists/*

# Add the package keys.
RUN sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
# Update the package list.
RUN curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | apt-key add -
# Install 'ros-noetic-desktop-full' packages
RUN apt-get update　# ここでエラーが出ない
```

### 失敗の要因2：ベースイメージが不適切
ベースイメージで最初はこれを使用していました。
```bash
FROM nvidia/cudagl:11.3.1-base-ubuntu20.04
RUN apt-get update # このときにエラーが出る
```
以前にもこれを使っており、そのときはうまくいっていたので流用しようと思ったら全然ビルドに成功しませんでした。

エラー内容はこちらです。
```bash
W: GPG error: https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64  InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY A4B469963BF863CC
E: The repository 'https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64  InRelease' is not signed.
```

原因は[CUDALinuxGPGリポジトリキーの更新](https://developer.nvidia.com/blog/updating-the-cuda-linux-gpg-repository-key/)があり、これに対応していないベースイメージを使っていたのが原因でした。

実際に使用したベースイメージはこちらです。[Docker Hub](https://hub.docker.com/r/nvidia/cudagl)を見て最近更新されているタグを選びました。
```bash
FROM nvidia/cudagl:11.3.0-devel-ubuntu20.04
```

## 感想
簡単なことだと思っていたのに思ったより時間がかかりました。同じ事例で詰まっている人の役に立てれば幸いです。