もうちょっと正確に説明すると、
- プロセスマネージャーにPM2を使っている
- Systemd環境(Ubuntuなど)で自動起動の設定を入れている
- Node.jsの起動パラメーターとして
-r
でモジュールを指定している
こういう条件が重なったときに "Cannot find module"
というエラーが出てプロセスを起動できないことがあります。2番目の条件は必須かどうかわかりません。
具体的な状況
例えば、dotenvモジュールを使うとnode -r dotenv/config
で実行時に.env
ファイルから環境変数を動的に設定できます。
そして、PM2のスタートアップ登録コマンドpm2 startup
でSystemdに登録すると、再起動後に "Cannot find module"
が出て起動できません。
原因
PM2の内部処理までは追えていないのですが、いろいろ調べたところclusterモードで実行する場合にこういうエラーが起きるっぽいことがわかりました。
解決方法
解決方法は少なくとも4つ。
-r
オプションを使わない- dotenvモジュールなら、プログラム内で読み込むコードを記述する
- 数行の初期化コードを書く根性があるならこれがベストかもしれない
- clusterモードを使わない
- forkモードを使う
- clusterモードは複数のプロセスを起動してもlistenするポートが1つで済むけど、forkモードはプロセスの数だけポートをlistenする必要がある
pm2 startup
を使わない- cronの
@reboot
など、別の方法でブート時に自動起動の設定を入れる -
そもそも
@reboot
ってcron標準の機能だったっけ?そもそもcronに標準規格的なものあったっけ? - PM2を使わない
- StrongLoopとかあったような。
なるべくコードは書きたくない派なので1は却下。そしてclusterモードは便利なので2も却下。
PM2に慣れているし、StrongLoopを使うことでこの問題が解消するかもわからないので4も却下。
というわけで3の@reboot
で対応しました。
そのうち、こういうノウハウを含めたNode.jsの実環境導入についての記事も書くかもしれません。
0 件のコメント:
コメントを投稿