Capistrano3でrailsデプロイ(+unicorn)

[前回](http://qiita.com/ijikeman/items/8554a005a132a4e9d7f2)、capistrano3が動くまでを確認したので次は、railsをデプロイします。


### ■capistrano-rails
railsをデプロイするのに capistrano-railsをインストールします

```ruby:Gemfile
gem 'capistrano-rails'
```
$ bundle
#### capistrano-railsの３つのモジュールを有効にする場合と個別に有効にする場合
```ruby:Capfile
require "capistrano/rails"
```

```ruby:Capfile
require "capistrano/bundler"
require "capistrano/rails/assets"
require "capistrano/rails/migrations"
```

### ■capistrano-railsモジュール毎のcapコマンド一覧 
capistrano/bundler

```
cap bundler:clean
cap bundler:install
cap bundler:map_bins
```

capistrano/assets

```
cap deploy:cleanup_assets
cap deploy:clobber_assets
cap deploy:compile_assets
cap deploy:normalize_assets
cap deploy:rollback_assets
```

capistrano/migrations

```
cap deploy:migrate
cap deploy:migrating
```

### ■設定
railsデプロイ時にdb:migrateする場合はrole :dbの設定が必ずいる

```ruby:config/deploy/production.rb
server "127.0.0.1",
  user: "root",
  roles: %w{web app db}
```

```ruby:config/deploy.rb
set repo_url: git@github.com:test/rails-test.git
```

デプロイ
$ bundle exec cap production deploy

```
00:00 git:wrapper
      01 mkdir -p /tmp
    ✔ 01 root@127.0.0.1 0.102s
      Uploading /tmp/git-ssh-my_app_name-production-.sh 100.0%
      02 chmod 700 /tmp/git-ssh-my_app_name-production-.sh
    ✔ 02 root@127.0.0.1 0.017s
00:00 git:check
      01 git ls-remote git@github.com:test/rails-test.git HEAD
      01 Error reading response length from authentication socket.
      01 d7e3a1f0a670906cd0edde82f48d30e17b2be85b   HEAD
    ✔ 01 root@127.0.0.1 2.721s
00:03 deploy:check:directories
      01 mkdir -p /var/www/my_app_name/shared /var/www/my_app_name/releases
    ✔ 01 root@127.0.0.1 0.008s
00:03 deploy:check:linked_dirs
      01 mkdir -p /var/www/my_app_name/shared/public/assets
    ✔ 01 root@127.0.0.1 0.008s
00:03 git:clone
      The repository mirror is at /var/www/my_app_name/repo
00:03 git:update
      01 git remote set-url origin git@github.com:test/rails-test.git
    ✔ 01 root@127.0.0.1 0.010s
      02 git remote update --prune
      02 Fetching origin
      02 Error reading response length from authentication socket.
    ✔ 02 root@127.0.0.1 2.587s
00:05 git:create_release
      01 mkdir -p /var/www/my_app_name/releases/20170220083247
    ✔ 01 root@127.0.0.1 0.014s
      02 git archive master | /usr/bin/env tar -x -f - -C /var/www/my_app_name/releases/20170220083247
    ✔ 02 root@127.0.0.1 0.053s
00:05 deploy:set_current_revision
      01 echo "d7e3a1f0a670906cd0edde82f48d30e17b2be85b" >> REVISION
    ✔ 01 root@127.0.0.1 0.015s
00:05 deploy:symlink:linked_dirs
      01 mkdir -p /var/www/my_app_name/releases/20170220083247/public
    ✔ 01 root@127.0.0.1 0.013s
      02 ln -s /var/www/my_app_name/shared/public/assets /var/www/my_app_name/releases/20170220083247/public/assets
    ✔ 02 root@127.0.0.1 0.012s
00:06 deploy:assets:precompile
      01 bundle exec rake assets:precompile
      01 I, [2017-02-20T08:32:55.624716 #27585]  INFO -- : Writing /var/www/my_app_name/releases/20170220083247/public/assets/application-42632fb4dae48435b11b6d52729a81a3dc86afba15015b77f9ac8c95d84d2a71.js
      01 I, [2017-02-20T08:32:55.629167 #27585]  INFO -- : Writing /var/www/my_app_name/releases/20170220083247/public/assets/application-42632fb4dae48435b11b6d52729a81a3dc86afba15015b77f9ac8c95d84d2a71.js.gz
      01 I, [2017-02-20T08:32:55.726577 #27585]  INFO -- : Writing /var/www/my_app_name/releases/20170220083247/public/assets/application-d12397cbc3a266ce5a99f7b588223090c55ca04a439953bb5f9304395de93fc3.css
      01 I, [2017-02-20T08:32:55.726984 #27585]  INFO -- : Writing /var/www/my_app_name/releases/20170220083247/public/assets/application-d12397cbc3a266ce5a99f7b588223090c55ca04a439953bb5f9304395de93fc3.css.gz
    ✔ 01 root@127.0.0.1 5.394s
00:11 deploy:assets:backup_manifest
      01 mkdir -p /var/www/my_app_name/releases/20170220083247/assets_manifest_backup
    ✔ 01 root@127.0.0.1 0.020s
      02 cp /var/www/my_app_name/releases/20170220083247/public/assets/.sprockets-manifest-3b5645db6bba329ac9558f5ca133198c.json /var/www/my_app_name/releases/20170220083247/assets_manifest_backup
    ✔ 02 root@127.0.0.1 0.015s
00:11 deploy:migrate
      [deploy:migrate] Run `rake db:migrate`
00:11 deploy:migrating
      01 bundle exec rake db:migrate
      01 == 20170220025016 CreateIdeas: migrating ======================================
      01 -- create_table(:ideas)
      01    -> 0.0013s
      01 == 20170220025016 CreateIdeas: migrated (0.0013s) =============================
      01
      01 == 20170220062640 CreateBooks: migrating ======================================
      01 -- create_table(:books)
      01    -> 0.0011s
      01 == 20170220062640 CreateBooks: migrated (0.0012s) =============================
      01
    ✔ 01 root@127.0.0.1 2.679s
00:14 deploy:symlink:release
      01 ln -s /var/www/my_app_name/releases/20170220083247 /var/www/my_app_name/releases/current
    ✔ 01 root@127.0.0.1 0.010s
      02 mv /var/www/my_app_name/releases/current /var/www/my_app_name
    ✔ 02 root@127.0.0.1 0.010s
00:14 deploy:log_revision
      01 echo "Branch master (at d7e3a1f0a670906cd0edde82f48d30e17b2be85b) deployed as release 20170220083247 by " >> /var/www/my_app_name/revisions.log
    ✔ 01 root@127.0.0.1 0.019s
```

### ■unicorn連携する
デプロイは可能になったがunicornの起動・停止も連携したいので
capistrano3-unicornを使う(lib/capistrano/unicorn.rbのunicornの起動停止を制御するrakeタスクを設置してもいいが、今回は便利なGemを利用します)

```ruby:Gemfile
gem "capistrano3-unicorn"
```

$ bundle

```ruby:Capfile
require 'capistrano3/unicorn'
```

capistrano-unicornで増えたコマンド
$ bundle exec cap -T

```
cap unicorn:add_worker
cap unicorn:duplicate
cap unicorn:force_stop
cap unicorn:legacy_restart
cap unicorn:reload
cap unicorn:remove_worker
cap unicorn:restart
cap unicorn:start
cap unicorn:stop
```

- デプロイ後にunicorn再起動を実施するよう設定
unicorn.pidの位置は/var/tmp/unicorn.pidを指定しています
unicorn設定ファイルはリポジトリ内に設置しているのでその場所を指定 default: #{CURRENT}/config/unicorn/#{RAILS_ENV}.rb

```ruby:config/deploy/production.rb
namespace :deploy do
  task :restart do
    invoke 'unicorn:restart'
  end
end
after 'deploy:publishing', 'deploy:restart'

set :unicorn_pid, "/var/tmp/unicorn.pid"
set :unicorn_config_path, "/var/www/my_app_name/current/config/unicorn/production/unicorn.rb"
set :unicorn_rack_env, "production"
```

※USR2シグナルでは再読込される為にはunicornの設定ファイルのbefore_forkのコメントアウト部分を有効にする必要があるので注意
unicornの設定ファイル(unicorn.conf.rb)はunicornのgem内に /examples/unicorn.conf.rbで設置してあるよ

```ruby:unicorn.conf.rb
before_fork do |server, worker|
...

+  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
...
end
```

デプロイするとunicornが起動する
$ bundle exec cap production deploy

```
... 省略 ...
    ✔ 01 root@127.0.0.1 2.851s
00:17 deploy:symlink:release
      01 ln -s /var/www/my_app_name/releases/20170220150828 /var/www/my_app_name/releases/current
    ✔ 01 root@127.0.0.1 0.008s
      02 mv /var/www/my_app_name/releases/current /var/www/my_app_name
    ✔ 02 root@127.0.0.1 0.008s
00:17 unicorn:start
      01 bundle exec unicorn -c /var/www/my_app_name/current/config/unicorn/production/unicorn.rb -E production -D 
    ✔ 01 root@127.0.0.1 2.878s
      unicorn restarting...
      02 kill -s USR2 `cat /var/tmp/unicorn.pid`
    ✔ 02 root@127.0.0.1 0.016s
00:20 deploy:cleanup
      Keeping 5 of 11 deployed releases on 127.0.0.1
      01 rm -rf /var/www/my_app_name/releases/20170220141400 /var/www/my_app_name/releases/20170220141515 /var/www/my_app_name/releases/20170220142403 /var/www/my_app_n…
    ✔ 01 root@127.0.0.1 0.095s
00:20 deploy:log_revision
      01 echo "Branch master (at c476b25e8d16546dba93633992455bf2d7941455) deployed as release 20170220150828 by " >> /var/www/my_app_name/revisions.log
    ✔ 01 root@127.0.0.1 0.013s
```