【　Ruby on Rails 6.0　】AWS + Nginx + Unicornでデプロイ⑤

# 始めに
前回まででEC2上に必要なGemをインストールし本番環境用に環境変数を設定しました。今回はHTTP通信を設定しRailsアプリを起動する工程までをまとめたいと思います。

# 目次
|目次|内容|
|:--:|:--:|
|セクション1|[EC2インスタンス作成](https://qiita.com/anago1030/items/854252bc9b728fe90beb)|
|セクション2|[Linuxサーバー構築](https://qiita.com/anago1030/items/07f7026c0f4c42a63440)|
|セクション3|[データベース設定](https://qiita.com/anago1030/items/79eebdc8474255b962b4)|
|セクション4|[EC2上でGemをインストールし環境変数を設定](https://qiita.com/anago1030/items/0a9a8937421f64f46a44)|
|セクション5|**Railsアプリを起動**（今回の内容）|
|セクション6|[Nginxの導入](https://qiita.com/anago1030/items/c4c80a46a75ff306db8d)|
|セクション7|[自動デプロイ](https://qiita.com/anago1030/items/cb60c8e99d408dc4fd80)|
|セクション8|[独自ドメイン取得](https://qiita.com/anago1030/items/5e487ec48fd7c0be86bc)|

## ポート開放
立ち上げたばかりのEC2インスタンスはSSHでアクセスすることはできますが、HTTPなどの他の通信方法では一切つながらないようになっています。そのため、WEBサーバとして利用するEC2インスタンスは事前にHTTPがつながるように「ポート」を開放する必要があります。

### セキュリティグループのポートを設定
AWSのEC2インスタンス一覧画面から、対象のインスタンスを選択し、「セキュリティグ
ループ」のリンクをクリックします。
![スクリーンショット 2021-02-25 10.11.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772095/d7f4d0f5-aed1-c248-52f7-7279b4767eff.png)
すると、インスタンスの属するセキュリティグループの設定画面に移動するので、「イン バウンド」タブの中の「編集」をクリックします。
![スクリーンショット 2021-02-25 10.14.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772095/3104037b-4069-7727-da64-9b4ec346a310.png)
モーダルが開くので、「ルールの追加」をクリックします。

|タイプ|カスタムTCPルール」|
|:--:|:--:|
|プロトコル|TCP|
|ポート範囲|3000|
|送信元|カスタム、0.0.0.0/0|
 「0.0.0.0」は「全てのアクセスを許可する」という意味です。

以上で、ポートの開放が完了です。

## database.ymlの本番環境の設定を編集
本番環境のmysqlの設定に合わせるため、ローカルのdatabase.ymlを以下のように編集して下さい。

```php:config/database.yml
production:
  <<: *default
  database: （ここは編集しないこと）
  username: root
  password: <%= ENV['DATABASE_PASSWORD']
  socket: /var/lib/mysql/mysql.sock
```
### ローカルでの編集をコミットして、GitHubにプッシュ
リモートリポジトリが更新されたため、サーバ上のアプリケーションにも反映させましょう。今回はすでにEC2とGithubは接続できているため、`git pullコマンド`を利用します。 
※別にブランチを切っている場合は、masterブランチにmergeしてから以下のコマンドを 実行しましょう。

```php:ターミナル(EC2)
[ec2-user@ip-172-31-23-189 <app名>]$ git pull origin master
```

### データベースを作成しマイグレーションを実行

```php:ターミナル(EC2)
[ec2-user@ip-172-31-23-189 <app名>]$ rails db:create RAILS_ENV=production
[ec2-user@ip-172-31-23-189 <app名>]$ rails db:migrate RAILS_ENV=production
```
もしここで`Mysql2::Error: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock'` というエラーが起こった場合、データベース が起動していない可能性があります。`sudo systemctl start mariadb`というコマン ドをターミナルから打ち込み、mysqlの起動を試してみましょう。

## アセットファイルをコンパイル
続いて、アセットファイルをコンパイルします。
**アセットファイル**とは、画像・CSS・ JavaScript等を管理しているファイルです。
コンパイルとはアセットファイルを圧縮し、 そのデータを転送するということです。
この作業を行わないと、本番環境でCSSが反映されずにビューが崩れてしまったり、エラーでブラウザが表示されない、などの問題が生じてしまいます。 

```php:ターミナル(EC2)
[ec2-user@ip-172-31-23-189 <アプリ名>]$ rails assets:precompile RAILS_ENV=production

# 成功すると
Yarn executable was not detected in the system.
Download Yarn at https://yarnpkg.com/en/docs/install
I, [2020-01-18T12:51:01.4345644 #1265]  INFO -- : Writing /var/app/web-share/public/assets/member_photo_noimage_thumb-224a733c50d48aba6d9fdaded809788bbeb5ea5f6d6b8368adaebb95e58bcf53.png
I, [2020-01-18T12:51:02.2615123#1265]  INFO -- : Writing /var/app/appname/public/assets/application-bc071e28a78e2b63c9313afed5ad3476e00e3f0e5b12445c37214d1f1317be48.js
I, [2020-01-18T12:51:02.2626434 #1265]  INFO -- : Writing /var/app/appname/public/assets/application-bc071e28a78e2b63c9313afed5ad3476e00e3f0e5b12445c37214d1f1317be48.js.gz
I, [2020-01-18T12:51:08.484546 #1265]  INFO -- : Writing /var/app/appname/public/assets/application-8549fb9a804686e593d5c0f90a2412a39de85908e5fb58fdf6681d4b0073d891.css
I, [2020-01-18T12:51:08.485454 #1265]  INFO -- : Writing /var/app/appname/public/assets/application-8549fb9a804686e593d5c0f90a2412a39de85908e5fb58fdf6681d4b0073d891.css.gz
```
ここでyarnのエラーが発生したら**node.js**をupdateします。

### Node.jsのアップデート
Node.jsのバージョン管理ツールnvmを使用してインストールします。

```php:ターミナル(EC2)
# 現在のバージョン確認
[ec2-user@ip-172-31-23-189 <アプリ名>]$ node -v
v4.9.1

# Node.jsのバージョン管理ツールnvmをclone
[ec2-user@ip-172-31-23-189 <アプリ名>]$ git clone git://github.com/creationix/nvm.git ~/.nvm
[ec2-user@ip-172-31-23-189 <アプリ名>]$ echo . ~/.nvm/nvm.sh >> ~/.bashrc
[ec2-user@ip-172-31-23-189 <アプリ名>]$ . ~/.bashrc

# nvmバージョン確認
[ec2-user@ip-172-31-23-189 <アプリ名>]$ nvm --version
0.35.0

# インストールできるNode.jsの確認
[ec2-user@ip-172-31-23-189 <アプリ名>]$ nvm ls-remote

# 最新の安定版をインストール
[ec2-user@ip-172-31-23-189 <アプリ名>]$ nvm install stable

# バージョン確認
[ec2-user@ip-172-31-23-189 <アプリ名>]$ node -v
v12.12.0 # バージョンが最新になっていたら成功
```
もう一度コンパイルを実行してみましょう。


## Unicornのプロセスを確認
コンパイルが成功したら反映を確認するため、Railsを再起動します。しかし、まずは今動 いているUnicornをストップします。そのために、Unicornのプロセスを確認し、プロセスを止めます。ターミナルからプロセスを確認するには`psコマンド`を利用します。

```php:ターミナル
# unicorn起動
[ec2-user@ip-172-31-38-126 <リポジトリ名>]$ bundle exec unicorn_rails -c config/unicorn.rb -E production -D

[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ ps aux | grep unicorn

ec2-user 17877  0.4 18.1 588472 182840 ?       Sl   01:55   0:02 unicorn_rails master -c config/unicorn.rb -E production -D
ec2-user 17881  0.0 17.3 589088 175164 ?       Sl   01:55   0:00 unicorn_rails worker[0] -c config/unicorn.rb -E production -D
ec2-user 17911  0.0  0.2 110532  2180 pts/0    S+   02:05   0:00 grep --color=auto unicorn
```
大事なのは左から2番目の列です。ここに表示されるのがプロセスのid、つまりPIDになります。
**「unicorn_rails master」**と表示されているプロセスがUnicornのプロセス本体です。この時のPIDは、17877となっています。

### killコマンドを入力してUnicornのプロセスを停止

```php:ターミナル
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ kill <確認したunicorn rails masterのPID>

# 再度確認する
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ ps aux | grep unicorn
...
ec2-user 17911  0.0  0.2 110532  2180 pts/0    S+   02:05   0:00 grep --color=auto unicorn

# できない場合は強制終了する
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ kill -9 [プロセスID]
```

### 先頭にRAILS_SERVE_STATIC_FILES=1をつけて、unicornを起動
続いて再びunicornを起動しましょう。このとき**RAILS_SERVE_STATIC_FILES=1**という指定を先頭に追加してください。これは、コンパイルされたアセットをRailsが見つけられるような指定になります。以下のようにコマンドを実行してください。

```php:ターミナル
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ RAILS_SERVE_STATIC_FILES=1 unicorn_rails -c config/unicorn.rb -E production -D
```

### ブラウザで確認
ブラウザで http://<Elastic IP>:3000/ にアクセスして、サイトが正常に表示されているか確認してみましょう。

### Railsの起動がうまくできなかった時
上記のコマンドを実行してもRailsが起動しないときや、起動できてもIPアドレス:3000に
アクセスするとエラーが表示されていることがあります。 

以下の項目をチェックしてみてください。

* **pushのし忘れ、またはEC2サーバ側でのpullのし忘れは無いか**
* **ローカルでの編集のpushやEC2でのgit pullを忘れていないか**
* **データベースの起動は正しく行えているか**
* **EC2サーバ側のSECRET_KEY_BASE等は正しく設定できているか**
* **EC2インスタンスの再起動を行ってみる**

## unicornのログを確認する
上記のポイントでも解決出来ない場合はunicornのログを確認してみましょう。
`lessコマンド`または`catコマンド`を使えばログを見ることが出来ます。

```php:ターミナル（EC2）
[ec2-user@ip-172-31-23-189 <app名>]$ less log/unicorn.stderr.log

# 実行結果
I, [2021-02-21T02:28:26.245480 #7257]  INFO -- : Refreshing Gem list
I, [2021-02-21T02:28:28.232692 #7257]  INFO -- : listening on addr=0.0.0.0:3000 fd=9
E, [2021-02-21T02:28:28.245079 #7257] ERROR -- : Unknown database 'app_production' (ActiveRecord::NoDatabaseError)
```
ログはEnterキーを押せば下にスクロールすることが出来ます。（下にいくほど最新のログです。）
上の例では`Unknown database`となっているため`rails db:create`をし忘れている可能生があります。
もしくは`database.yml`の設定に誤りがあるかもしれません。
このようにログを頼りに原因を特定していきます。

# 終わりに
今回の内容までで、Elastic IPアドレスを入力してブラウザ上でアプリが起動していることを確認出来ました。
次回はユーザーのリクエストに対してレスポンスを送れるようにWebサーバーを導入していきます。

次回
[Nginxの導入](https://qiita.com/anago1030/items/c4c80a46a75ff306db8d)