2020年9月27日日曜日

Node.jsサーバーの自動起動でエラーが発生する

もうちょっと正確に説明すると、

  • プロセスマネージャーに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つ。

  1. -rオプションを使わない
    • dotenvモジュールなら、プログラム内で読み込むコードを記述する
    • 数行の初期化コードを書く根性があるならこれがベストかもしれない
  2. clusterモードを使わない
    • forkモードを使う
    • clusterモードは複数のプロセスを起動してもlistenするポートが1つで済むけど、forkモードはプロセスの数だけポートをlistenする必要がある
  3. pm2 startupを使わない
    • cronの@rebootなど、別の方法でブート時に自動起動の設定を入れる
    • そもそも@rebootってcron標準の機能だったっけ?そもそもcronに標準規格的なものあったっけ?
  4. PM2を使わない

なるべくコードは書きたくない派なので1は却下。そしてclusterモードは便利なので2も却下。

PM2に慣れているし、StrongLoopを使うことでこの問題が解消するかもわからないので4も却下。

というわけで3の@rebootで対応しました。

そのうち、こういうノウハウを含めたNode.jsの実環境導入についての記事も書くかもしれません。

0 件のコメント:

コメントを投稿