LINEで現役エンジニアに直接質問してみよう!登録無料

Rails6(Puma)とNginxとソケット通信で連携させる方法

この記事のまとめ

Rails6(Puma)とNginxをソケット通信で連携させる方法を解説します。

Rails6やNginxを触り始めた人にとって、ソケット通信は理解できにくい部分の1つです。なぜなら、ソケット通信を理解するにはLinuxやUnix固有のUnixドメインソケットという知識が必要だからです。

この記事では、Rails6(Puma)とNginxでドメイン通信をサクッと実現する方法を紹介するので、まずはトライして見てください。

やること

Rails6のPumaとNginxをSocket通信で連携させてWebサービスを高速に配信する方法を紹介します。

通常、TCP通信を使って連携をするのですが、同じマシン内ではTCPよりもSocket通信の方がPC負荷が少なく高速動作が可能です。

その分、1台のサーバーで捌ける量も増えるので、メリットが多くオススメです。

Rails6のPuma設定

Rails6(Puma)とNginxをSocket通信するには、同じPC内で2つのプログラムが動いている場合のみです。別PCで動いている場合はTCPで通信しか出来ないので、注意しましょう!

ソケット通信のための設定

Pumaでsocket通信でNginxと連携させるため、config/puma.rbを編集します。

  1. ポートでのlistenは不要なのでコメントアウト
  2. socketの設定

ポートでのlistenは不要なのでコメントアウト

ポートでの設定を残しておくと、socket接続出来なくなってしまうでコメントアウトしましょう

socketの設定

config/puma.rbにsockファイルの場所を書きます。ディレクトリがない場合は作成しておきましょう

bind "unix://#{Rails.root}/tmp/sockets/puma.sock"
MEMO

sockファイルとは?

sockファイルとは、簡単に言うとLinuxやUnix系OS特有の機能で、ファイルの入出力を使ってPC内でデータのやり取りを行う仕組みです。

例えば、MySQLなどではhttp: //localhost:3306など「ホスト名 + ポート名」での接続を思い浮かぶかもしれません。しかし、sockファイル(正式名: Unixドメインソケット/ファイルシステムソケット)になると/tmp/mysql.sockというようなファイルで接続します。

これの実態はただのファイルなので、echo a > /tmp/mysql.sockのように情報を書き込めば、MySQL側に情報が伝わる仕組みになっています(但し、やり取りはバイナリの可能性もあり)。また、逆に読み込めばMySQLからのレスポンスを得られます。

このようにして、実際の入出力はこのファイルを通じて行われます。

Nginxの設定を変更

NginxとPumaを連携するには、Nginx側にも設定を追加する必要があります。先程、bindで記述したURIの内容を使います。

nginxの設定は/etc/nginx/conf.d/*に書きます。今回は/etc/nginx/conf.d/railsapp.confというファイル名で作成しました。

下記は、NginxとRailsを連携させるための最低限の設定です。

upstream rails {
  server unix:///<Railsまでのルートパス>/tmp/sockets/puma.sock;
}

server {
  listen 80;
  server_name <サーバー名>; # 本番環境のipアドレス

  location / {
    proxy_pass http://rails;
  }
}

クライアント情報をRailsアプリケーションに転送する

Railsなどのアプリケーションでは、ブラウザから送られてきたクライアント情報を使って情報を処理&表示していることがあります。

今の最低限の設定だと、Nginxがクライアント情報を上書きしてしまい、Railsに正確な情報が届きません。

ですので、下記のようにproxy_set_headerディレクティブを使って、情報を中継させてあげるのが普通です。

location / {
    proxy_redirect off;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
}

上から順番に意味を解説していきます。

  1. proxy_redirect off: 「Rails => Nginx」RailsからNginxに来たデータがNginxによってLocationヘッダが書き換えられないようにする設定です。
  2. $remote_addr
  3. proxy_add_x_forwarded_for: リクエストのX-Forwarded-Forに$remote_addrを足したもの。この情報でどのサーバーにプロキシされたか分かります。

まとめ

  • Rails6(Puma)とNginxでソケット通信するには両方の設定を変更します
  • Rails6(Puma)側の設定には2点の変更を加えます
    – ポートでのレッスンはコメントアウト
    bindでsockファイルの場所を指定する
  • Nginx側の設定では新しく設定ファイルを作ります
    upstreamを使ってRails(Puma)のsockファイルを指定します。
    – NginxからRails(Puma)に正確な情報を渡すためにproxy_set_headerを設定します。
    X-Forwarded-For Host X-Real-IPは最低限設定しておきましょう

以上、Rails6(Puma)とNginxでソケット通信をする方法をアキ(@hackablejp)が解説しました!

この記事を書いた人

自身がプログラミングを独学で勉強し始めて躓いた経験を元に、これから勉強をする人に向けに「イラスト多めでわかりやすい記事」にこだわって情報を発信しています。

現在はフルスタックエンジニアとしてサービス開発などのお仕事をしています。