最新のRails環境構築を例に学ぶ、望み通りのDockerコンテナを粛々と組み上げていくプロセス

# 前回はLaravelで今回はRails
 前に、Laravelを例にDockerとdoker-composeの仕組みについて記事を書きましたが、今回は、その仕組みを踏まえた上で、どうやって自分の思い通りのコンテナを作っていくかの過程を記事にしていこうと思います。

前の記事はこちらです。こちらもちょくちょく更新しています。よろしければお読みください。
[開発環境構築in Docker ~Laravelを例に学ぶDockerの仕組み~
](https://qiita.com/Nedward/items/89bcb729106065650b7f)

# 今回のRails
こちらを作ってみました。完成品はこちらです。使い方はREADMEをお読みください。
[docker-compose-origin-rails](https://github.com/Ohnao/docker-compose-origin-rails)

```
Rails 5.2.3
ruby 2.6.3
mysql8
```
今回はこの環境を構築するにあたり、どうやって作っていくのかを、作っている過程で出てきた問題の１つを例にとってまとめていきたいと思います。１つ１つ起きたエラーを記述するより、どうやってあエラーを効率よく潰していくかのプロセスを知ることで、たくさん出てくるエラーにも物怖じしない力をつける必要があると思ったので、この記事を書きました。

実行環境は以下の通りです。

```
OS: Mojave ver.10.14.5
Docker: ver.18.09.2
docker-compose: ver.1.23.2
```

# 今回のRails
こちらを作ってみました。完成品はこちら。
[docker-compose-origin-rails](https://github.com/Ohnao/docker-compose-origin-rails)

```
Rails 5.2.3
ruby 2.6.3
mysql8
```
今回はこの環境を構築するにあたり、どうやって作っていくのかを、作っている過程で出てきた問題の１つを例にとってまとめていきたいと思います。

# docker build or upでエラーが出るけどどのファイル？
　buildやupでうまくいかない場合、どのコンテナが落ちていて、そのコンテナのイメージを指定しているファイル、Dockerfile or docker-compose.ymlを見極めていく必要がある。例えば、mysqlのコンテナが落ちていたら、docker-compose.ymlでイメージ読んでるから、こっちのファイルかな？とかです。で、実際に見にいくと落ちてる原因になっている記述があったりします。筆者は、

```docker-compose.yml
command: mysqld --collation-server=utf8mb4_unicode_ci
```
ここのUTF8の設定で怒られてコンテナがexitしてしまいました。mysql8のデフォルトの文字コードが変わったみたいですね。
[[MySQL8.0] デフォルトUTF8MB4、そして新しい日本語用照合順序
](http://scsk-db.jp/mysql/topics/2018/05/23-090000.html)

# buildできなくても、noneのイメージに侵入してみる
　buildにたとえ失敗したとしてもnoneとしてイメージが出来上がっているので、

```
$ docker run -it Image_ID /bin/bash
```

noneのイメージに上記コマンドで入ってみましょう。
**たまにベースイメージにしているOSの違いでbashで入れないことがあります。**
固有のシェルが必要なこともありますので、その時は適宜調べましょう。
例えば、alpine linuxの場合、ashというシェルになります。

## 実際に直してみる
実際にコンテナビルドした時にでてくるエラーなり警告なりを直してみます。

```
warning: /var/cache/yum/x86_64/7/base/packages/audit-libs-2.8.4-4.el7.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
```

　すみません、フェータルなエラーは直すのに血眼でログとっておくのをすっかり忘れてしまいましたので、解決プロセスをこのwarningを使って見ていきたいと思います。このwarningはrpmの鍵が不足していることで、パッケージの信頼性が証明されていないということのようです。
　ここで大事なのは、このwarningの解決策を探る際に、ググるわけですが、実はこのwarningを本文丸ごとググってもいい検索結果は得られないです。理由は、

```
/var/cache/yum/x86_64/7/base/packages/audit-libs-2.8.4-4.el7.x86_64.rpm

key ID f4a80eb5
```

　上記の部分が環境要因なので自身のPC固有の標準出力の可能性が高いからです。ここで正しく検索にかけるべきは、より抽象度の高いerrorないしwarningの標準出力です。この環境要因と使用しているソフトウェアそのものの要因とで分けられるようになるとグッと検索効率が上がります。私より優秀なエンジニアの方がこの話を教えてくれてまた思考の幅が広くなりました。
　さて、今回のwarningでは、

```
Header V3 RSA/SHA256 Signature　

NO KEY
```

ここを検索にかけると良いです。加えてDockerやCentOS7などの単語をキーワードとして追加してあげるといいです。個人的にエラーは英語読めば一撃なのもありますが、たまにこう言ったものも混ざっているので、検索ワードを見定める基準を１つ２つ持っておくといいのかなと思います。

そうすると、
[CentOS7 パッケージ管理（インストール済みRPMの最新化）
](https://qiita.com/mattsun/items/2a71eef5b396a8495264)

こんな記事が出てきました。

この記事を見ると、

> GPGキーは「GnuPG」（GNU Privacy Guard）という暗号化ソフトで生成される公開鍵。apt-getコマンドやyumコマンドを使ってインターネットから入手できるパッケージが正しい配布先のものかどうかのチェックなどに利用する

ということなので、先ほどパッケージの信頼性が証明されていないと書きましたが、まさにそれを確かめるキーをrpmでインポートしてくることでうまくいきそうです。

### コンテナに入ってみて検証してみる
先ほど調べた記事によるとrpmコマンドを使ってキーをインポートしているようなので、早速実行してみる。

先ほどのdocker runコマンドでコンテナ内に侵入し、

```
$ sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

$rpm -qa gpg-pubkey*
gpg-pubkey-352c64e5-52ae6884
```

OKのようなので、コンテナからexitして、Dockerfileへ記述します。

```Dockerfile
RUN rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 && \　# ←書き足した内容
    yum clean all && \
    yum update -y && \
          .
          .
          .
```

実行の順序としては、このキーはパッケージの安全保障のキーなので、yumでのインストール作業が動き出す前に実施するのがベストなので、一番最初に記述します。

このように、dockerからエラーや警告が出たら、検索の仕方を工夫して検索かけて、それをコンテナ内で実行してみてうまくいったらファイルに記述して永続化するという作業を繰り返してコツコツ作り込んでいきます。

## まとめ
　結局のところは、初めてローカルで開発環境を立ち上げる時にえっちらおっちらhomebrew使って色々パッケージを入れて準備を整えてみたりしたと思いますが、それをCentOS7をベースイメージにして、コンテナに侵入していき、yumを使って実際にコマンドを叩いてうまくいけば、そのコマンドを都度、Dockerfileへ粛々と書いていくことで、作れるようになります。
　なんとも地道な作業にではありますが、結構楽しいです。更新していくたびにgit pushして草いっぱい生やしてみると、Dockerの習熟達成感がみるみる内に実感できます。（あくまで個人の見解です。）