yuuki blog

プログラミング をアプトプットしています。

AWS (Webサーバーの設定方法)

サーバーの種類

サーバには複数の種類があり、ここではクローンしたアプリケーションを起動するために必要な「Webサーバー」と「アプリケーションサーバー」について理解を深めましょう。

 Webサーバー

「Webサーバー」とは、静的コンテンツのみをリクエストとしてクライアントに返します。ここでいう「クライアント」とは、サイトを閲覧するブラウザのことを示します。

 静的コンテンツ

「静的コンテンツ」とは、リクエストのたびに内容が変更されないファイルのことです。例として、表示するものが定まっているCSSや、画像ファイルなどがあります。

 アプリケーションサーバ

アプリケーションサーバー」は、動的コンテンツを生成し、処理結果を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サーバ内で処理ができるものとは、データベースと通信せず、「静的コンテンツのみ」をリクエストとしてクライアントに返すものです。

次に、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」とは、いわば翻訳プログラムになります。Rackが翻訳をすることにより、アプリケーションサーバーとアプリケーション本体がコミュニケーションを取ることができ、処理結果をWebサーバーに返すことができます。

ここまでをまとめると、アプリケーションサーバーの役割は以下の2つとなります。

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

次に、アプリケーションサーバーから返ってくる処理を、ブラウザにレスポンスとして返します。

https://tech-master.s3.amazonaws.com/uploads/curriculums//7ccf6b145dde5f26c5c478e561ebff2b.png

Webサーバー内で処理をすることが出来ないと判断した場合は、処理をアプリケーションサーバーに依頼します。Webサーバー内で処理が出来ないものとは、「動的コンテンツ」を生成し、リクエストとして返すものです。

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

ここまでをまとめると、Webサーバーの役割は以下の3つとなります。

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

ここからは、Webサーバーである「Nginx」の導入と設定を行います。

 Nginx(エンジン・エックス)

「Nginx」とは、Webサーバーの一種です。ユーザーのリクエストに対して静的コンテンツのみ取り出し処理を行い、動的コンテンツの生成はアプリケーションサーバに依頼します。

Nginxを導入しよう

それでは早速、Nginxを導入しましょう。

 ターミナルで以下のコマンドを実行し、Nginxを導入しましょう

今回は、Nginxの中でも「Nginx1」というバージョンを導入します。

ターミナル(EC2内で実行)
 
[ec2-user@ip-172-31-25-189 ~]$ sudo amazon-linux-extras install nginx1

Is this ok [y/d/N]:と出てきたら、yを選択して決定してください。

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

Nginxの設定ファイルを編集しよう

次に、Nginxが正しく動くように設定しましょう。

Nginxの設定は「設定項目X 設定値x;」という形式で入力します。
それでは、順に進めていきましょう。

以下の手順で、Nginxの設定ファイルを編集しましょう

ターミナルで以下のコマンドを実行しましょう。

ターミナル(EC2内で実行)
1
[ec2-user@ip-172-31-25-189 ~]$ sudo vim /etc/nginx/conf.d/rails.conf

うまくターミナル上でファイルを開けたら次のように編集してください。

 「アプリケーション名」と「Elastic IP」の部分は適宜ご自身のものに置き換えましょう。
要注意の箇所 行番号
アプリケーション名 3 , 17
Elastic IP 11
/etc/nginx/conf.d/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と連携させるための設定
  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;
}

入力を終えたら「escキー」→「:wq」の順で実行し、保存しましょう。

次は、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  

これで、Nginxの設定が完了しました。
それでは、以下のコマンドを実行してNginx設定ファイルを再読み込みして起動しましょう。

ターミナル(EC2内で実行)
1
2
3
[ec2-user@ip-172-31-25-189 lib]$ cd ~
[ec2-user@ip-172-31-25-189 ~]$ sudo systemctl start nginx
[ec2-user@ip-172-31-25-189 ~]$ sudo systemctl reload nginx

Unicornの設定を変更

Nginxを介した処理に変更したため、Unicornの設定も修正します。

以下の手順で、Unicornの設定を変更します

config/unicorn.rb
1
2
3
4
5
(省略)

listen 3000

(省略)

↓↓↓↓↓以下のように修正↓↓↓↓↓

config/unicorn.rb
1
2
3
(省略)

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

編集したら、リモートリポジトリへ「commit→push」しましょう。

 別にブランチを切っている場合は、masterブランチにmergeしてから以下のコマンドを実行しましょう。

次は、GitHubの変更点を本番環境へ反映させましょう。

ターミナル(EC2内で実行)
1
2
3
4
5
# 開発中のアプリケーションに移動
[ec2-user@ip-172-31-25-189 ~]$ cd /var/www/開発中のアプリケーション

# GitHubの内容をEC2に反映させる
[ec2-user@ip-172-31-23-189 <レポジトリ名>]$ git pull origin master

次は、Unicornを再起動しましょう。
再起動の手順は、

①プロセスを確認
②プロセスをkill
unicorn_railsコマンドを実行

となります。

ターミナル(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
# 上記の例だと「7877」
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ kill プロセス番号

最後に、Unicornを起動します。

ターミナル(EC2内で実行)
1
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ RAILS_SERVE_STATIC_FILES=1 unicorn_rails -c config/unicorn.rb -E production -D

ここまでできたら、ブラウザからElastic IPでアクセスしましょう。

 「http://<Elastic IP>:3000/」ではないので注意しましょう。

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

Railsが起動しない」「ブラウザで確認するとエラーが表示されている」などの問題がある場合、まずは「エラーログ」を確認する必要があります。

ここでは「502 but gateway」と出た時の対処方法を学びましょう。

「502 but gateway」と出た時の対処方法を学びましょう

こちらのエラーはnginxのlogの確認が必要になります。

以下のコマンドを実行し、ログを確認しましょう。

ターミナル(EC2内で実行)
1
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$  sudo less /var/log/nginx/error.log

この中からエラーログを探します。