LoginSignup
496
482

More than 5 years have passed since last update.

Rails 4.2 + Unicorn + Nginx でアプリケーションサーバの構築

Last updated at Posted at 2015-01-14

Unicorn とは

Rails 標準アプリケーションサーバは重いので、動作が軽い Unicorn を導入してみる。

環境構築

Chef-Solo + Berkshelf で Rails 4 の開発環境を構築 を参考に。
他のサーバとは別のプライベートIPを割り当てておく。

プロジェクト作成

以下のコマンドを実行していく。

$ mkdir ~/projects/unicorn_sample
$ cd ~/projects/unicorn_sample
$ bundle init

作成されたGemfileを以下のように書き換える。

Gemfile
source 'https://rubygems.org'

gem 'rails', '4.2.0'

以下のコマンドを実行。

$ bundle install --path vendor/bundle
$ bundle exec rails new .
...
Overwrite /home/vagrant/projects/unicorn_sample/Gemfile? (enter "h" for help) [Ynaqdh] Y
...

Gemfile を下記のように書き換える。

Gemfile
source 'https://rubygems.org'

gem 'rails', '4.2.0'
gem 'sqlite3'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.1.0'
gem 'therubyracer', platforms: :ruby
gem 'jquery-rails'
gem 'turbolinks'
gem 'jbuilder', '~> 2.0'
gem 'sdoc', '~> 0.4.0', group: :doc
gem 'bcrypt', '~> 3.1.7'
gem 'unicorn'

group :development, :test do
  gem 'byebug'
  gem 'web-console', '~> 2.0'
  gem 'spring'
end

下記コマンドを実行。

$ bundle install --path vendor/bundle

テスト用アプリ作成

$ bundle exec rails generate scaffold board title:string text:string
$ rake db:migrate

config/routes.rb を下記のように編集

config/routes.rb
Rails.application.routes.draw do
  resources :boards
  root boards#index"
end

下記コマンドでサーバーを起動し、ページが見えるかどうか確認しておく。

$ bundle exec rails server -b 0.0.0.0

Unicorn の設定

config/unicorn.rb を下記の内容で新規に作成 (参考資料)。

config/unicorn.rb
# -*- coding: utf-8 -*-
worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)
timeout 15
preload_app true  # 更新時ダウンタイム無し

listen "/tmp/unicorn.sock"
pid "/tmp/unicorn.pid"

before_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
    Process.kill 'QUIT', Process.pid
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end

# ログの出力
stderr_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])
stdout_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])

下記コマンドで unicorn 起動。

$ bundle exec unicorn_rails -c config/unicorn.rb -E production -D

起動できているかどうかは下記コマンドで確認できる。

$ ps -ef | grep unicorn | grep -v grep

Unicorn を止めるには下記のコマンドでプロセスをKillする。

$ kill -9 [Process ID]

このままだと起動 & 終了が面倒なので、Rakeのtask に Unicorn の起動 & 終了の設定を記述する。
このページを参考にした。

Taskのテンプレートファイルを作成する。

$ bundle exec rails generate task unicorn

以下の内容に変更する。

lib/tasks/unicorn.rake
namespace :unicorn do
  ##
  # Tasks
  ##
  desc "Start unicorn for development env."
  task(:start) {
    config = Rails.root.join('config', 'unicorn.rb')
    sh "bundle exec unicorn_rails -c #{config} -E development -D"
  }

  desc "Stop unicorn"
  task(:stop) { unicorn_signal :QUIT }

  desc "Restart unicorn with USR2"
  task(:restart) { unicorn_signal :USR2 }

  desc "Increment number of worker processes"
  task(:increment) { unicorn_signal :TTIN }

  desc "Decrement number of worker processes"
  task(:decrement) { unicorn_signal :TTOU }

  desc "Unicorn pstree (depends on pstree command)"
  task(:pstree) do
    sh "pstree '#{unicorn_pid}'"
  end

  def unicorn_signal signal
    Process.kill signal, unicorn_pid
  end

  def unicorn_pid
    begin
      File.read("/tmp/unicorn.pid").to_i
    rescue Errno::ENOENT
      raise "Unicorn doesn't seem to be running"
    end
  end

end

下記のコマンドでUnicornを起動、停止出来るようになる。

$ bundle exec rake unicorn:start
$ bundle exec rake unicorn:stop

とりあえず、Unicornを起動しておく。

Nginx の設定

下記コマンドで設定ファイルの作成を行う。

$ sudo cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/local.conf
$ sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bk

/etc/nginx/conf.d/local.conf を下記のように書き換える。
upstream の server の部分は Unicorn 側で指定した sock ファルの場所を、
root の部分はアプリケーションのルートディレクトリを指定する。

/etc/nginx/conf.d/local.conf
upstream unicorn {
  server unix:/home/vagrant/projects/unicorn_sample/tmp/unicorn.sock;
}

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

  access_log /var/log/nginx/sample_access.log;
  error_log /var/log/nginx/sample_error.log;

  root /home/vagrant/projects/unicorn_sample;

  client_max_body_size 100m;
  error_page 404 /404.html;
  error_page 500 502 503 504 /500.html;
  try_files $uri/index.html $uri @unicorn;

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

Nginx を(再)起動する。

$ sudo service nginx restart

動作確認

http://[ドメイン名]/ にアクセスして、
$ bundle exec rails server -b 0.0.0.0
で起動した場合と同じ画面が表示されていればOK。

D3A692FF-37E8-4124-9F3B-A2A3D87B4ADD.png

496
482
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
496
482