9
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Capistranoでunicornとsidekiqをシンプルにrestartする

Posted at

デプロイ完了後、currentディレクトリが最新のものに切り替わりますが、その際、unicornやsidekiqを再起動しないと、以前のreleaseのものを参照してしまい、思わぬトラブルが起きてしまいます (起きました)。

簡単なことはシンプルにこなしたい

デプロイ時に自動でunicornとsidekiqを再起動させるため、capistrano3-unicornやcapistrano-sidekiqといったプラグインも使ってみましたが、コールバックで実行されるタイミングがよくわからなかったのと、プラグイン用の設定項目がいくつもある上それがバージョンによっては有ったり無かったりで、つまりは面倒くさそうだったので採用しませんでした。

また、初めてCapstranoを使う身としてはshared_pathやcurrent_pathがどのような扱いになっているのか、自分で手を動かしながら確認したかったというのもあり、あえて自前でタスクを作ってみました。

unicornにはダウンタイム無しで再起動するやり方もあるそうですが、今運用中のものは起動にあまり時間がかからないため、シンプルに一旦プロセスを落として新たに起動するという方法をとっています (sidekiqも同じ)。

またstartとstopというタスクを別々に作るのも面倒なので、シンプルにrestartタスクとしてまとめています。今のところ、これで上手く動いています。

config/deploy/production.rb
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

9
5
0

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
9
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?