Rails+Nginx+unicorn:サブディレクトリで複数のアプリを動作させる

はじめに

背景

この記事では、1台のサーバで複数のアプリを動作させるためのNginx、unicornの設定を記載します。

想定するシーンは「遊び用のレンタルサーバを借り、その中にいくつもRailsアプリを動作させたい」です。
アプリ1「http://123.456.789.000/app1」アプリ2「http://123.456.789.000/app2」のような形式で動作させます。

遊びが本格化してきたら、ドメインを当てて、SSLにしたいなー

記事公開時の環境は以下です。

RubyVersion                 2.3.0p0
RubyGems Version            2.5.2   
RailsVersion                5.0.2

NginxVersion                1.4.6 (Ubuntu)
UnicornVersion              5.3.0

構成のお勉強

Webサーバ:Nginx(他にもApacheなどが有名)
サーバ単位で動作させる。

アプリケーションサーバunicorn(他にもPassenger, Thin, Mongrelが有名)
Railsアプリケーション単位で動作させる。

アクセスをNginxが管理し、各アプリケーション等(unicorn)へ振り分けるイメージです。
Nginxとunicornの接続にはunixソケットを利用します。
インターネット == Nginx == [unicorn - Rails App]

事前準備

サーバ

事前にサーバの準備は完了している前提です。
サーバはさくらVPS Utuntu14.04を利用します。
プラン:さくらのVPS(v4) SSD 512 TK02

※TODO:そのうち記事に書く

前提

  • 任意のディレクト/rails1にあるRailsアプリケーションをサブディレクトhttp://123.456.789.000/app1で動作させる
  • rails1のパスは/home/user/rails1とする
  • Railsの動作環境はより手軽に動作させる想定でdevelopment

1. Nginxの設定

/etc/nginx

Nginxを設定していきます。Nginxのインストールが完了していれば、/etc/nginxに関連ファイルが作成されているはずです。

/etc/nginxにあるnginx.confがNginxの全体設定ファイル。
さらに、そこから詳細設定ファイルをconf.d/(もしくはsite-enable)をインクルードします。

各アプリのconf.d[myapp].confを作成し、設定を記述。
unicornとの接続にはunixソケットを利用するため、ソケット部分はnginxとunicornの設定ファイルで揃えること。

# unixソケットを定義。任意だが、`/tmp/[環境]_unicorn.sock`などが一般的。
# ソケットの部分はNginxとunicornの設定ファイルで揃えること。
upstream unicorn {
  server unix:/home/vex13/project/p_v3/tmp/development_unicorn.sock fail_timeout=0;
}

server {
  listen 80;
  server_name [サーバのIP/ドメイン];

  # サブディレクトリ形式の設定
  location /app1[サブディレクトリ] {
    alias /home/user/rails1[サブディレクトリのパス];
    # 下記のlocationを利用
    try_files $uri/index.html $uri.html $uri @unicorn;
    
  }

  location @unicorn {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_pass http://unicorn;
  }
}

# 複数のアプリケーションを立てるなら、同様にしてupstream, serverを記述する
# もしくは上記server内にupstream, locationを追加する
server {
}

2. Nginxの起動

$ sudo nginx -t #nginxの設定ファイル構文テスト
$ sudo service nginx start

3. unicornの設定

/home/user/rails1/confing/development_unicorn.rb

unicorn用の設定ファイルを作成します。

rails_root = '/home/user/rails1' # Railsのルートパス
rails_env = ENV['RAILS_ENV'] || "development"

worker_processes 2
working_directory rails_root

# ここが重要!Nginxで設定したunixソケットのパスと同一のものにすること。
# Unicorn Socket
# listen  '/tmp/unicorn.sock'
listen "#{rails_root}/tmp/#{rails_env}_unicorn.sock"

# Unicorn PID file location
# pid '/path/to/pids/unicorn.pid'
pid "#{rails_root}/tmp/pids/#{rails_env}_unicorn.pid"

# Path to logs
# stderr_path '/path/to/log/unicorn.log'
# stdout_path '/path/to/log/unicorn.log'
stderr_path "#{rails_root}/log/#{rails_env}_unicorn_error.log"
stdout_path "#{rails_root}/log/#{rails_env}_unicorn.log"

# Time-out
timeout 300

4. config.ruを設定

/home/user/rails1/config.ru

Railsアプリケーション内でのルートパス等をサブディレクトリで動作できるように設定する。
※当該ファイルを削除してもunicornがよしなに計らってくれて動作することもある。
※私はこのファイルの存在にハマって何時間か失った。。

# This file is used by Rack-based servers to start the application.
RAILS_RELATIVE_URL_ROOT="/app1[サブディレクトリ]"
require ::File.expand_path('../config/environment',  __FILE__)
if RAILS_RELATIVE_URL_ROOT then
        map RAILS_RELATIVE_URL_ROOT do
                run Rails.application
        end
else
        run Rails.application
end

5. unicornの起動

別途、起動、停止、再起動のスクリプトを書くべし。※TODO:そのうち記事に書く

$ bundle exec unicorn_rails -c config/development_unicorn.rb -D -E development --path /app1

まとめ

これで、http://123.456.789.000/app1Railsアプリケーションが動作するでしょう。
※さらっと書いてますが、13が幾度となく失敗、絶望を繰り返した結果の備忘です。

参考

qiita.com