サーバーがダウンを防ぐためDocker + Node.jsのアプリにPM2を導入してみました。
エラーが起きるとサーバーが落ちる
Node.jsでAPIを開発しているのですが、エラーが発生するとサーバーがダウンしてしまいます。一度サーバーがダウンしてしまうと、次リクエストから応答しなくなります。
try/catchでエラーハンドリングしていても、予期せぬところでエラーが発生する可能性があるため、さすがに運用していく上ではサーバーが落ちないようにしたいです。
なんとかサーバーが落ちないようにできないものかと調べてみると、PM2が良さそうな感じでした。
PM2とは
PM2はNode.jsアプリケーションのプロセス管理を行うためのオープンソースです。PM2を使うことで、Node.jsアプリケーションの起動やログ管理、モニタリングができます。
プロセスの状態を常に監視しているため、プロセスが停止した場合などに自動で再起動させる機能を持っています。
PM2を導入する
PM2を導入してみます。まずpackage.jsonにpm2を追加します。
・package.json
1 2 3 4 5 6 7 8 9 10 | … "dependencies": { ... "pm2": "latest" }, … |
次にPM2の設定ファイルを作成します。scriptの箇所などは適宜読み替える必要があります。watchをtrueにすることでコードが変更があった場合に自動で再起動してくれます。
・pm2.config.json
1 2 3 4 5 6 7 8 9 10 11 | } "name": "sample-app", "script" : "ts-node src/driver/server.ts", "watch": true, "env" : { "NODE_ENV" : "development" }, "env_production" : { "NODE_ENV" : "production" } } |
Dockerfileを修正する
Dockerfileを修正し、先ほど作成したpm2.config.jsonを読み込ませてpm2を使えるようにします。
–no-daemonオプションを指定することで、PM2を実行し続けることができます。
・Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 | FROM node:16 WORKDIR /usr/src/app COPY package*.json ./ RUN npm install RUN npm install -g ts-node COPY . . EXPOSE 5000 CMD node_modules/pm2/bin/pm2 --no-daemon start pm2.config.json |
PM2で実際に動かしてみる
Dockerを再度ビルドして動かしみます。
無事動きました。
挙動の違いを確認する
nodemonの場合
従来のnodemonの場合は、以下のようにエラーが発生した場合「app crashed」になりコードの変更が検知されるまでは再起動されませんでした。
そのため、以降のリクエストはNo Responseとなってしまいます。
PM2の場合
今回導入したPM2の場合は、以下のようにエラーが発生した場合でもすぐにサーバーが再起動しました。
そのため、以降のリクエストも受け付けることができます。