2014年8月20日水曜日

Ruby on Rails4をproduction環境として動かす(nginx + unicorn)

rails4(nginx + unicorn)での動かし方をまとめます。

環境は下記となります。
・Ruby2.1
・nginx
・unicorn

1.Unicornをインストールする
Gemfileに書きを追記
gem 'unicorn'
追記後にbundle installをお忘れなく。

2.config/unicorn.rb作成(下記をコピペでいい)
application = '{適当なアプリ名}'

worker_processes 2
working_directory "/#{application}"

listen "/var/run/unicorn/unicorn_#{application}.sock"   # Unix Domain Socket

pid "/var/run/unicorn/unicorn_#{application}.pid"       # PIDファイル出力先
 
timeout 60
 
preload_app true

stdout_path "/var/log/unicorn/unicorn.stdout_#{application}.log"  # 標準出力ログ出力先
stderr_path "/var/log/unicorn/unicorn.stderr_#{application}.log"  # 標準エラー出力ログ出力先
 
GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = 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
3.assetsをプリコンパイルする
production環境ではassetsを毎回コンパイルすると遅いらしいので、最初にコンパイルさせる。
bundle exec rake assets:precompile
4.unicorn起動
unicorn_rails -c config/unicorn.rb -E production -D -p 13000

5.nginxの設定
/etc/nginx/conf.d/rails.conf的なファイルに書きを記載(rails.confは.confがあれば勝手に読み込むのでファイル名は何でも良い)
upstream unicorn-unix-domain-socket {
   ### unicorn.rbで指定したUnicornのソケットを指定:
   server unix:/var/run/unicorn/unicorn_subsche.sock fail_timeout=0;
}

upstream unicorn-tcp {
   ### unicornのポートを指定 ※ここでは、Unicorn起動時にポート 13000で起動させるものとします。
   server 127.0.0.1:13000;
}

server {
   listen 80;
   server_name {サーバ名};

   root /{アプリパス}/public;

   access_log  /var/log/nginx/access.log;
   error_log /var/log/nginx/error.log;

   location ^/assets/ {
       root /{アプリパス}/public;
   }


   auth_basic "user name";
   auth_basic_user_file "/etc/nginx/htpasswd";

   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-unix-domain-socket;
    }

    location ~* \.(ico|css|js|gif|jpe?g|png)(\?[0-9]+)?$ {
       expires 1y;
    }
}


6.nginx起動
service nginx start
起動しているのであれば、下記コマンド。
service nginx restart

7.ブラウザからアクセス
表示できれば終わり。表示できなければ下記を確認して下さい。


■起動しない場合
・DBがない
・SECRET_KEY_BASEを設定していない

ポイント1.DBがない
ずっとdevelopment環境で開発している場合、production用のdatabaseが作成されていない可能性があります。
下記コマンドで、production用のdatabaseを作成しましょう。
rake db:create db:migrate RAILS_ENV=production

ポイント2. SECRET_KEY_BASEを設定していない
下記のエラーが出る場合は、きっとこのパターンです。
E, [2014-08-20T22:34:16.262827 #3625] ERROR -- : app error: Missing `secret_key_base` for 'production' environment, set this value in `config/secrets.yml` (RuntimeError)
E, [2014-08-20T22:34:16.263001 #3625] ERROR -- : /usr/local/lib/ruby/gems/2.1.0/gems/railties-4.1.4/lib/rails/application.rb:452:in `validate_secret_key_config!'
E, [2014-08-20T22:34:16.263061 #3625] ERROR -- : /usr/local/lib/ruby/gems/2.1.0/gems/railties-4.1.4/lib/rails/application.rb:195:in `env_config'
E, [2014-08-20T22:34:16.263083 #3625] ERROR -- : /usr/local/lib/ruby/gems/2.1.0/gems/railties-4.1.4/lib/rails/engine.rb:510:in `call'
E, [2014-08-20T22:34:16.263103 #3625] ERROR -- : /usr/local/lib/ruby/gems/2.1.0/gems/railties-4.1.4/lib/rails/application.rb:144:in `call'
E, [2014-08-20T22:34:16.263122 #3625] ERROR -- : /usr/local/lib/ruby/gems/2.1.0/gems/unicorn-4.8.3/lib/unicorn/http_server.rb:576:in `process_client'
E, [2014-08-20T22:34:16.263142 #3625] ERROR -- : /usr/local/lib/ruby/gems/2.1.0/gems/unicorn-4.8.3/lib/unicorn/http_server.rb:670:in `worker_loop'
E, [2014-08-20T22:34:16.263160 #3625] ERROR -- : /usr/local/lib/ruby/gems/2.1.0/gems/unicorn-4.8.3/lib/unicorn/http_server.rb:525:in `spawn_missing_workers'
E, [2014-08-20T22:34:16.263187 #3625] ERROR -- : /usr/local/lib/ruby/gems/2.1.0/gems/unicorn-4.8.3/lib/unicorn/http_server.rb:140:in `start'
E, [2014-08-20T22:34:16.263206 #3625] ERROR -- : /usr/local/lib/ruby/gems/2.1.0/gems/unicorn-4.8.3/bin/unicorn_rails:209:in `'
E, [2014-08-20T22:34:16.263225 #3625] ERROR -- : /usr/local/bin/unicorn_rails:23:in `load'
E, [2014-08-20T22:34:16.263243 #3625] ERROR -- : /usr/local/bin/unicorn_rails:23:in `
'
config/secrets.ymlファイルで「secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>」という部分が存在するため、下記コマンドを実施する。
export SECRET_KEY_BASE=`rake secret`
その後、unicornの再起動を行う。

これでアクセス出来なければ別な問題かもしれません。