構築を試みたときに調べたことなどなど
なぜunicorn + nginx?
unicornは汎用のRackアプリケーションサーバ。Railsからもsinatraからも使える。
unicornだけでも、任意のポートをlistenすればwebサーバーとして使えるが、
以下のようなメリットがあるため、本番ではnginxをリバースプロキシとして
前に立ててからリクエストをunicornに流すのが良い
-
画像やcssなどの静的ファイルはnginxで高速に返せる
-
リクエストをバッファリングして受信完了してからunicornにリクエストを
投げるため、遅い回線(3Gなど)で接続が来た時にunicornの
ワーカプロセスの待ち時間を削減できる
動作原理はgithubの運用例が記載された以下のドキュメントが詳しい
https://github.com/blog/517-unicorn
まずは、unicornだけでサーバーを立てる
サンプルのsinatraアプリをunicornから呼んでみる
require 'rubygems'
require 'sinatra/base'
class HelloApp < Sinatra::Base
get '/hello' do
'Good Sunday Morning!'
end
end
run HelloApp
Gemfileにunicornを足して、bundle installする
gem "unicorn"
$ bundle install
$ bundle exec unicorn -v
unicorn v4.6.3
unicornの設定ファイルを作る。rubyのコードで書けてgood。
@dir = "/path/to/app/"
worker_processes 2 # CPUのコア数に揃える
working_directory @dir
timeout 300
listen 80
pid "#{@dir}tmp/pids/unicorn.pid" #pidを保存するファイル
# unicornは標準出力には何も吐かないのでログ出力を忘れずに
stderr_path "#{@dir}log/unicorn.stderr.log"
stdout_path "#{@dir}log/unicorn.stdout.log"
AWSを使っているなら、セキュリティグループで指定したportを
空けておく(よく忘れてハマる...)
これで準備完了。以下のコマンドで起動できる。-Dはdaemonとしての起動。
本番環境で起動する時は-E production とする
(※ オプションは設定ファイルより優先される)
$ bundle exec unicorn -c unicorn.rb -D
$ ps auxf | grep unicorn | grep -v grep
unicorn master -c unicorn.rb -D
\_ unicorn worker[0] -c unicorn.rb -D
\_ unicorn worker[1] -c unicorn.rb -D
psを見ると、workerプロセスとそれを管理するmasterプロセスが
動いていることが確認できる
また、unicorn_railsという実行ファイルもあるが、こちらは
過去verのRails向けで、基本的にはunicornを使うことが推奨されている
nginxをリバースプロキシとしてunicornの前に置く
次に、nginxをunicornの前に置く
unixドメインソケットを経由してnginxとunicornがやりとりを行うよう設定
また、/path/to/app/static以下のリクエストはnginxが処理する(unicornまでいかない)
$ sudo yum -y install nginx
$ nginx -v
nginx version: nginx/1.4.2
user root;
worker_processes 2;
http {
upstream unicorn_server {
server unix:/path/to/app/tmp/unicorn.sock;
}
server {
listen 80;
server_name ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com;
root /path/to/app/static;
location / {
# 静的ファイルが存在しなかった時はUnicornにproxy
if (!-f $request_filename) {
proxy_pass http://unicorn_server;
break;
}
}
}
}
# listen 80
listen "/path/to/app/tmp/unicorn.sock", backlog: 1024 # UNIXソケットを見るように変更
nginxを起動,unicornを再起動
ブラウザでhttp://xx.xx.xx.xx/hello を叩いて確認
$ sudo /etc/init.d/nginx start
or
$ sudo nginx
ネクストステップ
以上でとりあえずは動くが、他にもunicornには調べておくべきトピックが
あるので、いくつか挙げておきます
-
linuxシグナル送信によるunicornの起動/停止
-
capistranoを用いてホットデプロイを実現する
-
preloadを有効化してリロード速度の応答低下を回避する
Have Fun!