インスタンスが起動したら自動的にNode.jsアプリが起動するようにする

# Node.jsアプリの自動起動をしたい

## はじめに

AWSでインスタンスを再起動するたびにアプリケーションを再起動するのが非常に面倒だったため、インスタンスが起動したら自動的にアプリケーションが起動するようにしました。

今回はPM2というプロセスマネージャーを利用してアプリの自動起動を行う方法を、作業メモを兼ねて紹介します。

## PM2とは

PM2はデーモンプロセスマネージャーです。

プロセスをデーモン化しておらず、シェルを抜けたらアプリケーションが終了していた、といった経験はみなさんあるのではないでしょうか。

PM2を利用するとプロセスをデーモン化することで、アプリケーションを起動した状態に保つことができます。

そのため、Node.jsアプリケーションの本番運用などに利用されているようです。

公式サイト: [PM2](https://pm2.keymetrics.io/)



## 導入

下記コマンドでインストールできます。

Node.jsやnpmは事前に[nvm](https://github.com/nvm-sh/nvm)などを利用してインストールしておきましょう。

```bash
$ npm install pm2@latest -g
# or
$ yarn global add pm2
```

下記コマンドでアプリケーションを開始できます。

```bash
$ pm2 start app.js
```

また、PM2は.jsファイル以外でも利用できます。
実はNode.jsアプリ以外も動かせます（

```bash
$ pm2 start bashscript.sh
$ pm2 start python-app.py --watch
$ pm2 start binary-file -- --port 1520
```

引用: [PM2 QUICK START](https://pm2.keymetrics.io/docs/usage/quick-start/)



## システムの起動時にアプリケーションを開始する

PM2はスタートアップスクリプトを生成することで、マシンの再起動後もプロセスリストをそのまま保持することができます。

つまり、マシンの再起動時にスクリプトやアプリケーションを自動的に開始することができます。

注意点や詳細については公式ドキュメントに記載がありますので、こちらもご覧ください。

引用: [PM2 STARTUP SCRIPT](https://pm2.keymetrics.io/docs/usage/startup/)



### スタートアップスクリプトの生成

スタートアップスクリプトを生成するには下記コマンドを入力します。

```bash
$ pm2 startup
```

上記コマンドを入力すると下記のようなメッセージが表示されます。

```bash
$ pm2 startup
[PM2] You have to run this command as root. Execute the following command:
      sudo su -c "env PATH=$PATH:/home/unitech/.nvm/versions/node/v4.3/bin pm2 startup <distribution> -u <user> --hp <home-path>
```

メッセージに従って、コマンドをコピーして実行してください。



### 現在のプロセスリストの保存

マシンの再起動時に再生成したいアプリケーションをすべて起動したら、現在のプロセスリストを保存する必要があります。

```bash
$ pm2 save
```

ちなみに、プロセスリストは下記コマンドで確認できます。

```bash
$ pm2 list
┌────┬───────────┬─────────┬─────────┬──────────┬────────┬──────┬──────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name      │ version │ mode    │ pid      │ uptime │ ↺    │ status   │ cpu      │ mem      │ user     │ watching │
├────┼───────────┼─────────┼─────────┼──────────┼────────┼──────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ 0  │ server    │ 1.0.0   │ fork    │ 2476     │ 1h     │ 1    │ online   │ 0.3%     │ 192.8mb  │ foobar   │ disabled │
└────┴───────────┴─────────┴─────────┴──────────┴────────┴──────┴──────────┴──────────┴──────────┴──────────┴──────────┘
```



以上です。

EC2インスタンスや仮想環境を再起動したら、自動的にスクリプトが実行されているはずです。

## .tsファイルって実行できる？

TypeScriptでアプリケーションを作成していたので、下記コマンドを試してみたところ、エラーを吐きました。

```bash
$ pm2 start app.ts # ts-nodeが入っていないとエラー
```

どうやら、トランスパイル後のjsファイルを実行するか、別途ts-nodeのインストールが必要なようです。

```bash
$ pm2 install typescript ts-node
$ pm2 start app.ts # OK
```

PM2とts-nodeの細々としたことについては、この[Issue](https://github.com/Unitech/pm2/issues/3503)が参考になりそう。

## さいごに

今回はアプリケーションの自動起動のためにPM2を利用してみました。

systemdを利用する方法([具体例]([https://qiita.com/riku-shiru/items/a870edd9dc0b132e092c#%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E7%AB%8B%E3%81%A1%E4%B8%8A%E3%81%92%E6%99%82%E3%81%AB%E8%87%AA%E5%8B%95%E7%9A%84%E3%81%ABrails%E3%81%AE%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%8C%E7%AB%8B%E3%81%A1%E4%B8%8A%E3%81%8C%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B](https://qiita.com/riku-shiru/items/a870edd9dc0b132e092c#インスタンス立ち上げ時に自動的にrailsのサーバーが立ち上がるようにする)))など他にもやり方はあります。[forever](https://github.com/foreversd/forever)もよく紹介されていましたしね。
例：[Expressアプリケーション用のプロセス・マネージャー](https://expressjs.com/ja/advanced/pm.html)



PM2はアプリケーションを管理する機能が豊富で、もっといろいろなことができるようです。例えばログを見たり、アプリをモニタリングしたり。
私もいろいろ触ってみようと思います。

公式: [PM2](https://pm2.keymetrics.io/)