2011年12月28日水曜日

nginxとunicorn上でrails3.1アプリを動かす。ついでにcapistranoを使ってデプロイ

かなりハマったので、メモ。

まずアプリ側。
Gemfileに以下を追加。

group :deployment do
gem 'capistrano'
gem 'capistrano_colors'
end

gem 'therubyracer'
gem 'unicorn'

で、bundle install。

次にcapistrano設定ファイルを作成
# capify .

#config/deploy.rb

# capistranoの出力がカラーになる
require 'capistrano_colors'

# cap deploy時に自動で bundle install が実行される
require "bundler/capistrano"

#rvm setting
set :rvm_type, :user
$:.unshift(File.expand_path('./lib', ENV['rvm_path']))
require "rvm/capistrano"
set :rvm_ruby_string, '1.9.2@rails3.1' #ここにgemset名を入力

set :user, "サーバーのユーザー名"
set :port, 22 #サーバーのポート番号
set :use_sudo, false #sudoをするかどうか。
ssh_options[:forward_agent] = true

#repository setting
set :application, "sample" #アプリケーション名
set :scm, :git #gitを使う
set :repository, "ssh://user@example.com:22/home/user/git/sample.git"
set :deploy_to, "/home/user/sample/"
default_environment["LD_LIBRARY_PATH"] = "$LD_LIBRARY_PATH:/usr/local/lib"



# Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`

role :web, "example.com" # Your HTTP server, Apache/etc
role :app, "example.com" # This may be the same as your `Web` server
role :db, "example.com", :primary => true # This is where Rails migrations will run

#sqlite3を使う場合、dbをshareフォルダに入れる。
task :db_setup, :roles => [:db] do
run "mkdir -p -m 775 #{shared_path}/db"
end

namespace :deploy do
task :start, :roles => :app do
run "cd #{current_path}; bundle exec unicorn_rails -c config/unicorn.rb -E production -D"
end
task :restart, :roles => :app do
if File.exist? "/tmp/unicorn.pid"
run "kill -s USR2 `cat /tmp/unicorn.pid`"
end
end
task :stop, :roles => :app do
run "kill -s QUIT `cat /tmp/unicorn.pid`"
end
end

namespace :assets do
task :precompile, :roles => :web do
run "cd #{current_path} && RAILS_ENV=production bundle exec rake assets:precompile"
end
task :cleanup, :roles => :web do
run "cd #{current_path} && RAILS_ENV=production bundle exec rake assets:clean"
end
end
after :deploy, "assets:precompile" #デプロイ後にassets compileをするように。
set :normalize_asset_timestamps, false #rails3.1対策


次にunicornの設定
#config/unicorn.rb

application = 'sample'

# ワーカーの数
worker_processes 2

# ソケット
listen "/tmp/unicorn.sock"
pid "/tmp/unicorn.pid"

# ログ
if ENV['RAILS_ENV'] == 'production'
shared_path = "/home/user/#{application}/shared"
stderr_path = "#{shared_path}/log/unicorn.stderr.log"
stdout_path = "#{shared_path}/log/unicorn.stdout.log"
end

# ダウンタイムなくす
preload_app true

before_fork do |server, worker|
if defined?(ActiveRecord::Base)
ActiveRecord::Base.connection.disconnect!
end
old_pid = "/tmp/unicorn.pid.oldbin"
if File.exists?(old_pid) && server.pid != old_pid
begin
Process.kill("QUIT", File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
end
end
end

after_fork do |server, worker|
if defined?(ActiveRecord::Base)
ActiveRecord::Base.establish_connection
end
end


environmentsのproduction内で
config.serve_static_assets = true
にする。
※こうしないとcssがロードされない。

あとdatabase.ymlのproductionを
database: ../../shared/db/production.sqlite3
にする。



次はサーバ側。
nginxをyumでインストールするために、repoに追加。
# sudo vim /etc/yum.repo.d/nginx.repo


[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/rhel/$releasever/$basearch/
gpgcheck=0
enabled=1


で、インストール。
#sudo yum install nginx

nginxの設定ファイルはこんな感じ。
#sudo vim /etc/nginx/conf.d/sample.conf


upstream unicorn {
server unix:/tmp/unicorn.sock;
}

server {
listen 80;
server_name example.com;

root /home/user/sample/current/public;
error_log /home/user/sample/current/log/error.log;

location / {
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;
}

}


あとは、capistranoでデプロイして、nginxを起動するだけ。必要があればchkconfigで自動起動設定をする。
capistranoでデプロイするときは、
#cap deploy:setup
#cap db_setup
#cap deploy:cold
の順で。


参考:
http://d.hatena.ne.jp/ntaku/20111112/1321093327
http://aerial.st/archive/2011/06/16/nginx-unicorn-rails-on-mac/

0 件のコメント:

コメントを投稿