Skip to content

Instantly share code, notes, and snippets.

@falcon8823
Created September 29, 2012 14:07
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save falcon8823/3804095 to your computer and use it in GitHub Desktop.
Save falcon8823/3804095 to your computer and use it in GitHub Desktop.
Deploying of Rails with Nginx and Unicorn

Rails デプロイ

Ruby on Railsの欠点と言えば,デプロイ作業が若干面倒くさいところかもしれません.

コンテンツを公開ディレクトリに設置してパーミッションを設定するだけでは動作しません.

ここではRailsのデプロイ方法について簡単に紹介します.

Rackライブラリ

RackはRuby系のWebサーバやWebアプリケーションフレームワークで主に使われています. Rackは,WebサーバとWebアプリケーションをつなぐインターフェースの役割を果たすライブラリです.

サーバ,アプリ共にRackで共通化してしまえば,どちらかを差し替えても問題なく動作します. つまり,Rackに対応していればどんなサーバでも,どんなフレームワークでも組み合わせることができるというわけです.

RailsもこのRackを使用しているので,Rackに対応したサーバを使わないといけません.

今回はフレームワークの題材としてRailsを使いますが,Rackに対応したものならだいたいどれでも通用する内容になります.

デプロイ構成例

ここでは,以下のような構成でデプロイをします.

  • サーバマシン
    • Web, App, DBサーバはすべて1台で動作
  • Nginx
    • リバースプロキシに利用する
  • Unicorn
    • Rackサーバ
  • Ruby on Railsアプリケーション

Unicorn

クックパッドやGithubなどでも採用されているRackサーバです. 特徴としては,

  • メモリを比較的食わない
  • デプロイ時のダウンタイムが無い

などなど...

詳しくは他のサイトを参考にしてみてください.

手動デプロイ

大まかな手順

  1. アプリケーションを設置(nginxがアクセスできるパーミッションで)
  2. データベースの作成,nginxの設定など.
  3. unicornのGemをインストール
    • Bundlerを使っている場合はGemfileに追加
  4. unicornの起動

Nginxの設定例

  • リバースプロキシとして動作
  • 静的ファイルには直接アクセス(Unicornに問い合わせない)
upstream app-server {
	server 127.0.0.1:8080;
}

server {
	listen 80;
	server_name hogehoge.falconsrv.net;
	root /PATH/TO/APP/public;

	try_files $uri $uri/index.html @unicorn;

	location @unicorn {
		proxy_pass http://app-server;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header Host $host;
		proxy_set_header Server $host;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_read_timeout 20;
	}
}

Unicornの設定例

worker_processes 2

listen 8080

pid 'tmp/pids/unicorn.pid'
stdout_path 'log/unicorn.log'
stderr_path 'log/unicorn.log'

timeout 30
preload_app true

before_fork do |server, worker|
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!

  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

  sleep 1
end

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

Unicornの制御

Unicornの起動

production環境でデーモンとして動作

> cd PATH_TO_APP
> unicorn -c config/unicorn.rb -D -E production

Unicornの設定のリロード

config/unicorn.rbを変更した時などに実行

例)ワーカー数を増やしたときなど

> kill -HUP `cat tmp/pids/unicorn.pid`

Unicornの再起動

プログラムコードの変更を適用する

ダウンタイムゼロ

> kill -USR2 `cat tmp/pids/unicorn.pid`

Unicornの終了

すべてのリクエストを処理し終えてから終了する

> kill -QUIT `cat tmp/pids/unicorn.pid`

Unicornの強制終了

リクエストの処理をすべて中断し,直ちに終了する

> kill -INT `cat tmp/pids/unicorn.pid`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment