nginx+UnicornでRedmineを動かす 2/3 「nginx+Unicornの設定」編
nginx(エンジンエックス)はロシアで開発されているWebサーバ兼リバースプロキシサーバです。消費リソースが低く、高負荷状態でも性能が劣化しにくい特徴があり、GitHubやHeroku、WordPress.comで採用されるなど近年人気が高まっています。
nginx単体では動的なコンテンツを取り扱えないため、nginxでRailsアプリを動作させるためにはアプリケーションサーバとの連携が必要になります。
Rails用のアプリケーションサーバとしてはPassengerなどが有名ですが、最近ではこちらも低消費リソースで高負荷に対応したUnicornが注目されています。
Unicornの設定
nginx+UnicornでRedmineを動作させるにあたり、まずはアプリケーションサーバであるUnicornのセットアップから始めます。Unicornの概要については以下のページが参考になります。
- 次世代RailsサーバーUnicornを使ってみた | TechRacho
- UnicornでSinatraアプリをデプロイしてみた - 射撃しつつ前転
- rails/unicorn - 技術メモ
- uu59のメモ | Rubyのhttpサーバまとめ 2012年4月版(thin, Unicorn, Passenger, etc)
Unicornのインストール
gemでUnicornをインストールします。
$ sudo gem install unicorn
Unicornの設定
RedmineにUnicorn用の設定ファイルを追加します。設定ファイルの内容は以下のページを参考にしました。
- Class: Unicorn::Configurator(unicorn.conf.rb, unicorn.conf.minimal.rb)
- nginx + unicorn + Rails on Mac - Aerialarts
$ vim /var/www/redmine/config/unicorn.rb
# ワーカーの数
worker_processes 1
# ソケット経由で通信する
listen File.expand_path('tmp/sockets/unicorn.sock', ENV['RAILS_ROOT'])
# ログ
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
# SIGTTOU だと worker_processes が多いときおかしい気がする
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
preload_appをtrueにするとmasterプロセスの使用メモリが増えるため無料VPSの貧弱メモリ環境ではOFFにしました。通常はONでよいと思います。(参考:unicornのpreload_app - motsatのブログ)
Unicornの起動
unicorn_railsコマンドでUnicornを起動します。
$ cd /var/www/redmine
$ unicorn_rails -c config/unicorn.rb -E production -D
-c : 設定ファイル
-E : RAILS_ENV(デフォルトはdevelopment)
-D : デーモンとして動作
psコマンドでmasterプロセスとworkerプロセスが動いていることを確認します。
$ ps auxf
Unicornの操作
Unicornの終了や再起動はkillコマンドによるシグナルの送信で行います。
- File: SIGNALS [Unicorn: Rack HTTP server for fast clients and Unix]
- unicornにどんなシグナル送るとどうなるのかまとめました - life.should be_happy # => 1 examples, ? failures
$ cd /var/www/redmine
終了
$ kill -QUIT `cat tmp/pids/unicorn.pid`
再起動
$ kill -HUP `cat tmp/pids/unicorn.pid`
nginxの設定
続いてnginxをセットアップしていきます。nginxの概要・使い方については以下のページが参考になります。
- nginx連載1回目: nginxの紹介 - インフラエンジニアway
- nginx連載2回目: nginxのインストール - インフラエンジニアway
- nginx連載3回目: nginxの設定、その1 - インフラエンジニアway
- nginx連載4回目: nginxの設定、その2 - バーチャルサーバの設定 - インフラエンジニアway
- nginx連載5回目: nginxの設定、その3 - locationディレクティブ - インフラエンジニアway
- nginx連載6回目: nginxの設定、その4 - TLS/SSLの設定 - インフラエンジニアway
- さくらVPSとnginxリバースプロクシで最速WordPressブログを作る方法(ベンチマーク付き) | さくらたんどっとびーず
- 入門! nginx - 馬鹿と天才は紙一重
Apacheの無効化
nginxのセットアップを始める前に、apacheを無効化しておきます。
$ sudo chkconfig httpd off
$ sudo service httpd stop
nginxのインストール
nginxはEPELリポジトリからインストールすることもできますが、nginxの公式リポジトリで最新版が提供されているため、こちらを利用します。
$ wget http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
$ sudo rpm -ivh nginx-release-centos-6-0.el6.ngx.noarch.rpm
$ cat /etc/yum.repos.d/nginx.repo
# nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/6/$basearch/
gpgcheck=0
enabled=1
$ sudo yum install nginx
$ sudo service nginx start
サービス起動後、ブラウザからアクセスすると初期ページが確認できます。
nginxの設定確認
標準の設定ファイルは以下の場所にあります。内容をひと通り確認しておきましょう。
$ cat /etc/nginx/nginx.conf
$ cat /etc/nginx/conf.d/default.conf
nginxのUnicorn連携設定
nginxの設定ファイルを変更して、静的ファイル以外はリバースプロキシでUnicornのソケットへ通信を通すようにします。設定内容は以下のページを参考にしました。
なお、「unicorn-redmine」としている部分(2箇所)は、ドメイン名等に関係なく任意の名前を付けることができます。
$ cd /etc/nginx/conf.d/
$ sudo cp -p default.conf default.conf.bak
$ sudo vim default.conf
upstream unicorn-redmine {
server unix:/var/www/redmine/tmp/sockets/unicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name localhost;
~中略~
#location / {
# root /usr/share/nginx/html;
# index index.html index.htm;
#}
location / {
root /var/www/redmine/public;
index index.html index.htm;
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 Host $http_host;
proxy_pass http://unicorn-redmine;
}
~中略~
}
設定ファイルの構文をチェックし、nginxを再起動します。
$ sudo nginx -t
$ sudo service nginx restart
ブラウザからアクセスして動作を確認します。
Unicorn起動スクリプトの作成と実行ユーザの設定
運用にあたり、少し追加の設定をしておきます。
Unicorn起動スクリプト
Unicornの起動スクリプトを作成して、OS起動時に自動的にUnicornが起動するようにしましょう。また、これによりserviceコマンドでUnicornの操作が可能になります。
起動スクリプトは以下のページを参考にしました。
$ sudo vim /etc/init.d/unicorn_redmine
#!/bin/bash
#
# unicorn_redmine Startup script for unicorn.
#
# chkconfig: - 85 15
# description: redmine on unicorn start/stop script.
#
set -u
set -e
APP_NAME=redmine
APP_ROOT="/var/www/$APP_NAME"
CNF="$APP_ROOT/config/unicorn.rb"
PID="$APP_ROOT/tmp/pids/unicorn.pid"
ENV=production
UNICORN_OPTS="-c $CNF -E $ENV -D"
old_pid="$PID.oldbin"
cd $APP_ROOT || exit 1
sig () {
test -s "$PID" && kill -$1 `cat $PID`
}
oldsig () {
test -s $old_pid && kill -$1 `cat $old_pid`
}
case ${1-help} in
start)
sig 0 && echo >&2 "Already running" && exit 0
cd $APP_ROOT ; unicorn_rails $UNICORN_OPTS
;;
stop)
sig QUIT && exit 0
echo >&2 "Not running"
;;
force-stop)
sig TERM && exit 0
echo >&2 "Not running"
;;
restart|reload)
sig HUP && echo reloaded OK && exit 0
echo >&2 "Couldn't reload, starting instead"
unicorn_rails $UNICORN_OPTS
;;
upgrade)
sig USR2 && exit 0
echo >&2 "Couldn't upgrade, starting instead"
unicorn_rails $UNICORN_OPTS
;;
rotate)
sig USR1 && echo rotated logs OK && exit 0
echo >&2 "Couldn't rotate logs" && exit 1
;;
*)
echo >&2 "Usage: $0 <start|stop|restart|upgrade|rotate|force-stop>"
exit 1
;;
esac
$ sudo chmod +x /etc/init.d/unicorn_redmine
$ sudo chkconfig unicorn_redmine on
$ sudo chkconfig --list unicorn_redmine
unicorn_redmine 0:off 1:off 2:on 3:on 4:on 5:on 6:off
Unicornのワーカープロセス実行ユーザ設定
Unicornのワーカープロセス実行ユーザを設定し、指定したユーザでRedmineを実行するようにしましょう。
ユーザを追加し、Redmine関連ファイルの所有権を変更します。
$ sudo useradd -s /sbin/nologin redmine
$ sudo chown -R redmine:redmine /var/www/redmine
Unicornの設定ファイル末尾にワーカープロセス実行ユーザ・グループの指定を追加します。
$ sudo vim /var/www/redmine/config/unicorn.rb
user 'redmine', 'redmine'
Unicornの再起動
Unicornを再起動してserviceコマンドが使用できることと、ワーカープロセスの実行ユーザが変更されたことを確認します。
$ sudo service unicorn_redmine stop
$ sudo service unicorn_redmine start
$ ps auxf
以上でnginxとUnicornの設定は完了です。
その他参考ページ
本文中でリンクした以外の参考ページは以下のとおり。
- nginx + Unicorn を試してみた - milk1000cc
- Rails3アプリをnginx+unicornで動かしたら速すぎた - どっかのBlogの前置きのような
- nginx + unicornでrails3.1が動作する環境を作る - A Peak Never Ending !
- tDiaryを Nginx + Unicorn + さくらVPSで動かした - まちゅダイアリー(2012-05-03)
- nginxとUnicornでRackアプリを動かす - As Sloth As Possible
- unicornでダウンタイムなしに再起動する - うんたらかんたら日記
- さくらの VPS に登録してみた(4) nginx + unicorn - まゆの日記
- cocoa*life - Redmine を nginx + Unicorn で動かしてみる
- CentOS5.6 で MySQL+Nginx+Unicorn な Rails アプリを動かす - happy lie, happy life
おわりに
無事、nginx+UnicornでRedmineを動作させることができました。HOST1FREEの無料VPS環境でも、それなりに実用的なレスポンスで使えています。
今回はひとまずRedmineをトップディレクトリで動作させましたが、最終的にはサブディレクトリで使用したいと思っています。PassengerであればRailsBaseURIなどで対応できるはずですが、nginx+Unicornの場合どのように設定すれば良いのか、まだよく分かっていません。
追記@2012/07/30
サブディレクトリへの設置方法について確認できたため、「サブディレクトリ」編を追加しました。
連載一覧
- nginx+UnicornでRedmineを動かす 1/3 「Redmineのインストール」編
- nginx+UnicornでRedmineを動かす 2/3 「nginx+Unicornの設定」編
- nginx+UnicornでRedmineを動かす 3/3 「サブディレクトリ」編