Node.jsアップデート後にforeverが動作しない時の対処
5月 31, 2023AmazonLinux_CentOS,OperatingSystem
Contents
概要
- 今回は、Node.js をアップデートしたら予期せぬトラブルを経験したので対処方法を紹介します。これまで、Node.js アプリケーションをデーモン化(永続化) するため、forever モジュールを使っていました。また、Linux起動時にforever も同時に開始したかったので、systemd でforever を自動起動させていました。
- トラブルのきっかけは、Node.js の脆弱性対策です。Node.js を最新バージョンへアップデート後に以下のWarning メッセージが出力され、Linux起動時にforever が動作しません。
- 原因は、Node.js 14.x 以降にアップグレードすると、forever モジュールに非対応となる様です。
forever: #033[33mwarn#033[39m: --minUptime not set. Defaulting to: 1000ms
forever: #033[33mwarn#033[39m: --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
forever: (node:1221) Warning: Accessing non-existent property 'padLevels' of module exports inside circular dependency
forever: (Use `node --trace-warnings ...` to show where the warning was created)
forever: (node:1221) Warning: Accessing non-existent property 'padLevels' of module exports inside circular dependency
forever をやめてsystemd で管理する
- Node.js アプリケーションのデーモン化(永続化) はforever モジュールを使わなくとも、systemd だけで実現できました。
Node.js の停止
- systemd に foreverを開始するための “app.service" サービスを登録していると仮定します。
- Node.js を停止するため、forever コマンドでアプリケーションを停止、systemctl コマンドでサービスを停止します。
# forever stopall
# systemctl stop app.service
# forever list
→「info: No forever processes running」が表示されることを確認する
# systemctl status app.service
→ 「Active: inactive (dead)」が表示されることを確認する
systemd の設定変更
- 以下変更前の systemd のユニットファイルです。
/etc/systemd/system/app.service
[Unit]
Description=Node.js Application
After=multi-user.target systemd-update-utmp-runlevel.service
[Service]
Type=forking
User=root
WorkingDirectory=/home/ec2-user/node
ExecStart=/usr/bin/forever start app.js
KillMode=process
Restart=on-failure
RestartSec=60s
[Install]
WantedBy=multi-user.target
# vi /etc/systemd/system/app.service
- 以下変更後の systemd のユニットファイルです。Node.js アプリケーションを常時起動させるため、「Restart=always」を設定します。「Restart=on-failure」を指定しない理由は、Node.js が正常終了した際に起動しないからです。
/etc/systemd/system/app.service
[Unit]
Description=Node.js Application
After=multi-user.target systemd-update-utmp-runlevel.service
[Service]
Type=simple
User=root
WorkingDirectory=/home/ec2-user/node/
ExecStart=/usr/bin/node app.js
KillMode=process
Restart=always
[Install]
WantedBy=multi-user.target
Node.js の起動
- systemctl コマンドでサービスを起動します。
- サービス起動後、forever プロセスは存在せず、node プロセスが存在することを確認できます。
# systemctl daemon-reload
# systemctl start app.service
# systemctl status app.service
→ 「Active: active (running)」が表示されることを確認する
# ps aux | grep node | grep -v grep
root 3199 2.1 1.0 976220 39280 ? Ssl 06:17 0:00 /usr/bin/node app.js
→ /usr/bin/node プロセスが存在することを確認する
Node.js を最新にアップデートする
Node.js のアップデート
- libuvのバージョンが 1.43.0 未満の場合、libuvを事前にアップデートします。libuvをアップデート後、バージョンが 1.43.0 以上、取得先のリポジトリが @epel であることを確認します。
- Node.js のアップデートは、yum update nodejs にて行います。Node.js をアップデート後、Node.jsのバージョンが更新されたことを確認します。
# systemctl stop app.service
# yum list installed | grep libuv
libuv.x86_64 1:1.23.2-1.amzn2.0.2 @amzn2-core
# yum update --disablerepo='*' --enablerepo=epel libuv
# yum list installed | grep libuv
libuv.x86_64 1:1.44.2-1.el7 @epel
# node -v
v6.17.1
# yum update nodejs
# node -v
v16.18.1
Node.js の起動
- systemctl コマンドでサービスを起動します。
# systemctl start app.service
# systemctl status app.service
→ 「Active: active (running)」が表示されることを確認する
AmazonLinux_CentOS,OperatingSystem
Posted by takaaki