Railsで開発したWebアプリケーションを公開するときは、「Nginx」などのWebサーバと連携するのが一般的です。
Railsは内部で「Puma」というWebサーバを起動していますが、Webサーバとしての機能が貧弱なため、アプリケーションサーバとして使われることのほうが多いからです。
今回は、アプリケーションサーバとして使っているPumaを、WebサーバであるNginxと連携させて、大量のアクセスにも耐えられるようにします。
利用する環境は、「Railsの環境構築」で構築したRails環境をもとに進めていきます。
RailsとPumaの関係がわからない方は、さきに以下の記事を読んでもらえるとスムーズです。

もくじ
Railsアプリの場所を確認
まずは、Railsアプリが置いてある場所を確認してみましょう。
「Railsの環境構築」を読みながらRailsアプリを作った方は、以下のようにホームディレクトリの下にRailsアプリがあると思います。
「/home/vagrant/training/training_app」
まずは、この「training_app」を「/opt」の下に移動、またはコピーしましょう。
なぜなら、公開するアプリを置いておく場所として、ホームディレクトリは適切ではないからです。
また、「/home/vagrant」にアクセスできるのは「vagrantユーザー」だけですが、今回は「nginxユーザー」がRailsアプリのディレクトリにアクセスする予定なので、ホームにあると都合が悪いのもあります。

# 移動する場合
$ sudo mv ~/training/training_app /opt/
# コピーする場合
$ sudo cp -arf ~/training/training_app /opt/
# ファイルを確認
$ ls -al /opt/
total 4
drwxr-xr-x. 3 root root 26 Apr 24 07:42 .
dr-xr-xr-x. 18 root root 248 Apr 4 01:56 ..
drwxrwxr-x. 14 vagrant vagrant 4096 Apr 24 01:12 training_app

Pumaのソケット通信設定
Rails(Puma)とNginxを連携させるために、Pumaの設定ファイルを修正します。
具体的には、「UNIXドメインソケット通信(ソケット通信)」をするための設定になります。
このソケット通信は、NginxとRailsが同じマシンに存在している場合のみできる設定です。
ソケットの設定
Pumaを起動したときに、ソケットである「puma.sock」を生成するよう設定します。
「puma.sock」は、Nginxとソケット通信をする際に必要になるファイルです。
# Pumaの設定ファイルを開く
$ vi /opt/training_app/config/puma.rb
:
:
# 追記
bind "unix://#{Rails.root}/tmp/sockets/puma.sock"

ちなみに、ホームの下にRailsアプリがあると、NginxはPumaとソケット通信できないので注意してください。
これは、「puma.sock」もホームディレクトリの下に生成されてしまい、nginxユーザーの権限ではアクセスできないためです。
どうしてもホームディレクトリ以下で実行させたい場合は、「bind "unix:///tmp/puma.sock"」などのようにNginxがアクセスできるディレクトリにバインドする必要があります。
デーモン化
「rails s」コマンド実行時、Pumaをバックグラウンドで動かしたい場合は、以下を記述してください。
# Pumaの設定ファイルを開く
$ vi /opt/training_app/config/puma.rb
:
:
# 追記
daemonize true
Pumaを停止したいときは、「kill」コマンドを使います。
# Pumaのプロセス番号を確認
$ ps aux | grep puma
vagrant 3117 0.0 2.9 910968 55008 ? Sl 08:26 0:00 puma 3.12.1 (tcp://localhost:3000,unix:///opt/training_app/tmp/sockets/puma.sock) [training_app]
vagrant 3160 0.0 0.0 112708 972 pts/0 S+ 08:27 0:00 grep --color=auto puma
# Pumaを停止
$ kill -9 3117

NginxとPumaの接続設定
ここからは、NginxとPumaの接続設定をおこないます。
Nginxのインストールが済んでいない方は、以下の記事を読みながらインストールを進めてください。

設定ファイルの作成
ここからは、「training_app」という名前のアプリケーションがあると仮定して進めていきます。
まずは、このアプリケーション専用のNginxの設定ファイルを作りましょう。
アプリごとの設定ファイルは「/etc/nginx/conf.d/」の下に新規で作成し、Nginx全体に関わる設定は「/etc/nginx/nginx.conf」を編集するようにします。
今回はアプリ単体の設定なので「/etc/nginx/conf.d/training_app.conf」を作成します。
また、既存の「/etc/nginx/conf.d/default.conf」は、不要であれば削除してもいいのですが、今回は何かあったときのバックアップとして残しておきます。
# default.confの無効化と同時にバックアップ
$ sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf_bk
# 設定ファイルを作成
$ sudo vi /etc/nginx/conf.d/training_app.conf
ファイルを開いたら、以下の内容で上書きしましょう。
upstream training_app {
# UNIXドメインソケット通信の設定
server unix:///opt/training_app/tmp/sockets/puma.sock fail_timeout=0;
}
server {
# 80番ポートを許可
listen 80;
# host名を指定
server_name 192.168.33.10;
# 静的ファイル(画像など)のパスをドキュメントルートに設定
root /opt/training_app/public;
# ドキュメントルート配下を以下の先頭から順番に辿る
try_files $uri/index.html $uri @training_app;
# 上記の@training_appが呼び出された場合のみ以下の設定を読み込む
location @training_app {
proxy_pass http://training_app;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
}
Nginxにアクセス
Nginxの設定ファイルを変更したら、Nginxを再起動し、Railsを起動します。
# Nginxを再起動
$ sudo systemctl restart nginx
# Railsを起動
$ rails s
ブラウザからNginxにアクセスしてみましょう。
「Linux環境構築」を読んでVagrantで構築した方は、「http://192.168.33.10」でアクセスできるはずです。
SELinuxの設定変更
ブラウザに「502 Bad Gateway」と表示された方は、SELinuxの影響を受けている可能性があります。
SELinux(Security Enhanced Linux)とは、簡単に説明すると、ディレクトリやファイルのアクセスを制御をするためのカーネル機能です。
本来であれば、SELinuxを正しく理解し設定するべきなのですが、ここではアクセス制御を「Permissive」にすることで対応します。
- 「Enforcing」…SELinuxが有効
- 「Permissive」…SELinuxが有効(アクセス制御はせずに警告のみ)
- 「Disabled」… SELinuxが無効
# SELinuxの状態を確認
$ getenforce
Enforcing
# アクセス制御を無効化
$ sudo setenforce 0
# SELinuxが無効になっていることを確認
$ getenforce
Permissive
このままだと、Linuxを再起動したときに、またアクセス制御が有効になってしまいます。
再起動してもアクセス制御が無効になるように、以下のファイルも修正しておきます。
$ sudo vi /etc/selinux/config
:
:
# SELINUX=enforcingを以下に変更
SELINUX=disabled
:
:
SELinuxの設定が終わったら、もう一度ブラウザからアクセスしてみましょう。
まとめ:NginxのSSL設定にも挑戦してみよう!
今回は、「/opt」にRailsアプリがあるという前提で解説しました。
環境によって対応方法も変わってきますが、どの環境であっても以下がポイントになると思います。
- パーミッション
- UNIXドメインソケット通信
- SELinuxの設定
自分がハマっている原因が、上のどれに当てはまるのかさえ見極めることができれば、Nginxとの連携自体は難しくありません。落ち着いて対応しましょう。
Nginx連携のあとは「NginxのSSL設定」を読んで、WebサイトのSSL化にも挑戦してみてくださいね。
またね、キツネ(@kitaaaa_kitsune)でした!

