Docker + CentOS8でrailsアプリをデプロイするまで

<!-- TOC -->

- [はじめに](#はじめに)
- [環境](#環境)
- [まずはDockerのところから](#まずはdockerのところから)
- [必要なソフトウェアをインストールしていく](#必要なソフトウェアをインストールしていく)
    - [nginxの動作確認](#nginxの動作確認)
    - [Rubyのインストール](#rubyのインストール)
- [Rails アプリのClone](#rails-アプリのclone)
    - [注意](#%EF%B8%8Fgemfilelockのbundler-のバージョンによってはgem-install-bundlerするだけじゃエラーが起こるから注意)
- [unicornとnginxの設定](#unicornとnginxの設定)
- [最後に](#最後に)

<!-- /TOC -->

# はじめに
CentOS8で自作したrailsアプリをdocker nginx unicornでデプロイするまでを、つまづいたことなど含めて備忘録として書いていきます（時系列順に書いているので少し遠回りな手順になってます）
Dockerについては、動きを把握するためにDockerfileを使わずに動かしてます

# 環境
ruby 2.5.1
(Rails 5.2.3)
CentOS8

# まずはDockerのところから

```
% docker run -d -it -p 3000:80 --name myapp centos:8
docker exec -it myapp bash
```

これでCentOSのコンテナを立ち上げてnginxをインストールして、systemctlで起動しようとしたら、D-Busだのnot permittedみたいなエラーが出て怒られた

どうやら、CentOS7でも同じようなことが起こるみたい。[こちらを参照した](https://qiita.com/Targityen/items/6e80b855b79d521412f0)

コンテナを削除して、もう一度立ち上げる

```
% docker rm myapp
% docker run -d -it -p 3000:80 --privileged --name myapp centos:8 /sbin/init
% docker exec -it myapp bash
```

`--privileged`オプションについては[こちらを参照](https://qiita.com/muddydixon/items/d2982ab0846002bf3ea8)

これでsystemctlコマンドが使えているはずです

# 必要なソフトウェアをインストールしていく

## nginxの動作確認

```
# systemctl
# dnf install -y git vim nginx
# systemctl start nginx
# systemctl status nginx
# vim /etc/nginx/nginx.conf
# vim /usr/share/nginx/html
# vim /usr/share/nginx/html/index.html
```

## Rubyのインストール

anyenv→rbenvから今回使うruby2.5.1をインストールする

anyenvのインストールについては[公式のwikiから](https://github.com/anyenv/anyenv)

```
# git clone https://github.com/anyenv/anyenv ~/.anyenv
# echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bash_profile
# ~/.anyenv/bin/anyenv init
# vim .bash_profile          →eval "$(anyenv init -)"を記述
# exec $SHELL -l
# anyenv install --init
# anyenv -v

# anyenv install rbenv
# exec $SHELL -l
```

rbenvを入れるところまではできたが、rubyを入れるところから少し躓いた

```
# rbenv install 2.5.1
Downloading ruby-2.5.1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.1.tar.bz2
/root/.anyenv/envs/rbenv/plugins/ruby-build/bin/ruby-build: line 213: pushd: ruby-2.5.1: No such file or directory

BUILD FAILED (CentOS Linux 8 using ruby-build 20200224)

Inspect or clean up the working tree at /tmp/ruby-build.20200302084110.884.8HpNM1
Results logged to /tmp/ruby-build.20200302084110.884.log

Last 10 log lines:
/tmp/ruby-build.20200302084110.884.8HpNM1 ~
warning: bzip2 not found; consider installing `bzip2` package
tar (child): bzip2: Cannot exec: No such file or directory
tar (child): Error is not recoverable: exiting now
tar: Child returned status 2
tar: Error is not recoverable: exiting now
```

どうやらtarやbzip2が入ってないと言われ怒られたようです

```
# dnf install tar bzip2 -y
```

もう一回チャレンジ

```
[root@32a991428119 ~]# rbenv install 2.5.1
Downloading ruby-2.5.1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.1.tar.bz2
Installing ruby-2.5.1...

BUILD FAILED (CentOS Linux 8 using ruby-build 20200224)

Inspect or clean up the working tree at /tmp/ruby-build.20200302084353.1066.LCm1tD
Results logged to /tmp/ruby-build.20200302084353.1066.log

Last 10 log lines:
checking for ruby... false
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking target system type... x86_64-pc-linux-gnu
checking for gcc... no
checking for cc... no
checking for cl.exe... no
configure: error: in `/tmp/ruby-build.20200302084353.1066.LCm1tD/ruby-2.5.1':
configure: error: no acceptable C compiler found in $PATH
See `config.log' for more details
```

今度はCコンパイラがないと言われてるから、それをインストールしてみる
(この後、makeもなかったようなのでmakeもインストール)

```
# dnf install gcc make
```

```
ERROR: Ruby install aborted due to missing extensions
Try running `yum install -y openssl-devel readline-devel zlib-devel` to fetch missing dependencies.
```

また怒られた。。。
さらにインストール

```
# dnf install -y openssl-devel readline-devel zlib-devel
```

```
# rbenv install 2.5.1
Downloading ruby-2.5.1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.1.tar.bz2
Installing ruby-2.5.1...
Installed ruby-2.5.1 to /root/.anyenv/envs/rbenv/versions/2.5.1
# ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
```

できた！

# Rails アプリのclone

作ったアプリをgithubリポジトリからクローン
今回は自分が作ったアプリをcloneしていきます。この部分は任意のURLに置き換えてください

```
# git clone https://github.com/xxx/hogehoge.git
```

## ⚠️Gemfile.lockのbundler のバージョンによっては`gem install bundler`するだけじゃエラーが起こるから注意！

こんなエラーが起こることがある

```
# gem install bundler
Fetching: bundler-2.1.4.gem (100%)
Successfully installed bundler-2.1.4
Parsing documentation for bundler-2.1.4
Installing ri documentation for bundler-2.1.4
Done installing documentation for bundler after 4 seconds
1 gem installed
# bundle install
Traceback (most recent call last):
	2: from /root/.anyenv/envs/rbenv/versions/2.5.1/bin/bundle:23:in `<main>'
	1: from /root/.anyenv/envs/rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems.rb:308:in `activate_bin_path'
/root/.anyenv/envs/rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems.rb:289:in `find_spec_for_exe': can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException)
```

gemfile.lockのBUNDLED WITHにあるバージョンをインストールする
[参考](https://qiita.com/sshuuu/items/213b4e82167317e1ebb3)

```
# gem install bundler -v 2.0.1
```

これで`bundle install`コマンドも使えているはず

# unicornとnginxの設定

unicornの設定については[こちら](https://qiita.com/noraworld/items/c8acf4bb981c8d8535df)

unicorn.rbのlisten, pidと、lib/tasks/unicorn.rbの`def unicorn_pid`は各自の環境で設定しておくこと

このまま`rake unicorn:start`コマンドをしてみると、`Could not find a JavaScript runtime.`と怒られます(JavaScript入れるの忘れてました)

ということでjavaScriptの動作環境を得るためにnode.jsをインストール。これもanyenvからインストール

```
# anyenv install -l    →nodenvがあったからそれを入れます
# anyenv install nodenv
# exec $SHELL -l
# nodenv install 12.16.1
# nodenv global 12.16.1
# exec $SHELL -l
# node -v
=>v12.16.1
```

また、この時点でsqlite3が入ってないときでもエラーになったから、入れておく
エラーの内容は`log/unicorn.log`で確認できるよ!sqliteのヘッダファイルがなかったらしい？

```
# dnf install -y sqlite
# dnf install sqlite-devel.x86_64 →sqliteをインストールするだけじゃgemインストールできず、Development toolsが必要だった(dnf search sqliteしてみた)
# gem install sqlite3 -v '1.3.13' --source 'https://rubygems.org/'
```

これでちゃんと`rake unicorn:start`が動いた！

あとは参考サイトのnginxの設定通りに進めていく。
・・・が、いざnginxの再起動をすると、正常に画面が出なくなった(403 Forbbidenが出てた)
エラーログをみてみる

```
% tail /var/log/nginx/error.log
2020/03/02 11:04:28 [crit] 54612#0: *2 connect() to unix:/root/Workspace/ikea_stock_finder/tmp/unicorn.sock failed (13: Permission denied) while connecting to upstream, client: 172.17.0.1, server: _, request: "GET / HTTP/1.1", upstream: "http://unix:/root/Workspace/ikea_stock_finder/tmp/unicorn.sock:/500.html", host: "localhost:3000"
```

どうやら権限がないらしい。`ps aux | grep unicorn`でプロセスをみてみるとrootで実行されている。nginx.confの設定ではuserはnginxとなっているからここがおかしいのか？と思いrootに変えてみたら、うまくできました

# 最後に
一度コンテナから抜け出した後に再び`% docker exec -it myapp bash`でログインしたら、bash_profileが読み込まれていないらしい?
`% docker exec -it myapp bash --login`とすると解決

当たり前ですが今の状態で`docker stop`した後に`docker start`すると、nginxやunicornの再起動が必要です