デプロイ完了後、currentディレクトリが最新のものに切り替わりますが、その際、unicornやsidekiqを再起動しないと、以前のreleaseのものを参照してしまい、思わぬトラブルが起きてしまいます (起きました)。
簡単なことはシンプルにこなしたい
デプロイ時に自動でunicornとsidekiqを再起動させるため、capistrano3-unicornやcapistrano-sidekiqといったプラグインも使ってみましたが、コールバックで実行されるタイミングがよくわからなかったのと、プラグイン用の設定項目がいくつもある上それがバージョンによっては有ったり無かったりで、つまりは面倒くさそうだったので採用しませんでした。
また、初めてCapstranoを使う身としてはshared_pathやcurrent_pathがどのような扱いになっているのか、自分で手を動かしながら確認したかったというのもあり、あえて自前でタスクを作ってみました。
unicornにはダウンタイム無しで再起動するやり方もあるそうですが、今運用中のものは起動にあまり時間がかからないため、シンプルに一旦プロセスを落として新たに起動するという方法をとっています (sidekiqも同じ)。
またstartとstopというタスクを別々に作るのも面倒なので、シンプルにrestartタスクとしてまとめています。今のところ、これで上手く動いています。
set :stage, :production
set :rails_env, :production
server 'example.com', user: 'user', roles: %w(app db web)
set :rbenv_ruby, '2.3.1'
set :unicorn_config_path, release_path.join('config/unicorn.rb')
set :unicorn_pid_path, shared_path.join('tmp/pids/unicorn.pid')
set :sidekiq_pid_path, shared_path.join('tmp/pids/sidekiq.pid')
before 'deploy:updated', 'bower:install'
after 'deploy:publishing', 'unicorn:restart'
after 'deploy:publishing', 'sidekiq:restart'
namespace :unicorn do
task :restart do
on roles(:app) do
execute "kill -QUIT `cat #{fetch :unicorn_pid_path}`; true"
within current_path do
execute :bundle, :exec, "unicorn_rails -c #{fetch :unicorn_config_path} -E production -D"
end
end
end
end
namespace :sidekiq do
task :restart do
on roles(:app) do
execute "kill -QUIT `cat #{fetch :sidekiq_pid_path}`; true"
within current_path do
execute :bundle, :exec, 'sidekiq -d -e production'
end
end
end
end
エラーを無視
初めてデプロイする際やなんらかのトラブルによりpidファイルが示すプロセスが死んでいる場合、killが通らずタスクが途中停止してしまうため、下記のようにkillのあとに; true を返しています。
execute "kill -QUIT `cat #{fetch :unicorn_pid_path}`; true"
このようにLinuxコマンド側でエラーを無視することもできますが、下記のようにcapistrano3の機能を使っても同じことが実現できます。こちらの方が可読性は高いような気がします。
execute "kill -QUIT `cat #{fetch :unicorn_pid_path}`", raise_on_non_zero_exit: false
参考URL: http://stackoverflow.com/questions/758774/capistrano-bash-ignore-command-exit-status