node.js を Capistrano3 でデプロイ時に pm2 をいい感じに再起動したい


pm2を再起動したい

node.js を Capistrano3 でデプロイする時に pm2 を restart したいです。

単純にこれでもまぁいいのですが、

execute :pm2, 'restart', fetch(:app_name)

予めpm2で目的のアプリケーションが起動していない場合にコケます。プロビジョニング直後とか。
なので deploy.rb で pm2 のステータスによって、restart するか startするか処理をわけたいのです。

pm2の状態を取る

pm2のステータスを取る、というのでググるとよく出てくるのはこれ。
(何かのコピペが広がったんでしょうか。決まってjlistのオプションにアプリケーション名らしきものを渡してますが意味無いんじゃ)

ps = JSON.parse(capture :pm2, :jlist, fetch(: app_command))
if ps.empty?
  return nil
else
  do something
end

これだと、デプロイ先のサーバでpm2で起動しているアプリケーションが1つの場合は兎も角、複数ある場合には意図しない結果になります。

起動 or 再起動

こんな感じで乗り切りました。
もっとエレガントな方法があれば知りたいです。

ps = JSON.parse(capture :pm2, :jlist)

is_exist = false
ps.each do |row|
  is_exist = true if row["name"] == fetch(:app_name)
end

if !is_exist
  execute 'NODE_ENV=#{stage}', :pm2, 'start', "#{current_path}/app.js", '--name', fetch(:app_name)
else
  execute :pm2, 'stop', fetch(:app_name)
  execute :pm2, 'delete', fetch(:app_name)
  execute 'NODE_ENV=#{stage}', :pm2, 'start', "#{current_path}/app.js", '--name', fetch(:app_name)
end

結論

未だに ruby 慣れない