【Ruby on Rails】unicornをNginx環境下で動かす時の設定方法

【Ruby on Rails】unicornをNginx環境下で動かす時の設定方法

こんにちは、nishi_talk(@nishi_talk)です。
今回はRailsで作ったアプリを本番環境で動かす時に使うunicornの設定をご紹介します。
Railsで作ったアプリを本番環境(production)でunicornを使って動かしてみたいと思います。

unicornとはrailsとかで作ったアプリケーションを動かすアプリケーションサーバーでプロセス上で動作するサーバーです。
(ざっくり説明するとRailsを動かしてくれるサーバーって感じかなー)
ココらへんのはUnicornとNginxの概要と違い – Qiitaで解説されています。

unicornをインストール

まずはRailsのアプリ側で設定をします。
railsアプリのGemfileをします。
コメントアウトされている場合はコメントアウトを外してください。
記述が無い場合は追加してください。

 gem 'unicorn'

保存したら、unicornをインストールします。

$ bundle install

これでunicornのインストールはOKです。



unicornの設定

Railsのアプリがあるディレクトリのconfig以下にunicorn.rbを新規作成します。

vim config/unicorn.rb
# unicorn.rbを新規作成
$ vim config/unicorn.rb

そして以下の記述をします。

#{app_name}の箇所はご自身のファイルパスを記述してください。
worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)
 timeout 15
 preload_app true

 listen '/var/www/{app_name}/tmp/unicorn.sock'
 pid    '/var/www/{app_name}/tmp/unicorn.pid'

 before_fork do |server, worker|
   Signal.trap 'TERM' do
     puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
     Process.kill 'QUIT', Process.pid
   end

   defined?(ActiveRecord::Base) and
     ActiveRecord::Base.connection.disconnect!
 end

 after_fork do |server, worker|
   Signal.trap 'TERM' do
     puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
   end

   defined?(ActiveRecord::Base) and
     ActiveRecord::Base.establish_connection
 end

 stderr_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])
 stdout_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])

unicornの起動・停止をするスクリプトを作成

ここは作らなくてもいいみたいですが、一度作っておくと後が楽になるのでunicornの起動・停止するスクリプトを作成します。
Railsのディレクトリで以下のコマンドを実行します。

$ rails g task unicorn

「lib/tasks」に「unicorn.rake」ファイルが生成されるので以下の記述を追加。
以下は本番環境で動作するスクリプトです。
開発環境で動かす場合は、unicorn.rakeにあるproductionの記述をdevelopmentに変更してください。
※本番環境だとパーミッションのエラーが発生する場合があるので、要注意してください。

$ vim lib/tasks/unicorn.rake
#{app_name}の箇所はご自身のファイルパスを記述してください。

namespace :unicorn do

   # Tasks
   desc "Start unicorn"
   task(:start) {
     config = Rails.root.join('config', 'unicorn.rb')
     sh "unicorn -c #{config} -E production -D"
   }

   desc "Stop unicorn"
   task(:stop) {
     unicorn_signal :QUIT
   }

   desc "Restart unicorn with USR2"
   task(:restart) {
     unicorn_signal :USR2
   }

   desc "Increment number of worker processes"
   task(:increment) {
     unicorn_signal :TTIN
   }

   desc "Decrement number of worker processes"
   task(:decrement) {
     unicorn_signal :TTOU
   }

   desc "Unicorn pstree (depends on pstree command)"
   task(:pstree) do
     sh "pstree '#{unicorn_pid}'"
   end

   # Helpers
   def unicorn_signal signal
     Process.kill signal, unicorn_pid
   end

   def unicorn_pid
     begin
       File.read("/var/www/{app_name}/tmp/unicorn.pid").to_i
     rescue Errno::ENOENT
       raise "Unicorn does not seem to be running"
     end
   end

 end

unicornの起動と停止

unicornを以下のコマンドを実行して起動します。

# rails unicorn:start
unicorn -c /{ドキュメントルート}/{app_name}/config/unicorn.rb -E production -D

上記の表示したらOK。エラーが発生した場合は、上記以外にも表示されます。

Unicornが起動しているかどうかを確認するにはコマンド。

# ps -ef | grep unicorn | grep -v grep

起動していれば、4行くらい表示されます。停止している場合は、何も表示されません。

unicornを停止させるには

# rails unicorn:stop

再起動させるには

rails unicorn:stop && rails unicorn:start

起動が確認できたら、Nginxの設定をおこないます。

Nginxの設定

Nginxの初期設定は/etc/nginx/conf.d/default.confに記述されています。
初期設定のままでもNginxの設定はできますが、{app_name}.confを作成したほうが後々の管理が楽になるので、今回は新規作成して設定をおこないます。
default.confの影響でNginxが起動しない場合があるみたいです。そんなときはdefault.confの必要ない箇所はコメントアウトして起動してみてください。

Nginxの初期設定はここらへんの記事を参考にしてください。

【さくらVPS】CentOS7で、Nginxを設定する方法

# 初期設定ファイルをコピー
#{app_name}の箇所はドメイン名などでわかりやすくする。
cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/{app_name}.conf
vi /etc/nginx/conf.d/{app_name}.conf
#{ドキュメントルート}と{app_name}の箇所はご自身のパスに書き換えてください。
# {ドメイン名}の箇所はドメイン名もしくはIPアドレスを指定してください。

upstream unicorn {
server  unix:/{ドキュメントルート}/{app_name}/tmp/unicorn.sock;
}

server {
    listen       80;
    server_name  {ドメイン名};

    access_log  /var/log/nginx/access.log;
    error_log   /var/log/nginx/error.log;

    root /{ドキュメントルート}/{app_name}/public;

    client_max_body_size 100m;
    error_page  404              /404.html;
    error_page  500 502 503 504  /500.html;
    try_files   $uri/index.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;
    }
}



Nginxの起動

設定ファイルを編集したら、Nginxを起動させます。

# systemctl start nginx

すでに起動している場合は再起動。

# systemctl restart nginx

無事に起動できればOK!

エラーが発生した場合

unicornの場合

# vim /{ドキュメントルート}/{app_name}/log/unicorn.log

Nginxの場合

# vi /var/log/nginx/error.log

対応したら、再起動させます。
エラーが出た場合は、まずはログを確認します。ログの内容を確認してすれば解決策が見つけやすくなります。

参考サイト
CentOS7にnginxの設定 – Qiita