Edited at

Capistrano3でrailsデプロイ(+unicorn)

More than 1 year has passed since last update.

前回、capistrano3が動くまでを確認したので次は、railsをデプロイします。


■capistrano-rails

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


Gemfile

gem 'capistrano-rails'


$ bundle


capistrano-railsの3つのモジュールを有効にする場合と個別に有効にする場合


Capfile

require "capistrano/rails"



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の設定が必ずいる


config/deploy/production.rb

server "127.0.0.1",

user: "root",
roles: %w{web app db}


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を利用します)


Gemfile

gem "capistrano3-unicorn"


$ bundle


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


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で設置してあるよ


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