LoginSignup
5
2

More than 1 year has passed since last update.

【Amazon Linux2】【Rails】Nginxをpumaのunixドメインソケットでリバースプロキシする設定

Last updated at Posted at 2021-08-15

背景

ポートフォリオをEC2で公開するときにrails serverだとhttpで3000番ポートで通信をしなければならず、アクセスログの取得が不可で、かつアクセス負荷に対応ができません。
そういった場合、Nginxを利用してpumaをunixドメインソケットでリバースプロキシをする場合、接続方法でハマってしまったので、備忘録を兼ねてまとめます。

環境

EC2(AmazonLinux2)
Nginx 1.20
puma 5.2.2
ruby 2.7.2
Rails 6.1
MySQL 5.7

puma

WEBサーバーの一つ。Railsではアプリケーションサーバーとしてよく使われていると思います。
速度やメモリ効率に強みを持つらしい。同様のサーバーではunicornなどがある。
pumaとunicornの比較はこの以下のサイトがわかりやすかったです。

Pumaの使い方 まとめ

puma設定ファイル

config/prd_puma.rb
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count

worker_timeout 3600 if ENV.fetch("RAILS_ENV", "production") == "production"

bind "unix:///var/www/アプリ名/shared/sockets/puma.sock"

environment ENV.fetch("RAILS_ENV") { "production" }

pidfile ENV.fetch("PIDFILE") { "shared/pids/server.pid" }

plugin :tmp_restart
ディレクティブ 説明
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } 変数max_threads_countを定義
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } 変数min_threads_countを定義
threads min_threads_count, max_threads_count スレッドの最小数, 最大数を定義
worker_timeout 3600 if ENV.fetch("RAILS_ENV", "production") == "production" pumaのworkerのタイムアウト時間を定義
bind "unix:///var/www/アプリ名/shared/sockets/puma.sock" bindでどのように接続するかをURIで指定。今回はunixソケット経由で接続
environment ENV.fetch("RAILS_ENV") { "production" } pumaをどの環境で動作させるか指定。今回はproduction
pidfile ENV.fetch("PIDFILE") { "shared/pids/server.pid" } PIDファイルの設置場所
plugin :tmp_restart pumaに機能追加するときに使う。デフォルトでtmp_restart。pumaを再起動することでできる

Nginx

NginxとはWEBサーバーの一つです。
ApacheというWEBサーバーの弱点であるC10k(Connect 10 × 1000 = 10,000の通信)問題を回避したWEBサーバーです。
Apacheは1アクセスに対して1対応する仕様なので、つ通信が10,000くると、負荷が大きくなってしまう弱点がありました。これに対して、Nginxは複数の通信に対して1対応なのでアクセス数の増加に比例して急激な負荷の増加を抑えられるそうです。

Nginx設定ファイル

EC2ターミナル
$ sudo amazon-linux-extras install nginx1

ちなみにamazon-linux-extrasとは、AmazonLinux2に存在するExtras Libraryというパッケージ群を操作するコマンドです。
もしAmazonLinux1を使っている場合には、amazon-linux-extrasコマンドはないのでyumというコマンドを使いましょう。

EC2ターミナル
$ nginx -v
->nginx version: nginx/1.20.0

インストールされていれば、バージョンが表示されます。

次に自分のアプリ専用にNginx設定ファイルを作りましょう。

インストールすると、/etc配下にnginx/nginx.confnginx/conf.dというディレクトリが生成されているはずです。
Nginxにはnginx.confには、Nginx自体の設定(起動, アクセス負荷チューニング等)を書きます。このファイルにもバーチャルホストを書くことはできますが、わかりやすくするためバーチャルホスト*の設定はnginx/conf.d配下にアプリ名.confを作りそこに書きましょう。

*バーチャルホストとは
デフォルトのバーチャルホストとは、複数のサイトが運用されているウェブサーバーに、IPアドレス(ドメイン名ではなく)でHTTPリクエストした場合に応答するホストのことです。
引用:nginxでデフォルトのバーチャルホストを設定する方法

アプリ名.confの書き方は以下のとおりです。

EC2ターミナル
$ sudo vi /etc/nginx/conf.d/アプリ名.conf

viコマンドでファイルの編集+新規作成ができます。
viについてはコマンドモードと入力モードを抑えておけばとりあえず大丈夫だと思います。コマンドモード中にiを押すと入力モードへ、入力モード中にescを押すとコマンドモードになります。

  1. iを押して入力モードへ
  2. 内容を編集
  3. escでコマンドモードへ
  4. :wqで保存して終了
コマンド 説明
i insert(入力)モード
esc コマンドモード
:wq 保存して終了
:q! 保存せずに終了

*もちろんまだまだ重要なコマンドはあるので気になる方は調べてみましょう!

/etc/nginx/conf.d/アプリ名.conf
upstream puma {
  server unix:/var/www/アプリ名/shared/sockets/puma.sock fail_timeout=0;
}

server {
  listen 80;
  server_name [ドメイン(ない場合はElastic IP];

  root /var/www/アプリ名/public;
  error_log  /var/log/nginx/error.log;
  access_log /var/log/nginx/access.log;
  client_max_body_size 2G;
  keepalive_timeout 5;

  # page cache loading
  try_files $uri/index.html $uri.html $uri @app;
  location / {

    # HTTP headers
    proxy_set_header X-Real-IP $remote_addr;
    index index.html index.htm;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://puma;

  }

}

設定ファイルの雛形はインストール後に自動生成されるnginx/nginx.confを見ると良いと思います。

設定ファイルの説明は以下のとおりです。

ディレクティブ 説明
upstream {}
server unix:/var/www/アプリ名/shared/sockets/puma.sock fail_timeout=0; UNIXドメインのpumaソケットファイルを指定
server {} バーチャルホストを定義
listen 80; バーチャルホストが使用するポートを指定
server_name [ドメイン(ない場合はElastic IP]; バーチャルサーバー内で使うホスト名としてドメイン名を指定
root /var/www/アプリ名/public; 公開するディレクトリを指定
error_log /var/log/nginx/error.log; エラーログの出力先を設定 (/var/log配下だとわかりやすい)
access_log /var/log/nginx/access.log; アクセスログの出力先を設定 (/var/log配下だとわかりやすい)
client_max_body_size 2G; Nginxが受信可能なリクエストボディの量を指定
keepalive_timeout 5; HTTP通信をタイムアウトを待つ秒数を指定
try_files \$uri/index.html \$uri.html $uri @app; 指定したファイルパスがある場合はリダイレクト、ない場合はその次のファイルパスへと繰り返し、最後までない場合は最後に指定されたURIへとリダイレクト
location URI {} リクエストされたURIにマッチししたときに使われる設定。設定は{}内に書く。
proxy_set_header XXXX リクエストをプロキシする際にヘッダを付与する
X-Real-IP $remote_addr; X-Real-IPで送信元を判別、$remote_addrで送信元IPを取得
index インデックスページとして表示するファイルを指定
X-Forwarded-Proto $scheme; ユーザーリクエストが使ったHTTPスキームを指定
X-Forwarded-For $proxy_add_x_forwarded_for; リクエストが経由したアドレス全てを指定
Host $http_host; ユーザーリクエストに含まれるホスト名を指定
proxy_redirect レスポンスヘッダをどのように書き換えるかを指定(今回はoff)
proxy_pass 転送先URI リクエストを転送先URIにプロキシ**する。今回はupstreamでpumaとして定義したpuma.sockに転送。

エラーが起きたとき
cat /var/log/nginx/error.logを見てデバッグしましょう。(権限なければ sudoを頭につけてください。)

アクセスログ確認方法
cat /var/log/nginx/access.log

用語解説

$: 変数を展開している。Nginxではもともと定義されている予約語的な変数がある。今回はほとんど予約語を使っている。
フォワードプロキシ: 一般に「プロキシ」と呼ばれる。クライアントとサーバーの間に設置し、 内部ネットワークからインターネットへの通信を中継する。主にセキュリティ目的
リバースプロキシ: WEBサーバーの前に設置し、WEBサイトへのリクエストを代理受付する。主にセキュリティ目的

Unixドメインソケット:

 ソケットは「受け口、接合部」の意味。「UNIXドメインソケット」とは、LinuxなどのUNIX系OS(オペレーティングシステム)で実行されるプロセス間のデータ通信の終点に使われるインターフェースのことをいう。
 LinuxなどのUNIX系OSは、各種デバイスの入出力にデバイスファイルというインターフェースを利用するため、一般のファイルを読み書きするのと同じ手順で周辺機器を操作できる。ところが、プロセス同士がネットワーク経由で通信するときには、ファイル・インターフェースを拡張した「ソケット」というインターフェースが必要になる。通常インターネットで利用しているソケット通信(INETドメインソケット通信)とは異なり、ネットワーク経由ではないローカルマシン上のプロセスが利用するソケットが、UNIXドメインソケットである。
引用:UNIXドメインソケット

まとめ

  • プロキシとはクライアントとサーバー間に設置することで内部から外部への通信を中継してくれる。
  • リバースプロキシはWEBサーバーの前に設置することでWEBサイトへのリクエストを代理受付してくれる。例えば会社であれば誰がどのサイトにアクセスしたか等を見ることができセキュリティ強化に繋がる。
  • Nginxとpumaをリバースプロキシさせることで、アクセス負荷対策やrails serverでは取得できないアクセスログを取得できる

未経験の立場からすると、サーバーサイドエンジニア志望となるとサーバーサイド言語の勉強に偏りがちですが、Nginxやpuma等のサーバーそのものの勉強は必須だと感じました。
言語と並行してWEB周りの知識も付けていきたいと思います。

参考

puma
- RackサーバーのPumaについて調べてみる
- Pumaの使い方 まとめ
- 【Rails】puma.rbの気になるあれこれ

Nginx
- ex1-lab
- Carpe Diem
- 8.1.11 proxy_redirect
- WEBプロキシとは? 仕組みや機能・メリットについて解説

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2