node server.jsでアプリを起動して,SSHを切ったら止まった── Nodeアプリの本番運用で誰もが通る失敗だ.これを解決し,常駐・自動再起動・マルチコア活用・ログ管理を一手に引き受けるのがPM2だ.

PM2はNode.jsエコシステムで広く使われるプロセスマネージャだ.アプリをデーモン化し,クラッシュから自動復帰させ,複数コアを活用し,ログを集約する.Node本番運用の定番ツールである.

この記事は,VPSでNodeアプリを運用する個人開発者に向けている.PM2の基本操作から,クラスタモード,ゼロダウンタイムリロード,OS再起動への対応,systemdとの使い分けまでを解説する.

読み終えたとき,あなたのNodeアプリは落ちても自動で復帰し,全CPUコアを活かし,無停止で更新できる本番品質の運用になっている.

なぜnode直起動ではダメなのか

node server.jsでの直起動には,本番に耐えない問題が複数ある.SSHを切ると止まる,クラッシュしたら復帰しない,OS再起動で消える,1コアしか使わない,ログが流れて消える

これらを一つずつ手当てするのは大変だ.PM2はこれらをまとめて解決する.デーモン化して常駐させ,クラッシュを検知して再起動し,全コアを使い,ログをファイルに残す.

とくにNodeはシングルスレッドで動くため,何もしないと1コアしか使えない.多コアのVPSの性能を活かすには,PM2のクラスタモードのような仕組みが要る.

PM2は,Nodeアプリを「開発で動く」から「本番で安定して動き続ける」へ引き上げる定番の道具だ.

PM2の基本 ― 起動・一覧・ログ

PM2の基本操作はシンプルだ.アプリをpm2 startで起動すれば,バックグラウンドで常駐し,クラッシュから自動復帰する.

PM2の基本コマンド

npm install -g pm2
pm2 start server.js --name myapp   # 起動(常駐+自動再起動)
pm2 list                            # 稼働中プロセス一覧
pm2 logs myapp                      # ログをリアルタイム表示
pm2 restart myapp                   # 再起動
pm2 stop myapp                      # 停止
pm2 delete myapp                    # 管理から削除

pm2 startした時点で,アプリはデーモン化され,クラッシュしても自動で再起動される.pm2 listでCPU・メモリ・再起動回数を一覧でき,pm2 logsでログを追える.node直起動の弱点の多くが,この時点で解消される.

クラスタモード ― 全CPUコアを活用する

Nodeはシングルスレッドだが,PM2のクラスタモードを使えば,CPUコア数だけプロセスを立ち上げ,負荷を分散できる.多コアVPSの性能を引き出せる.

クラスタモードで起動

# CPUコア数分のインスタンスを起動
pm2 start server.js -i max --name myapp
# 特定数を指定する場合
pm2 start server.js -i 4 --name myapp
# スケール変更
pm2 scale myapp 2

-i max全CPUコアを使う.PM2が内蔵ロードバランサで各インスタンスにリクエストを分散する(Nodeのcluster機能を利用).これにより,4コアのVPSなら理論上4倍のリクエストを捌ける.ただしアプリが状態を持たない(ステートレス)ことが前提だ──セッション等はRedis等で共有する(Redis記事参照).

OS再起動への対応 ― startupで永続化

PM2はクラッシュからは復帰するが,OSを再起動すると消える.これを防ぐのがpm2 startuppm2 saveだ.OS起動時にPM2と管理下のアプリが自動で立ち上がる.

OS再起動後も自動起動させる

pm2 startup          # 表示されたコマンドを実行(systemd登録)
pm2 start server.js --name myapp
pm2 save             # 現在のプロセスリストを保存
# 以降,OS再起動後も自動で復帰する

pm2 startupPM2自体をsystemdサービスとして登録するコマンドを生成する.それを実行し,pm2 saveで現在の構成を保存すれば,OS再起動後もアプリが自動で立ち上がる.この設定を忘れると「サーバー再起動したらサービスが止まっていた」事故になる.

ゼロダウンタイムリロード ― 無停止で更新

PM2のクラスタモードでは,無停止での更新(reload)ができる.インスタンスを1つずつ入れ替えるため,更新中もリクエストを処理し続けられる.

ゼロダウンタイムリロード

# コード更新後
git pull origin main
npm ci --omit=dev
pm2 reload myapp     # 1つずつ入れ替え(無停止)
# restart は全部一斉に止めて再起動(一瞬のダウンあり)
# reload は順次入れ替えでダウンタイムなし

restartは全インスタンスを一斉に再起動する(一瞬のダウン)が,reloadはインスタンスを1つずつ入れ替えるため,ダウンタイムなしで更新できる.これはクラスタモードならではの強みで,個人開発でも「更新時にサービスが途切れない」体験が手に入る.

ログ管理とエコシステムファイル

PM2はログをファイルに集約する.また設定ファイル(ecosystem.config.js)に起動構成を書いておけば,再現性のある起動ができる.

ecosystem.config.js

module.exports = {
  apps: [{
    name: 'myapp',
    script: 'server.js',
    instances: 'max',
    exec_mode: 'cluster',
    env: { NODE_ENV: 'production' },
    max_memory_restart: '500M'   // メモリ超過で自動再起動
  }]
}
// pm2 start ecosystem.config.js

ecosystem.config.jsに構成を書けば,起動オプションをコードとして管理でき,再現性が高まる.max_memory_restartはメモリリーク対策に有効で,指定メモリを超えたら自動で再起動する.ログはpm2 logsで見られ,pm2-logrotateモジュールでローテーションも設定できる(ログ肥大化を防ぐ).

PM2とsystemd ― どちらで管理するか

Nodeの常駐は,PM2でもsystemd(systemdの記事参照)でも実現できる.どちらを使うべきか.

PM2systemd
クラスタ(マルチコア)◎ 内蔵△ 自前で工夫
無停止リロード
Node以外も管理△(Node向き)◎(言語非依存)
OS標準×(別途導入)

Nodeアプリでマルチコア活用や無停止リロードが欲しいならPM2言語を問わずOS標準で統一管理したいならsystemdだ.PM2自体をpm2 startupでsystemdに登録する(PM2をsystemdが管理し,PM2がNodeを管理する)構成が,両者の良いとこ取りになる.

補論:PM2のクラスタは「マルチコアVPS」で真価を発揮する

PM2のクラスタモードは,CPUコアが多いほど効果が出る.1コアのVPSではクラスタの恩恵は薄く,複数コアあって初めて「コア数分のスループット」が活きる.

高速NVMe・50種類以上のOSテンプレートに対応した国内VPS─シン・VPS─ はプランに応じて複数のvCPUを選べ,NVMe SSDで起動・リロードも軽快だ.クラスタモードで全コアを使い切り,ゼロダウンタイムリロードで無停止更新する── PM2の強みをフルに引き出せる.スナップショットで構成変更も安全に試せる.

PM2で安定運用するNodeアプリを,独自ドメイン+HTTPSで公開しよう.取り扱い400種類以上のドメイン取得サービス─ムームードメイン─ でドメインを取得し,前段のリバースプロキシ(Nginx/Caddy)からPM2のアプリに振り分ければ,本格的なサービス構成が完成する.

よくある質問(FAQ)

Q1.PM2とsystemdどちらを使う?

Nodeでマルチコア活用や無停止リロードが欲しいならPM2,言語非依存でOS標準統一ならsystemd.pm2 startupでPM2自体をsystemdに登録すれば両者を組み合わせられる.

Q2.クラスタモードの注意点は?

アプリがステートレスであることが前提だ.複数インスタンスで動くため,セッションやキャッシュはメモリに持たずRedis等で共有する.状態をプロセス内に持つと不整合が起きる.

Q3.OS再起動でPM2が消える

pm2 startupでsystemdに登録し,pm2 saveで構成を保存する.これでOS再起動後も自動復帰する.忘れると再起動でサービスが止まる.

Q4.restartとreloadの違いは?

restartは全インスタンス一斉再起動(一瞬のダウン),reloadは1つずつ入れ替え(無停止).クラスタモードならreloadでゼロダウンタイム更新ができる.

Q5.メモリリークが心配

max_memory_restartを設定すれば,指定メモリを超えたインスタンスを自動再起動する.リークの応急処置として有効だが,根本原因の調査も併せて行う.

Q6.ログが溜まりすぎる

pm2-logrotateモジュールを導入すれば,PM2のログを自動ローテーションできる(pm2 install pm2-logrotate).ログ肥大化によるディスク枯渇を防げる.

まとめ ― PM2でNodeアプリを本番品質に

PM2は,常駐・自動再起動・マルチコア活用・無停止リロード・ログ管理を一手に引き受け,Nodeアプリを本番品質に引き上げる.node直起動の弱点をまとめて解消する定番ツールだ.

今日やるべきことは,自分のNodeアプリをpm2 startで起動し,pm2 startuppm2 saveでOS再起動に備えること.これだけで常駐と自動復帰が手に入る.

マルチコアVPSなら,クラスタモードでさらに性能を引き出せる.スナップショットで戻せる環境で,PM2の本番運用を組み上げよう.