PM2でnodejsアプリを動かす


foreverは使ったことあるが、pm2の方が高機能という話を聞いたので使ってみる。

# PM2のインストール
グローバルインストールする

```
npm i -g pm2
```

pm2コマンドが認識されていればインストールOK

# PM2を使ってアプリ起動

シンプルにjsを起動するだけなら`pm2 start`を使う。

```
pm2 start jsファイル
```

jsファイルを指定してもいいが、`--name`で名前つきでスクリプトを起動すると便利

というか、名前がないと操作が不便すぎるので必須だと思う。
ファイル名が main.js だった場合、pm2 list でアプリ一覧を表示したとき、main.js とでてきて「これは何のアプリだっけ？」となるからだ。

今回は例として、slack-bot というアプリ名でpm2起動する

```
$ pm2 start main.js --name slack-bot

[PM2] Starting /home/pi/dev/slack-bot/main.js in fork_mode (1 instance)
[PM2] Done.
┌───────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────┬───────────┬──────┬──────────┐
│ App name  │ id │ mode │ pid  │ status │ restart │ uptime │ cpu │ mem       │ user │ watching │
├───────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼───────────┼──────┼──────────┤
│ slack-bot │ 0  │ fork │ 1432 │ online │ 0       │ 0s     │ 12% │ 20.0 MB   │ pi   │ disabled │
└───────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────┴───────────┴──────┴──────────┘
```

statusが`online`になったので起動している。

# 再起動
`pm2 restart アプリ名`


```
$ pm2 restart slack-bot
Use --update-env to update environment variables
[PM2] Applying action restartProcessId on app [slack-bot](ids: 0)
[PM2] [slack-bot](0) ✓
┌───────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────┬───────────┬──────┬──────────┐
│ App name  │ id │ mode │ pid  │ status │ restart │ uptime │ cpu │ mem       │ user │ watching │
├───────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼───────────┼──────┼──────────┤
│ slack-bot │ 0  │ fork │ 1480 │ online │ 1       │ 0s     │ 66% │ 15.1 MB   │ pi   │ disabled │
└───────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────┴───────────┴──────┴──────────┘
 Use `pm2 show <id|name>` to get more details about an app
```

pidが変わったので再起動したっぽい

# 停止する
pm2 stop アプリ名

```
$ pm2 stop slack-bot
[PM2] Applying action stopProcessId on app [slack-bot](ids: 0)
[PM2] [slack-bot](0) ✓
┌───────────┬────┬──────┬─────┬─────────┬─────────┬────────┬─────┬────────┬──────┬──────────┐
│ App name  │ id │ mode │ pid │ status  │ restart │ uptime │ cpu │ mem    │ user │ watching │
├───────────┼────┼──────┼─────┼─────────┼─────────┼────────┼─────┼────────┼──────┼──────────┤
│ slack-bot │ 0  │ fork │ 0   │ stopped │ 1       │ 0      │ 0%  │ 0 B    │ pi   │ disabled │
└───────────┴────┴──────┴─────┴─────────┴─────────┴────────┴─────┴────────┴──────┴──────────┘
 Use `pm2 show <id|name>` to get more details about an app
```
 
statusがstoppedになってるので停止したようだ。
 
# ログを見る
 
pm2 logs アプリ名
 
```
 $ pm2 logs slack-bot
[TAILING] Tailing last 15 lines for [slack-bot] process (change the value with --lines option)
/home/pi/.pm2/logs/slack-bot-error-0.log last 15 lines:
...
```

デフォルトだと15行しか表示されないため、表示行数を増やすと見やすい。

```
pm2 logs slack-bot --lines 50
```
# ログを消す

`pm2 flush`

# アプリ状態を見る

`pm2 show アプリ名`

アプリの状態/パス/バージョンが見れる。

```
┌───────────────────┬─────────────────────────────────────────────────────────────┐
│ status            │ online                                                      │
│ name              │ slack-bot                                             │
│ restarts          │ 2                                                           │
│ uptime            │ 3h                                                          │
│ script path       │ /home/pi/dev/slack-bot/receptionist.js                │
│ script args       │ token=xoxb-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx                  │
│ error log path    │ /home/pi/.pm2/logs/slack-bot-error-0.log              │
│ out log path      │ /home/pi/.pm2/logs/slack-bot-out-0.log                │
│ pid path          │ /home/pi/.pm2/pids/slack-bot-0.pid                    │
│ interpreter       │ node                                                        │
│ interpreter args  │ N/A                                                         │
│ script id         │ 0                                                           │
│ exec cwd          │ /home/pi/dev/slack-bot                                │
│ exec mode         │ fork_mode                                                   │
│ node.js version   │ 10.4.1                                                      │
│ watch & reload    │ ✔                                                           │
│ unstable restarts │ 0                                                           │
│ created at        │ 2018-11-19T02:17:46.158Z                                    │
└───────────────────┴─────────────────────────────────────────────────────────────┘
 Code metrics value
┌─────────────────┬────────┐
│ Loop delay      │ 1.49ms │
│ Active requests │ 0      │
│ Active handles  │ 5      │
└─────────────────┴────────┘
```

# アプリをモニタリングする

起動しているアプリのCPU使用率、メモリ使用量、ループ遅延、リクエスト/分を確認できる。

```
pm2 monit
```

見やすくて少しカッコいい

![スクリーンショット 2018-04-27 18.41.53.png](https://qiita-image-store.s3.amazonaws.com/0/52227/ec260e1a-94a1-0e45-ddec-5ba6a1b46295.png "スクリーンショット 2018-04-27 18.41.53.png")

PM2 Plusというサービスがあり、Webでダッシュボード的な情報を見れるようだ。（詳細は未確認）
https://pm2.io/doc/en/plus/quick-start/

# 設定ファイルを用いた起動指定

YamlとJsonで起動オプションを設定ファイルに定義できる。
今回はYamlで作成してみる。

```yaml
# ファイル名：pm2config.yml（ファイル名は自由です）

name: slack-bot                        # アプリ名
script: main.js                        # スクリプトファイルパス
watch: true                            # フォルダやサブフォルダ内のファイルが変更された場合、アプリは再読み込みされます
log-date-format: "YYYY-MM-DD HH:mm Z"  # ログに日付を追加

```

設定ファイルで使える項目は以下リンク
https://pm2.io/doc/en/runtime/reference/ecosystem-file/#apps-options

設定ファイルで起動する

```
pm2 start pm2.yml
pm2 stop pm2.yml
pm2 restart pm2.yml
```

# 参考にしたリンク
- [\[Node\.js\] PM2を用いて本番環境でNodeJSアプリを動かす \- YoheiM \.NET](https://www.yoheim.net/blog.php?q=20170706)
- [PM2 \- Process File](http://pm2.keymetrics.io/docs/usage/application-declaration/)