hiyoko-programingの日記

プログラミングを勉強したてのひよっ子。   エンジニア目指して勉強中。

Nginx経由でRailにアクセス

Webサーバとアプリケーションサーバ

クライアントとサーバの全体像を以下の図に示した。
一体、Webサーバとアプリケーションサーバの違いは何なのか?
https://tech-master.s3.amazonaws.com/uploads/curriculums//4acde8a3a9f3cdd5910090f77efb1972.png

 Webサーバ

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

① クライアントからのリクエスト全てがWebサーバに送られる。
https://tech-master.s3.amazonaws.com/uploads/curriculums//5b8b625d3be3f34b6c9b07d9edffc143.png

② Webサーバが、Webサーバ内で処理することが出来ると判断すれば、ブラウザにレスポンスを返す。

https://tech-master.s3.amazonaws.com/uploads/curriculums//932ffe6a9c2f5a9bbf76d055c0ee82b7.png
Webサーバ内で処理が出来るものとは、データベースと通信せずに、静的なコンテンツのみをリクエストとしてクライアントに返すものです。(※静的なコンテンツ:リクエストのたびに内容が変更されないファイルのこと。例:表示するものが定まっているCSSや、画像ファイルのこと)

 

③ Webサーバから渡されてきた情報を、アプリケーションサーバ内で処理する
https://tech-master.s3.amazonaws.com/uploads/curriculums//d69e9df7db40f572d32476d45d3b9337.png

④ 処理結果を、Webサーバに返す

https://tech-master.s3.amazonaws.com/uploads/curriculums//07d985b522f4e9374dbb55bd872a619c.png
しかし、ここで1つ問題がある。
アプリケーションサーバとアプリケーション本体は、使用している言葉が違うので、連携することが出来ない。この問題を解決してくれるのがRackといわれるもの。
Rackとは、いわば翻訳プログラム。Rackが翻訳をすることにより、アプリケーションサーバとアプリケーション本体がコミュニケーションを取ることができ、処理結果をWebサーバに返すことが出来る。

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

 

アプリケーションサーバから返ってくる処理を、ブラウザにレスポンスとして返す。
https://tech-master.s3.amazonaws.com/uploads/curriculums//7ccf6b145dde5f26c5c478e561ebff2b.png

Webサーバ内で処理をすることが出来ないと判断した場合は、処理をアプリケーションサーバに依頼する。Webサーバ内で処理が出来ないものとは、動的なコンテンツを生成し、リクエストとして返すもの。(※動的なコンテンツとは、リクエストのたびに内容が変更されるファイルのこと。例:検索リクエストのたびに、データベースから検索条件に該当するデータ取得して、表示するファイルのこと)

アプリケーションサーバに動的コンテンツの生成を依頼し、生成されたコンテンツがレスポンスが返ってくるので、Webサーバはその結果をクライアントに返す。

よって、Webサーバは3つの処理を担っている。

  • 静的なコンテンツをレスポンスとしてクライアントに返す処理
  • 動的なコンテンツ生成をアプリケーション本体に依頼する処理
  • アプリケーションサーバから返ってくる処理結果をレスポンスとしてクライアントに返す処理

 

 アプリケーションサーバ

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

Nginxの導入と設定

 Nginx

Nginx(エンジン・エックス)とは、Webサーバの一種。ユーザーのリクエストに対して静的コンテンツの取り出し処理を行い、そして動的コンテンツの生成をアプリケーションサーバに依頼するためのもの。

Nginxをインストールする

ターミナル(EC2サーバ)
1
[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サーバ)
1
[ec2-user@ip-172-31-25-189 ~]$ sudo vim /etc/nginx/conf.d/rails.conf

 2. VimでNginxの設定を以下のように編集する

rails.conf
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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ファイル(CSSJavaScriptのファイルなど)にアクセスが来た際に適用される設定
  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点は書き換えが必須。

  1. 3行目の<アプリケーション名> となっている箇所は、自身のものに変更。
  2. 11行目の<Elastic IP>となっている箇所も同様に、自身のものに変更。
  3. 14行目の<アプリケーション名> となっている箇所は、自身のものに変更。

※この場合<>は記入不要なもの/表示されないもの。

 3. nginxの権限を変更する

設定が完了したら、POSTメソッドでもエラーが出ないようにするために、下記のコマンドも実行。

ターミナル(EC2サーバ)
1
2
[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サーバ)
1
2
[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修正

1
2
3
4
5
listen 3000

↓以下のように修正

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

 2. ローカルで編集したファイルをリモートへpush

修正をしたら忘れずに、commitとpushをし、サーバ側で以下のコマンドを実行して修正点を反映させておく。

 3. ローカルの変更点を本番環境へ反映させる

ターミナル(EC2サーバ)
1
2
3
# まず、chat-spaceのディレクトリに移動
[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サーバ)
1
2
3
4
5
[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サーバ)
1
2
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ kill <確認したunicorn rails masterのPID(上のコードでは17877)>
...

Unicornを起動する。

ターミナル(EC2サーバ)
1
2
[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アドレスにアクセスしてもエラーが出る時

IPアドレスにアクセスするとエラーが表示されたり、想定通りの画面が表示されないことがある。以下の点を確認してみましょう。

  • サーバ側で、/var/www/<レポジトリ名>/log/unicorn.stderr.loglessまたはcatコマンドで確認し、エラーが出ていないか確認する(下に行くほど最新のログです。時刻表記UTCであることに注意)
  • Railsを起動しているか
  • カリキュラムどおりに関連ファイルの記載ができているか
  • カリキュラムどおりにコマンドを実施したか
  • EC2インスタンスの再起動を行ってみる(※本番環境にてmysqlとnginxの起動が必要。)

まとめ

Webサーバ

  • Webサーバとは、外部から送られてきたリクエストを受け取り、処理を加えるプログラム
  • Webサーバには3つの役割が存在する
  1. 静的なコンテンツをレスポンスとしてクライアントに返す処理
  2. 動的なコンテンツの生成を、アプリケーションサーバに依頼する処理
  3. アプリケーションサーバから返ってくる処理結果をレスポンスとしてクライアントに返す処理

アプリケーションサーバ

  1. Webサーバから依頼された情報を元に、動的なコンテンツの生成を行う。
  2. 処理結果を、Webサーバに返す処理

サーバについて

サーバの種類と、それぞれの役割を理解していれば、何らかの問題に遭遇した時に適切に対処することができる。