デプロイ方法⑤(Nginx/Unicorn)

※デプロイの方法の手順⑤　今後の自分のメモ用に

#Nginxの導入と設定

###Nginx
Nginx（エンジン・エックス）とは、Webサーバの一種です。本章の前半で述べましたが、ユーザーのリクエストに対して静的コンテンツの取り出し処理を行い、そして動的コンテンツの生成をアプリケーションサーバに依頼するためのものになります。
早速インストールしていきましょう。

###Nginxをインストールしよう
・ターミナル（EC2サーバ）

```bash
[ec2-user@ip-172-31-25-189 ~]$ sudo yum -y install nginx 
```

無事に完了すれば、Nginxがインストールできています。

###Nginxの設定ファイルを編集しよう
次に、Nginxが正しく動くように設定しましょう。

Nginxの設定は設定項目X 設定値x;という形式で入力していきます。

これも先ほどと同様に、vimコマンドを使ってターミナル上で編集していきます。/etc以下のファイルなので、強い権限でないと書き込み、保存ができません。そのため、コマンドの頭にsudoをつけています。

###1. rails.confファイルをvimで開きましょう
・ターミナル（EC2サーバ）

```bash
[ec2-user@ip-172-31-25-189 ~]$ sudo vim /etc/nginx/conf.d/rails.conf
```

###2. VimでNginxの設定を以下のように編集しましょう
・rails.conf

```ruby
upstream app_server {
  # Unicornと連携させるための設定。アプリケーション名を自身のアプリ名に書き換えることに注意。今回であればおそらくchat-space
  server unix:/var/www/<アプリケーション名>/tmp/sockets/unicorn.sock;
}

# {}で囲った部分をブロックと呼ぶ。サーバの設定ができる
server {
  # このプログラムが接続を受け付けるポート番号
  listen 80;
  # 接続を受け付けるリクエストURL ここに書いていないURLではアクセスできない
  server_name <Elastic IP>;

  # クライアントからアップロードされてくるファイルの容量の上限を2ギガに設定。デフォルトは1メガなので大きめにしておく
  client_max_body_size 2g;

# 接続が来た際のrootディレクトリ
  root /var/www/<アプリケーション名>/public;

# assetsファイル(CSSやJavaScriptのファイルなど)にアクセスが来た際に適用される設定
  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  try_files $uri/index.html $uri @unicorn;

  location @unicorn {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://app_server;
  }

  error_page 500 502 503 504 /500.html;
}
```

以下の３点は書き換えが必須です。

3行目の<アプリケーション名> となっている箇所は、ご自身のものに変更してください。
11行目の＜Elastic IP＞となっている箇所も同様に、ご自身のものに変更してください。
17行目の<アプリケーション名> となっている箇所は、ご自身のものに変更してください。

###3. nginxの権限を変更しましょう
設定が完了したら、POSTメソッドでもエラーが出ないようにするために、下記のコマンドも実行してください。

・ターミナル（EC2サーバ）

```bash
[ec2-user@ip-172-31-25-189 ~]$ cd /var/lib
[ec2-user@ip-172-31-25-189 lib]$ sudo chmod -R 775 nginx  
```

#####POSTメソッドとは、HTTP通信でクライアントからWebサーバへ送るリクエストの種類の一つで、URLで指定したプログラムなどに対してクライアントからデータを送信するためのものです。大きなデータやファイルをサーバに送るために使われます。
これで、Nginxの設定が完了しました。

###4. Nginxを再起動して設定ファイルを再読み込みしましょう。
・ターミナル（EC2サーバ）

```bash
[ec2-user@ip-172-31-25-189 lib]$ cd ~
[ec2-user@ip-172-31-25-189 ~]$ sudo service nginx restart
```

#unicorn.rbを修正しよう

Nginxを介した処理を行うためにunicornの設定を修正します。

###1. 次に以下のようにローカルでunicorn.rb修正しましょう
unicorn.rb

```ruby
listen 3000

↓以下のように修正

listen "#{app_path}/tmp/sockets/unicorn.sock"
```

###2. ローカルで編集したファイルをリモートへpushしましょう
修正をしたら忘れずに、commitとpushをし、サーバ側で以下のコマンドを実行して修正点を反映させておきましょう。

###3. ローカルの変更点を本番環境へ反映させましょう
ターミナル（EC2サーバ）

```bash
# まず、Appのディレクトリに移動
[ec2-user@ip-172-31-25-189 ~]$ cd /var/www/chat-space
[ec2-user@ip-172-31-23-189 <レポジトリ名>]$ git pull origin master
```

###4. Unicornを再起動しましょう
Unicornのプロセスをkillして、再起動する作業を行います。

ターミナル（EC2サーバ）

```bash
#プロセスの番号を確認します。
[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

#プロセスをkillします。
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ kill <確認したunicorn rails masterのPID（上のコードでは17877）>
...

#Unicornを起動します。
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ RAILS_SERVE_STATIC_FILES=1 unicorn_rails -c config/unicorn.rb -E production -D
...
```


#ブラウザからElastic IPでアクセスしましょう
ブラウザからElastic IPでアクセスすると、アプリケーションにアクセスできます（:3000をつける必要はありません）。なお、この時もunicornが起動している必要があります。

#IPアドレスにアクセスしてもエラーが出る時

・502 but gatewayとエラーが出る場合は、nginxのlogの確認が必要になります。/var/log/nginx/error.logをlessまたはcatコマンドで確認する。
・サーバ側で、/var/www/<レポジトリ名>/log/unicorn.stderr.logをlessまたはcatコマンドで確認し、エラーが出ていないか確認する（下に行くほど最新のログです。時刻表記がUTCであることに注意してください）
・Railsを起動しているか
・EC2インスタンスの再起動を行ってみる(※本番環境にてmysqlとnginxの起動が必要です。)




###Webサーバ
Webサーバとは、クライアントから送られてきたリクエストを受け取り、そのリクエストに応じたコンテンツをレスポンスとして返すプログラムです。ここでのクライアントとは、サイトを閲覧するブラウザのことを示します。

###アプリケーションサーバ
アプリケーションサーバは、動的なコンテンツを生成し、処理結果をWebサーバに返すという役割を果たします。具体的には、アプリケーションサーバが、アプリケーションサーバ内に設置されているアプリケーション本体にリクエスト処理の指令を出します。アプリケーション本体が処理を完了すると、アプリケーションサーバはその処理結果をレスポンスとしてWebサーバに返します。

###Webサーバとアプリケーションサーバについて
Webサーバ内で処理が出来るものとは、データベースと通信せずに、静的なコンテンツのみをリクエストとしてクライアントに返すものです。(※静的なコンテンツ：リクエストのたびに内容が変更されないファイルのこと。例：表示するものが定まっているCSSや、画像ファイルのこと）

アプリケーションサーバとアプリケーション本体は、使用している言葉が違うので、連携することが出来ません。この問題を解決してくれるのがRackといわれるものになります。
Rackとは、いわば翻訳プログラムになります。Rackが翻訳をすることにより、アプリケーションサーバとアプリケーション本体がコミュニケーションを取ることができ、処理結果をWebサーバに返すことが出来ます。

よって、アプリケーションサーバは2つの処理を担っています。：

・Webサーバから渡されてきた情報を、アプリケーションサーバ内で処理
・処理結果を、Webサーバに返す処理

Webサーバ内で処理をすることが出来ないと判断した場合は、処理をアプリケーションサーバに依頼します。Webサーバ内で処理が出来ないものとは、動的なコンテンツを生成し、リクエストとして返すものです。(※動的なコンテンツとは、リクエストのたびに内容が変更されるファイルのことです。例：検索リクエストのたびに、データベースから検索条件に該当するデータ取得して、表示するファイルのこと）
アプリケーションサーバに動的コンテンツの生成を依頼し、生成されたコンテンツがレスポンスが返ってくるので、Webサーバはその結果をクライアントに返します。
よって、Webサーバは3つの処理を担っています。：
・静的なコンテンツをレスポンスとしてクライアントに返す処理
・動的なコンテンツ生成をアプリケーション本体に依頼する処理
・アプリケーションサーバから返ってくる処理結果をレスポンスとしてクライアントに返す処理