Red Hat Universal Base Image（UBI）にNginxを入れてコンテナ起動させてみる

自由に再配布可能なRed Hat Enterprise Linux ベースのコンテナ用OSイメージ「Red Hat Universal Base Image」(以降UBI）にNginxを入れてコンテナ起動させてみる。

UBIは2020/06時点でRHEL7ベースとRHEL8ベースの2種類、パッケージ構成はstandard(標準)、init(systemd初期化システムあり)、minimal(最小構成)の3種類がRHEL7と8それぞれに用意されている。

今回は①RHEL7ベースstandard、②RHEL7ベースinitを試してみる。
※standardだけでも良かったが、コンテナでsystemdを使ってみたかったためinitも試してみることにした。

イメージ作成は普通はdockerfileだが、今回はわざわざ手でひとつひとつ実行していくやり方も試してみる。

まずはUBIイメージをどこから入手すればよいか探すところから。
　


## UBIイメージを探す
ubiでググってみると、どうやら[Red Hat Ecosystem Catalog](https://catalog.redhat.com/software/containers/search)から入手するようだった。このサイトの検索フォームから ubi7 と検索したところ探し物が出てきてくれた。

Red Hat Universal Base Image 7 →標準
Red Hat Universal Base Image 7 Minimal →最小構成
Red Hat Universal Base Image 7 Init →systemd 初期化システムあり

Minimalは文字通りの意味のはずだが、標準とsystemd初期化システムありの違いは説明が欲しい。ググってみると[公式](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/building_running_and_managing_containers/using_red_hat_universal_base_images_standard_minimal_and_runtimes)に説明があった。

> ubi8-init イメージは ubi8 イメージの上に構築されるため、その内容はほとんど同じです。ただし、重要な相違点がいくつかあります。ubi8-init では、Cmd は bashではなく /sbin/init に設定され、デフォルトで systemd Init サービスを開始します。これには ps およびプロセス関連のコマンド (procps-ng パッケージ) が含まれていますが、ubi8 には含まれていません。また、ubi8-init の systemd は、終了する通常の信号 (SIGTERM および SIGKILL) を無視しますが、SIGRTMIN + 3 を受信すると終了するため、ubi8-init は SIGRTMIN+3 を StopSignal として設定します。

なるほど、なるほどと理解したところで次はリポジトリのURL探し。
先ほどの検索結果から[標準(Red Hat Universal Base Image 7)](https://catalog.redhat.com/software/containers/ubi7/ubi/5c3592dcd70cc534b3a37814)を選択しポチポチ探していると、[Get this image]タブの中の[Unauthenticated]タグに載っていた。

> Using docker
Use the following command(s) from a system with docker service installed and running
 
>$ docker pull registry.access.redhat.com/ubi7/ubi



必要な情報は揃ったのでこのベースイメージにNginxを入れてコンテナ起動させてみる。ホストはLinuxなら何でも良かったので、お手軽なEC2(t2.micro) Amazon Linux 2とした。

## UBI7(標準)にNginxを入れてコンテナ起動
### まずはdockerfileを使わないでイメージ作成してみる

```text:ベースイメージ（UBI7-standard）のコンテナ起動
$ docker container run -it --name ubi7 registry.access.redhat.com/ubi7/ubi:7.8 /bin/bash
```

↓ yumのデフォルトリポジトリにnginxが無かった為、[Nginx公式](http://nginx.org/en/linux_packages.html#RHEL-CentOS)を参考にNginxのリポジトリを追加（ちなみにUBI8はデフォルトリポジトリにnginxが入っている為この操作はいらない）。

```text:【コンテナ内操作】Nginx用のレポジトリ設定
# yum install yum-utils
# vi /etc/yum.repos.d/nginx.repo
------下記内容で保存-----
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
--------------------
```
↓ Nginxのインストールではsubscription-managerオプションでサブスクリプション管理を無効にしている。指定しなくても良さそうだが再配布まわりで念のため。

```text:【コンテナ内操作】Nginxインストール
# yum install -y --disableplugin=subscription-manager nginx
# yum clean all
```

```text:コンテナから抜ける
# exit
```
↓ イメージを作成する。nginxの起動時オプションに -g "daemon off;" を指定しているのはNginxをフォアグランドで動かす為。コンテナはフォアグランドで動かさないと直ぐに停止してしまう為、このオプションでデーモンモードをoffにしている。
※Nginxの設定ファイル（/etc/nginx/nginx.conf)にdeamon off;を記載するでもOK。

```text:イメージ作成
$ docker container commit -c 'CMD ["-g","daemon off;"]' -c 'ENTRYPOINT ["nginx"]' ubi7 ubi7nginx:standard
```

```text:Nginxコンテナ起動
docker container run -d --name ubi7nginx -p 80:80 ubi7nginx:standard
```
　
ブラウザから表示できることを確認。

```http:ブラウザ
http://xxxx.xxxx.xxx   ※EC2のパブリックDNS or パブリックIPv4
```

以下のような画面が表示されれば疎通OK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/771cdc28-c865-c26d-17a2-7c8085d518e1.png)

動作確認できたので後片付け。作成したコンテナとイメージを削除。

```text:後片付け
$ docker container rm -f $(docker container ls -qa)
$ docker image rm ubi7nginx:standard
```
 
　

### 続いてdockerfileでイメージ作成してコンテナ起動
```text:dockerfile作成
$ vi dockerfile
-------ファイル内容----------
FROM registry.access.redhat.com/ubi7/ubi:7.8
RUN { \
      echo '[nginx-stable]'; \
      echo 'name=nginx stable repo'; \
      echo 'baseurl=http://nginx.org/packages/centos/$releasever/$basearch/'; \
      echo 'gpgcheck=1'; \
      echo 'enabled=1'; \
      echo 'gpgkey=https://nginx.org/keys/nginx_signing.key'; \
      echo 'module_hotfixes=true'; \
      echo ''; \
      echo '[nginx-mainline]'; \
      echo 'name=nginx mainline repo'; \
      echo 'baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/'; \
      echo 'gpgcheck=1'; \
      echo 'enabled=0'; \
      echo 'gpgkey=https://nginx.org/keys/nginx_signing.key'; \
      echo 'module_hotfixes=true'; \
    }  > /etc/yum.repos.d/nginx.repo
RUN yum install -y --disableplugin=subscription-manager nginx && yum clean all
ENTRYPOINT ["nginx"]
CMD ["-g","daemon off;"]
-----------------------------
```
 
```text:イメージ作成
$ docker build -t ubi7nginx:standard .
```

```text:Nginxコンテナ起動
docker container run -d --name ubi7nginx -p 80:80 ubi7nginx:standard
```

ブラウザから表示できることを確認。

```http:ブラウザ
http://xxxx.xxxx.xxx   ※EC2のパブリックDNS or パブリックIPv4
```

以下のような画面が表示されれば疎通OK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/771cdc28-c865-c26d-17a2-7c8085d518e1.png)

動作確認できたので後片付け。作成したコンテナとイメージを削除。

```text:後片付け
$ docker container rm -f $(docker container ls -qa)
$ docker image rm ubi7nginx:standard
```
　
　


## UBI7(Init)にNginxを入れてコンテナ起動（systemdでNginx起動）
### まずはdockerfileを使わないでイメージ作成してみる

```text:UBI7（Init）コンテナ起動
$ docker container run -it --name ubi7 registry.access.redhat.com/ubi7/ubi-init:7.8 /bin/bash
```
 
```text:【コンテナ内操作】Nginx用のレポジトリ設定
# yum install yum-utils
# vi /etc/yum.repos.d/nginx.repo
------下記内容で保存-----
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
--------------------
```

```text:【コンテナ内操作】Nginxインストール
# yum install -y --disableplugin=subscription-manager nginx
# yum clean all
```

```text:【コンテナ内操作】自動起動設定ON
# systemctl enable nginx.service
```

```text:コンテナから抜ける
# exit
```


```text:イメージ作成
$ docker container commit -c 'CMD ["/sbin/init"]' ubi7 ubi7nginx:systemd
```

```text:Nginxコンテナ起動
docker run --name ubi7nginx -p 80:80 -d --privileged ubi7nginx:systemd
```
↑ --privilegedをつけないとnginxが立ち上がらなかった。
--privileged無しで起動してコンテナ内をpsしてみる。
>  # ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 22:05 ?        00:00:00 /sbin/init
root         6     0  6 22:07 pts/0    00:00:00 /bin/bash
root        19     6  0 22:07 pts/0    00:00:00 ps -ef

やはりnginxはいない。
systemctl statuでステータスを見ようとしてもエラーになる。
>  # systemctl status nginx.service
Failed to get D-Bus connection: Operation not permitted

エラー文言でググると**コンテナ起動時に--privilegedをつけろ**と出てくる。詳しくは別途調べる必要ありだが、ひとまず付ければ上手くいくので先に進む。
　
ブラウザから表示できることを確認。

```http:ブラウザ
http://xxxx.xxxx.xxx   ※EC2のパブリックDNS or パブリックIPv4
```

以下のような画面が表示されれば疎通OK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/771cdc28-c865-c26d-17a2-7c8085d518e1.png)

動作確認できたので後片付け。作成したコンテナとイメージを削除。

```text:後片付け
$ docker container rm -f $(docker container ls -qa)
$ docker image rm ubi7nginx:systemd
```
 
　

### 続いてdockerfileでイメージ作成してコンテナ起動
```text:dockerfile作成
$ vi dockerfile
-------ファイル内容----------
FROM registry.access.redhat.com/ubi7/ubi-init:7.8
RUN { \
      echo '[nginx-stable]'; \
      echo 'name=nginx stable repo'; \
      echo 'baseurl=http://nginx.org/packages/centos/$releasever/$basearch/'; \
      echo 'gpgcheck=1'; \
      echo 'enabled=1'; \
      echo 'gpgkey=https://nginx.org/keys/nginx_signing.key'; \
      echo 'module_hotfixes=true'; \
      echo ''; \
      echo '[nginx-mainline]'; \
      echo 'name=nginx mainline repo'; \
      echo 'baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/'; \
      echo 'gpgcheck=1'; \
      echo 'enabled=0'; \
      echo 'gpgkey=https://nginx.org/keys/nginx_signing.key'; \
      echo 'module_hotfixes=true'; \
    }  > /etc/yum.repos.d/nginx.repo
RUN yum install -y --disableplugin=subscription-manager nginx && yum clean all
RUN systemctl enable nginx.service;
CMD ["/sbin/init"]
-----------------------------
```
 
```text:ビルド
$ docker build -t ubi7nginx:systemd .
```

```text:Nginxコンテナ起動
$ docker container run -d --name ubi7nginx -p 80:80 --privileged ubi7nginx:systemd
```

ブラウザから表示できることを確認。

```http:ブラウザ
http://xxxx.xxxx.xxx   ※EC2のパブリックDNS or パブリックIPv4
```

以下のような画面が表示されれば疎通OK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651099/771cdc28-c865-c26d-17a2-7c8085d518e1.png)

動作確認できたので後片付け。作成したコンテナとイメージを削除。

```text:後片付け
$ docker container rm -f $(docker container ls -qa)
$ docker image rm ubi7nginx:systemd
```
 
　
### 参考にさせて頂いたサイト
・[RHEL8+nginxイメージの作成](https://qiita.com/HOBO0222/items/18f4a4e0eca540bc8bba)
・[docker container / image コマンド新旧比較](https://qiita.com/zembutsu/items/6e1ad18f0d548ce6c266)
・[Docker nginxのコンテナすぐに終了してしまう現象](http://yinm.hatenadiary.jp/entry/2017/05/04/220439)
・[yum clean コマンドでキャッシュ削除・アップデートのチェックと実行 〜 CentOS6](https://easyramble.com/yum-clean-and-update.html)
・[DockerコンテナのCentOS7で 「Failed to get D-Bus connection: Operation not permitted」と出た時の対処方法](https://www.opensourcetech.tokyo/entry/20190222/1550822082)
・[コンテナに外部からアクセス（ポートフォワード）](https://qiita.com/tifa2chan/items/a58e34019d4f10097a4d)
・[一発ですべてのDockerコンテナを停止・削除、イメージの削除をする](https://qiita.com/shisama/items/48e2eaf1dc356568b0d7)
・[自由に再配布可能なRed Hat Enterprise Linux 8ベースのコンテナ用OSイメージ「Red Hat Universal Base Image」が公開](https://www.publickey1.jp/blog/19/red_hat_enterprise_linux_8osred_hat_universal_base_image.html)

　
　
　
以上です。おつかれさまでした。