Redmine を Nginx + Unicorn で動かす
前回までのあらすじ
Nginx を Apache のリバースプロキシに設定した。
今日の目標
現在 Apache + Passenger で動いている Rails アプリの Redmine を Nginx + Unicorn に切り替えてみよう。
Redmine は /var/www/redmine
に設置されている。
Gem の追加
Redmine の gem に unicorn を追加する。
もしRedmine本体は使用しないgem(例: mongrel, fcgi)もロードしたい場合、 Gemfile.local というファイルをRedmineのディレクトリに作成してください。 Redmineのインストール — Redmine Guide 日本語訳
ということなので Gemfile.local を作成した。
# Gemfile.local gem "unicorn"
インストール。
$ bundle install
Unicorn の設定
Redmine の config ディレクトリに unicorn.rb というファイルを作成した。
worker_processes 1 timeout 60 listen File.expand_path("tmp/sockets/unicorn.sock", ENV['RAILS_ROOT']) pid File.expand_path("tmp/pids/unicorn.pid", ENV['RAILS_ROOT']) stdout_path File.expand_path("log/unicorn.stdout.log", ENV['RAILS_ROOT']) stderr_path File.expand_path("log/unicorn.stderr.log", ENV['RAILS_ROOT']) preload_app true GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = true before_fork do |server, worker| # この設定はpreload_app trueの場合に必須 defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect! # USR2シグナルで旧プロセスを終了させる old_pid = "#{server.config[:pid]}.oldbin" if old_pid != server.pid begin sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU Process.kill(sig, File.read(old_pid).to_i) rescue Errno::ENOENT, Errno::ESRCH end end end after_fork do |server, worker| # この設定はpreload_app trueの場合に必須 defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection end
とりあえず socket のパス。これ大事。
tmp/sockets/unicorn.sock
pid のパス。これも大事。
tmp/pids/unicorn.pid
Unicorn 起動
え、Unicorn て Apache とか Nginx とかとは別口で起動しておかないといけないの?
後で自動化できないか調べなきゃ。
$ bundle exec unicorn_rails -c config/unicorn.rb -D -E production
コマンドのオプションは -c
で設定ファイル指定、-E
で動作モード指定、-D
がデーモン化。
終了の仕方は力ずく。
$ kill -quit 'cat /var/www/redmine/tmp/pids/unicorn.pid'
Nginx の設定
/etc/nginx/sites-available/ に設定ファイルを作成して /etc/nginx/sites-enabled/ からリンクを張る。
upstream redmine { server unix:/var/www/redmine/tmp/sockets/unicorn.sock; } server { listen 80; server_name redmine.tepidworks.jp; location / { root /var/www/redmine/public; if ( -f $request_filename ) { break; } proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_pass http://redmine; } }
if ( -f $request_filename ) { break; }
があるので、静的ファイルへのアクセスは Rails を通さないで Nginx が直接返す。*1
Nginx 再起動
$ sudo service nginx restart
無事アクセスできた。
*1:少なくとも、確認した限り静的ファイルへのアクセスでは Rails がログを吐かなかったので Unicorn に処理は渡っていないはず。