Capistrano で数回 deploy したあとに pm2 で起動できなくなる現象の対処
Capistrano で何度か deploy を行っていると、いずれ pm2 restart ecosystem.json
でエラーが発生して起動できなくなります。
PM2 | Error: spawn node ENOENT
PM2 | at _errnoException (util.js:1003:13)
PM2 | at Process.ChildProcess._handle.onexit (internal/child_process.js:201:19)
PM2 | at onErrorNT (internal/child_process.js:389:16)
PM2 | at process._tickCallback (internal/process/next_tick.js:152:19)
この問題は公式ドキュメントのチュートリアルでも解説されている有名なものだったのですが、エラーログや日本語からの検索では対処法の発見が困難であったため書き残しておきます。
公式ドキュメント
原因
Capistrano は deploy において新しい releases/YYYYMMDDHHMMSS
ディレクトリを作成し、転送完了後に symlink をはりかえて current
とする動作があります。古くなった releases/YYYYMMDDHHMMSS
ディレクトリは設定回数分の履歴を経た後に削除されます。
pm2 のデフォルトでは初めて pm2 start
pm2 restart
を行ったときに current
であった releases/YYYYMMDDHHMMSS
ディレクトリを基準として ecosystem.json
を参照し続けるため、上記の削除発生後の起動では ENOENT
エラーが発生することになります。
対処
ecosystem.json
に cwd
として current
を設定します。これにより参照先が current
として記録されるので削除の影響を受けることがありません。
{
"apps": [
{
"name": "SSR Server",
"script": "./built/server/index.js",
"cwd": "/home/www/project_root/current",
}
]
}
cwd
のハードコードがつらい場合は PWD
を使うといいでしょう。
module.exports = {
apps: [
{
name: 'SSR Server',
script: './built/server/index.js',
cwd: process.env.PWD,
},
],
};