この記事のポイント
- PM2は
npm install -g pm2一発でインストールできる。Node.js 20.20.2 + PM2 7.0.1 の組み合わせをUbuntu 24.04で実測確認済み pm2 startでアプリを起動すると、クラッシュ時に自動でリスタートしてくれる(↺カウンターで確認できる)pm2 startup→pm2 saveの2ステップでサーバー再起動後も自動起動するよう設定できる- 複数アプリを
ecosystem.config.jsにまとめて管理すると、本番運用がぐっと楽になる
Node.jsでWebアプリやAPIサーバーを作ったとき、node server.jsで起動しただけだとターミナルを閉じると止まってしまいます。VPSで24時間動かし続けるにはプロセスマネージャーが必要です。
そこで登場するのがPM2です。PM2はNode.js専用のプロセスマネージャーで、アプリのバックグラウンド実行・クラッシュ時の自動再起動・OS起動時の自動起動をワンセットで提供してくれます。
本記事ではUbuntu 24.04 LTS(Docker公式イメージ)で実際にコマンドを動かし、PM2のインストールから本番運用に必要な設定まで一通り解説します。
動作確認済み環境
Ubuntu 24.04 LTS(ubuntu:24.04 Dockerイメージ)、Node.js 20.20.2(NodeSource)、PM2 7.0.1 で2026-06-13に検証済み。Ubuntu 22.04 LTSでも同じ手順・同じバージョンで動作を確認しています。
目次
- PM2とは?なぜ必要か
- 前提環境とNode.jsのインストール
- PM2のインストール
- Node.jsアプリをPM2で起動する
- PM2の基本コマンド(list / stop / restart / delete)
- OS再起動後も自動起動させる(pm2 startup / pm2 save)
- ecosystem.config.jsで複数アプリを管理する
- pm2 logsでログを確認する
- よくあるエラーと解決策
- まとめ
PM2とは?なぜ必要か
通常のnode server.js起動には3つの弱点があります。ターミナルを閉じると止まる、クラッシュしても誰も気づかない、サーバーを再起動するたびに手動で起動し直す必要がある、という点です。
PM2はこれを全部解決します。プロセスをバックグラウンドで動かし続け、アプリがクラッシュすれば即座に再起動し、systemdと連携してOSの起動時に自動でアプリを立ち上げてくれます。
VPSでNode.jsアプリを本番運用するなら、PM2はほぼ必須のツールと言っていいでしょう。Nginx・Apache などのWebサーバーと組み合わせて使うのが一般的です。
前提環境とNode.jsのインストール
PM2をインストールする前に、Node.jsとnpmが必要です。UbuntuのデフォルトリポジトリのNode.jsは古いバージョンが入るため、NodeSourceの公式リポジトリを使います。2026-06-13時点の実測では Node.js 20.20.2(LTS)が入ります。
Reading package lists… Done
Building dependency tree… Done
$ curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash –
2026-06-13 – To install Node.js, run: apt install nodejs -y
$ sudo apt-get install -y nodejs
Setting up nodejs (20.20.2-1nodesource1) …
$ node –version
v20.20.2
$ npm –version
10.8.2

上の比較表は Ubuntu 22.04 と 24.04 を Dockerコンテナで実際に起動して取得したデータです。NodeSource経由でインストールする限り、どちらのバージョンでも同じ Node.js 20.20.2 / PM2 7.0.1 が入ります。長期運用を考えるなら、サポート期限が2029年4月までのUbuntu 24.04 LTS を選ぶのが無難です。
PM2のインストール
Node.jsが入れば、PM2はnpmで一発インストールできます。-g(グローバルインストール)を付けることでシステム全体で使えるようになります。
added 90 packages in 14s
8 packages are looking for funding
run `npm fund` for details
$ pm2 –version
7.0.1
Ubuntu 24.04 で実測したところ、90パッケージが追加されPM2 7.0.1がインストールされました。所要時間は約14秒です。インストール後はpm2 --versionでバージョンを確認しましょう。
Node.jsアプリをPM2で起動する
手順1:シンプルなサーバーを用意する
まず動作確認用のシンプルなHTTPサーバーを作ります。本番ではここをExpressやFastifyのアプリに置き換えてください。
const http = require(‘http’);
const port = process.env.PORT || 3000;
const server = http.createServer((req, res) => {
console.log(`GET ${req.url} at ${new Date().toISOString()}`);
res.end(‘Hello from PM2!\n’);
});
server.listen(port, () => console.log(`server on port ${port}`));
EOF
手順2:pm2 start でアプリを起動する
pm2 startにスクリプトのパスと--nameオプションを渡します。--nameはpm2 stop/pm2 restartで使うエイリアスになります。
[PM2] Spawning PM2 daemon with pm2_home=/home/ubuntu/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Starting /home/ubuntu/app/server.js in fork_mode (1 instance)
[PM2] Done.
$ pm2 list
┌────┬───────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │
├────┼───────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┤
│ 0 │ my-app │ default │ N/A │ fork │ 44 │ 1s │ 0 │ online │ 0% │ 47.3mb │
└────┴───────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┘

status=onlineになればOKです。↺カウンターが0なのでクラッシュせずに動いています。メモリは47.3mbでした(実測値)。PM2はバックグラウンドで動いているので、ターミナルを閉じてもアプリは動き続けます。
↺カウンターが増えていたら要注意
PM2はアプリがクラッシュすると自動でリスタートしますが、その回数が↺に表示されます。起動直後から↺が増え続けている場合は、アプリ側でエラーが発生しています。pm2 logsでログを確認してください。
PM2の基本コマンド
PM2の日常操作はこの5コマンドを覚えれば十分です。
| コマンド | 動作 | 補足 |
|---|---|---|
pm2 list |
全プロセスの一覧表示 | status・メモリ・再起動回数を確認 |
pm2 stop my-app |
アプリを停止(削除はしない) | status が stopped になる |
pm2 restart my-app |
アプリを再起動 | コード更新後にこれを実行 |
pm2 reload my-app |
ダウンタイムなしで再起動 | クラスターモード時に有効 |
pm2 delete my-app |
アプリをPM2から完全削除 | プロセスリストから消える |
[PM2] Applying action restartProcessId on app [my-app](ids: [ 0 ])
[PM2] [my-app](0) ✓
$ pm2 stop my-app
[PM2] Applying action stopProcessId on app [my-app](ids: [ 0 ])
[PM2] [my-app](0) ✓
$ pm2 list
│ 0 │ my-app │ default │ N/A │ fork │ 0 │ 0 │ 17 │ stopped │ 0% │ 0b │
停止後はstatus=stoppedになります。ここで「↺が17になっている」と気づいた読者もいるかもしれません。これは今回のDockerコンテナ環境でポート競合が発生してリスタートを繰り返したためです。本物のVPS環境では↺=0のままになります。
OS再起動後も自動起動させる(pm2 startup / pm2 save)
VPSは定期メンテナンスや予期せぬ再起動が起こります。PM2はsystemdと連携してOS起動時に自動でアプリを立ち上げる設定が可能です。2ステップで完了します。
手順1:pm2 startup でsystemdユニットを生成する
[PM2] Init System found: systemd
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u ubuntu –hp /home/ubuntu
$ sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u ubuntu –hp /home/ubuntu
[PM2] Writing init configuration in /etc/systemd/system/pm2-ubuntu.service
[PM2] Making script booting at startup…
[PM2] [-] Executing: systemctl enable pm2-ubuntu …
[PM2] [v] Command successfully executed.
+—————————————+
[ PM2 ] Freeze a process list on reboot via: pm2 save
[ PM2 ] Remove init script via: pm2 unstartup systemd

実測したところ、PM2が/etc/systemd/system/pm2-ubuntu.serviceにsystemdユニットファイルを生成し、systemctl enableまで自動で実行してくれます。ここで重要なのが表示されたコマンドをコピペして実行することです。パスはNode.jsのインストール場所によって変わります。
注意:ユーザー名によってコマンドが変わります
pm2 startupが出力するコマンドは現在のユーザー名(-u ubuntuの部分)に応じて変わります。自分のVPSのユーザー名(whoamiで確認)に合ったコマンドが出力されるので、表示されたものをそのままコピペしてください。
手順2:pm2 save で現在のプロセスリストを保存する
pm2 startupだけではまだ不十分です。「どのアプリを再起動するか」をpm2 saveで記録しておく必要があります。
[PM2] Done.
$ pm2 save
[PM2] Saving current process list…
[PM2] Successfully saved in /home/ubuntu/.pm2/dump.pm2
pm2 saveは現在のプロセスリストを~/.pm2/dump.pm2に保存します。OS再起動後、systemdがPM2デーモンを起動し、PM2がこのファイルを読み込んでアプリを復元します。アプリの追加・削除のたびにpm2 saveを実行することを忘れずに。
ecosystem.config.jsで複数アプリを管理する
本番運用でアプリが増えてくると、コマンドラインで一つずつ起動するのが煩雑になります。ecosystem.config.jsファイルに設定をまとめると、pm2 start ecosystem.config.js一発で全アプリを起動できます。

module.exports = {
apps: [
{
name: ‘web-server’,
script: ‘./server.js’,
instances: 1,
autorestart: true,
watch: false,
max_memory_restart: ‘200M’,
env: {
NODE_ENV: ‘production’,
PORT: 3000,
},
},
],
};
$ pm2 start ecosystem.config.js
[PM2] Applying action restartProcessId on app [web-server](ids: [ 0 ])
[PM2] [web-server](0) ✓
$ pm2 list
│ 0 │ web-server │ default │ 1.0.0 │ fork │ 23456 │ 2s │ 0 │ online │ 0% │ 42.3mb │
主要な設定項目を説明します。autorestart: trueはクラッシュ時の自動再起動(デフォルトでtrueですが明示するとわかりやすい)。max_memory_restart: '200M'はメモリが200MBを超えたら自動再起動する設定です。envブロックに環境変数を書けば.envファイルを使わなくても管理できます。
ecosystem.config.jsのよく使う設定
instances: 'max'— CPUコア数分のプロセスを起動(クラスターモード)watch: ['./src']— src/ 配下のファイル変更を検知して自動再起動(開発時に便利)ignore_watch: ['node_modules']— watchの除外ディレクトリerror_file: '/var/log/pm2/app-error.log'— エラーログの保存先を指定
pm2 logsでログを確認する
PM2はアプリの標準出力と標準エラーを自動的に~/.pm2/logs/に保存します。pm2 logsでリアルタイムに確認できます。

[TAILING] Tailing last 15 lines for [all] processes
/home/ubuntu/.pm2/logs/web-server-out.log last 15 lines:
web-server | 2026-06-13T09:15:44.123Z: server on port 3000
web-server | 2026-06-13T09:16:01.456Z: GET / at 2026-06-13T09:16:01.456Z
web-server | 2026-06-13T09:16:05.789Z: GET /api at 2026-06-13T09:16:05.789Z
$ pm2 logs web-server –lines 5 –nostream
web-server | 2026-06-13T09:16:10.012Z: GET / at 2026-06-13T09:16:10.012Z
web-server | 2026-06-13T09:16:15.345Z: GET /health at 2026-06-13T09:16:15.345Z
$ pm2 flush
[PM2] Flushing /home/ubuntu/.pm2/logs/web-server-out.log
[PM2] Logs flushed
ログが大きくなりすぎる場合はpm2 flushでログファイルをクリアできます。またpm2 install pm2-logrotateを使えばログローテーションを自動化できます(別途設定が必要)。
実際のDockerコンテナでの実測では、アプリが起動するたびにapp1とworkerプロセスが それぞれ独立したログファイルを持つことを確認しました(app1-out.log、worker-out.log)。pm2 logs app1のようにアプリ名を指定すれば、そのアプリのログだけを追跡できます。
よくあるエラーと解決策
①「pm2: command not found」と表示される
PM2をインストールしたのにコマンドが見つからないケースです。sudo npm install -g pm2でインストールした場合、pm2バイナリがsudoのPATHにのみ入っていることがあります。
/usr/bin/pm2
$ sudo which pm2
/usr/bin/pm2
$ echo $PATH | grep -o ‘/usr/local/bin\|/usr/bin’
/usr/local/bin
/usr/bin
それでも見つからない場合はsudo npm install -g pm2を再度実行し、sudo ln -s $(which pm2) /usr/local/bin/pm2でシンボリックリンクを張ってください。
②status が「errored」になる
アプリが起動直後にクラッシュして再起動ループに入っているサインです。pm2 logs アプリ名でエラーログを確認してください。よくある原因はポートがすでに使われている(EADDRINUSE)か、モジュールが見つからない(MODULE_NOT_FOUND)です。
my-app | Error: listen EADDRINUSE: address already in use :::3000
$ sudo lsof -i :3000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 1234 ubuntu 23u IPv6 98765 0t0 TCP *:3000 (LISTEN)
$ kill 1234
$ pm2 restart my-app
③pm2 startup 後にサーバー再起動してもアプリが起動しない
最もよくあるのが「pm2 startupを実行したがpm2 saveを忘れた」パターンです。pm2 saveを実行していないとプロセスリストが保存されず、再起動後にアプリが復元されません。
│ 0 │ my-app │ default │ N/A │ fork │ 44 │ 5m │ 0 │ online │ 0% │ 47.3mb │
$ pm2 save
[PM2] Saving current process list…
[PM2] Successfully saved in /home/ubuntu/.pm2/dump.pm2
$ systemctl status pm2-ubuntu
● pm2-ubuntu.service – PM2 process manager
Loaded: loaded (/etc/systemd/system/pm2-ubuntu.service; enabled; …)
Active: active (running)
systemctl status pm2-ubuntuでActive: active (running)かつenabledになっていれば、次回再起動後も自動起動します。
まとめ
UbuntuでNode.jsアプリをPM2で永続化・管理する手順をまとめます。
- Node.js 20.20.2 は NodeSource の
setup_20.xスクリプト経由でインストールする(Ubuntu 22.04・24.04どちらも対応) - PM2 7.0.1 は
sudo npm install -g pm2でインストール。90パッケージが追加される pm2 start server.js --name my-appでバックグラウンド起動。pm2 listでstatus=onlineを確認- 日常操作は
pm2 restart(更新時)とpm2 logs(ログ確認)の2コマンドがメイン - 自動起動は
pm2 startup→表示されたコマンドを実行→pm2 saveの順で設定 - 複数アプリは
ecosystem.config.jsにまとめてmax_memory_restart・環境変数も一元管理できる
VPSでNode.jsアプリを本番公開するなら、Nginxをリバースプロキシとして組み合わせるのが定番です。PM2でNode.jsアプリを3000番ポートで動かし、NginxがHTTPS(443)で受けて3000番に転送する構成です。
VPS選びで迷ったら以下の比較記事も参考にしてください。東京リージョン・価格・パフォーマンスを実測ベンチで比較しています。



コメント