NginxとUnicornでRubyonRailsの本番アプリサーバー構築手順
Railsに標準で入っているWEBrickは、開発中には気軽に動かせて便利で問題なしですが、
本番でRailsサーバーを動かすには、やっぱりきちんとWEBサーバーを構築してあげる必要があります。
そこで、Rails周りでは最近よく聞くNginx + Unicornでの構成を構築してみたいと思います。
軽い解説
Nginxとは
エンジンエックスと読みます。
いわゆるWEBサーバーで、Apacheと同様の役割を担っているんですが、最近良く聞くようになってきましたね。
Apacheよりも動作が速くなる事もあり、優秀ですね。
nginx
Unicornとは
そのままユニコーンと読みます。
Rack Webサーバーなんですが、そもそもRackとはRubyにてサーバーとアプリケーション・フレームワークの間の
インターフェイス的役割をするライブラリの事です。
UnicornはRackの機能もWebサーバーの機能も併せ持っていて、そういった意味ではWEBrickも同じ立ち位置です。
なので、UnicornとRailsの組み合わせでも動きます。
じゃあなぜこの組み合わせなのかという話なんですが、UnicornはWEBrickより優れているけど、
Webサーバー機能はNginxの方が優れている。
だったら最高の組み合わせが、Rails + Unicorn + Nginxなんじゃないかってなる感じですかね。
前提
今回構築した環境の条件例です。
- Railsは稼働済みで、WEBrickでアプリケーションが動くレベルになっている事
- CentOS7 64bit
- Ruby 2.3.1
- Rails 4.2.6
- unicorn 5.1.0
- nginx 1.10.1
手順
Unicornインストール
Gemfileに記載して、インストールするだけです。
以下、対象のプロジェクトで実行します。
project/Gemfile
gem 'unicorn'
shell
bundle install
を実行します。
Unicorn設定ファイル準備
project/config 配下にunicorn.rbファイルを新規で作成します。
用意したファイルに以下の様に記述します。
project/config/unicron.rb
# -*- coding: utf-8 -*- worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3) timeout 15 # ソケット listen "/run/unicorn/unicorn.sock" pid "/run/unicorn/unicorn.pid" # ログ stderr_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT']) stdout_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT']) preload_app true before_fork do |server, worker| defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect! old_pid = "#{ server.config[:pid] }.oldbin" unless old_pid == server.pid begin sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU Process.kill :QUIT, File.read(old_pid).to_i rescue Errno::ENOENT, Errno::ESRCH end end end after_fork do |server, worker| defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection end
- listenとpidは環境によって指定を変更して下さい。
なお、Linuxの権限設定周りを確認する事も重要です。chmodなどで、適宜権限を与えて下さい。 - ENV['RAILS_ROOT']と書いているので、Linux側の環境変数で定義してあげて下さい。
Unicornの動作確認
Shellで実行していきます。
プロセス起動
shell
bundle exec unicorn_rails -c config/unicorn.rb -E production -D
起動確認
shell
ps -ef | grep unicorn | grep -v grep
一端停止
shell
kill -9 [Process ID]
UnicornをRakeのTaskに埋め込む
毎回コマンドを打つのが大変なので、rakeコマンドを作ってあげます。 まずはTaskテンプレートを作成します。
shell
bundle exec rails generate task unicorn
作成されたTaskを以下内容に書き換えます。
lib/tasks/unicorn.rake
namespace :unicorn do desc "Start unicorn for production env." task(:start) do config_path = "#{Rails.root}/config/unicorn.rb" sh "unicorn_rails -c #{config_path} -E development -D" end 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 def unicorn_signal signal Process.kill signal, unicorn_pid end def unicorn_pid begin File.read("/run/unicorn/unicorn.pid").to_i rescue Errno::ENOENT raise "Unicorn doesn't seem to be running" end end end
pidの場所などは設定ファイルと合わせます。
これで以下コマンドにてUnicornの起動、停止が可能となります。
shell
bundle exec rake unicorn:start bundle exec rake unicorn:stop
Nginxのインストール
続いてNginxをインストールしていきます。
リポジトリからインストール
まずはリポジトリをインストールします。
shell
https://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
続いて、Nginxのパッケージをインストールします。
shell
sudo yum install --enablerepo=nginx nginx
動作確認
# 起動 systemctl start nginx # 停止 systemctl stop nginx # 自動起動設定(必要であれば) systemctl enable nginx # 設定適用 systemctl reload nginx # ステータス確認 systemctl status nginx
Nginx設定ファイル準備
デフォルトのファイルを一端待避し、設定ファイルを準備します。
shell
cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/projectname.conf mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bk
用意したconfファイルを書き換えます。
shell
vi /etc/nginx/conf.d/projectname.conf
/etc/nginx/conf.d/projectname.conf
upstream unicorn { server unix:/run/unicorn/unicorn.sock; } server { listen 80; server_name localhost; #charset koi8-r; access_log /var/log/nginx/host.access.log main; error_log /var/log/nginx/host.error.log; root /mnt/hgfs/source/projectname; try_files $uri.html $uri/index.html $uri @unicorn; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /500.html; error_page 404 /404.html; 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を再起動します。
動作確認
UnicornとNginxを起動させ、「http://< IPAddress > or < HostName >/
」にアクセスし、
アプリが起動していれば成功です。