Rails5からデフォルトRackサーバがPumaになり、Unicornの代わりに利用される機会が増えそうなので、環境構築手順を自分用メモとして書いておきます。
投稿時のバージョン
- Ubuntu 15.10
- Ruby 2.3.0(rbenvでインストール)
- Rails 5.0.0beta3
- Puma 3.4.0
- Nginx 1.9.3
ヘルパコマンドを用意
Pumaの推奨はJRubyかRubiniusですが、Rubyでもクラスターモードで実行させればそこそこパフォーマンスが出せるはずなので1、起動時にworkersにCPUコア数を指定します。
workersへの指定は起動引数-wでも可能ですので、CPUコア数を取得するヘルパコマンドを用意し、workersにCPUコア数が自動設定されるようにします2。
$ mkdir -p ~/bin
$ echo 'cat /proc/cpuinfo | grep processor | wc -l' > ~/bin/ncpu; chmod +x ~/bin/ncpu
$ echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile
動作確認
$ ncpu
4
Rails5プロジェクトを用意
プロジェクト作成
$ rails -v
Rails 5.0.0.beta3
$ rails new hello_rails5
$ cd hello_rails5
$ rails g scaffold person name age:integer
$ rails db:migrate
$ rails db:migrate RAILS_ENV=production
デフォルトDBはSQLite3になりますが、今回はそのままにします。
Pumaの設定
デフォルトで作成される設定ファイルへ、Nginx用の設定を追加します。
config/puma.rb
_proj_path = "#{File.expand_path("../..", __FILE__)}"
_proj_name = File.basename(_proj_path)
_home = ENV.fetch("HOME") { "/home/vagrant" }
pidfile "#{_home}/run/#{_proj_name}.pid"
bind "unix://#{_home}/run/#{_proj_name}.sock"
directory _proj_path
# --- ここまで追加 ---
# Puma can serve each request in a thread from an internal thread pool.
# The `threads` method setting takes two numbers a minimum and maximum.
# Any libraries that use thread pools should be configured to match
# the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum, this matches the default thread size of Active Record.
#
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i
threads threads_count, threads_count
# Specifies the `port` that Puma will listen on to receive requests, default is 3000.
#
port ENV.fetch("PORT") { 3000 }
# Specifies the `environment` that Puma will run in.
#
environment ENV.fetch("RAILS_ENV") { "development" }
# Specifies the number of `workers` to boot in clustered mode.
# Workers are forked webserver processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
#
# workers ENV.fetch("WEB_CONCURRENCY") { 2 }
# Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code
# before forking the application. This takes advantage of Copy On Write
# process behavior so workers use less memory. If you use this option
# you need to make sure to reconnect any threads in the `on_worker_boot`
# block.
#
# preload_app!
# The code in the `on_worker_boot` will be called if you are using
# clustered mode by specifying a number of `workers`. After each worker
# process is booted this block will be run, if you are using `preload_app!`
# option you will want to use this block to reconnect to any threads
# or connections that may have been created at application boot, Ruby
# cannot share connections between processes.
#
# on_worker_boot do
# ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
# end
# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart
Nginxの設定
/etc/nginx/conf.d/hello_rails5.conf
upstream hello_rails5 {
# Path to Puma SOCK file, as defined previously
server unix:/home/vagrant/run/hello_rails5.sock fail_timeout=0;
}
server {
listen 80;
server_name 192.168.33.10; # Vagrantfileに書かれているデフォルトIP
root /path/to/hello_rails5/public; # /path/toを変更
try_files $uri/index.html $uri @hello_rails5;
location / {
proxy_pass http://hello_rails5;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
設定追加後、Nginxを再起動
$ sudo service nginx restart
最小の設定で済むように、conf.dに今回のRailsアプリ用のバーチャルサーバ設定を追加します、初期インストールのファイルは触りません。
Rails5アプリを起動
development環境の場合は
$ puma -w $(ncpu)
production環境の場合は
$ rails assets:precompile RAILS_ENV=production
# ※RAILS_ENV=productionはpumaの前
$ SECRET_KEY_BASE=$(rake secret) RAILS_SERVE_STATIC_FILES=true RAILS_ENV=production puma -w $(ncpu)
コマンドを叩くのが面倒な時は、起動用のaliasを用意して
$ echo "alias devpuma='puma -w \$(ncpu)'" >> ~/.bash_profile
$ echo "alias prodpuma='rails assets:precompile RAILS_ENV=production; SECRET_KEY_BASE=\$(rake secret) RAILS_SERVE_STATIC_FILES=true RAILS_ENV=production puma -w \$(ncpu)'" >> ~/.bash_profile
$ source ~/.bash_profile
aliasから起動
# developmentで起動
$ devpuma
# productionで起動
$ prodpuma
あとはブラウザからURLへアクセスして表示されれば環境構築は成功。