BunアプリをPM2で動かしてデーモン化する

#### 追記: 2023/12/16 Bunでpm2をインストールして動かす方法について記事のへ追記しました
この記事で「pm2をインストール」する方法をpm2本家にふってしまっていたので「Bunでpm2をインストールして動かす」方法を追記しました。

やはり、bun install は速くて気持ちが良いっす。

ーー

実行しているプログラムを、ユーザーがログアウトしたり、シェルセッションを閉じてもプロセスを続行したいとか、アプリケーションがクラッシュしても自動的に再起動したいなどという需要は結構あります。

そんな場合に Node.js で良く使われるのは、デーモン・プロセス・マネージャーPM2 です。

https://pm2.keymetrics.io/

https://github.com/Unitech/pm2

PM2は、複数のプロセスを一覧管理し、その log や error log などをリアルタイムに監視もできるなどの豊富な機能を持つ優れたツールです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7103/ece2393d-4a13-5629-cdcf-f8cb31a4f1a1.png)

# PM2 に Bun アプリを登録する

さて、今回はその PM2 に Bun アプリを登録しようという企画になります。

例えば先日書いた「[BunでWebSocketのデータ配信サーバーを建ててccchartにリアルタイム表示する](https://qiita.com/toshirot/items/3af83303f95ac7baa546)」という記事の WebSocket サーバーは、サーバーが止まると当然チャート表示も止まってしまいます。つまり、常時動いて配信を続けていて欲しいサーバーです。

https://qiita.com/toshirot/items/3af83303f95ac7baa546

動作サンプルURL
https://ccchart.com/bun/ws-8116.html
動画
<img width=400 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7103/add886c8-0e27-05e3-8b13-ccb709d209a1.gif>

まぁ、この WebSocketサーバーに限らず、 Webサーバーでもチャットサーバーでも普通のアプリでもそういうものはたくさんありますよね。

ここでは PM2 のインストールなどのドキュメントは、[PM2の本家　(https://pm2.keymetrics.io/docs/usage/quick-start/)　](https://pm2.keymetrics.io/docs/usage/quick-start/) を参照していただくとして、どう登録したら良いのかについて書いていきます。

# PM2 で Bun サーバーをどう動かすか

PM2 はアプリをこんなふうに登録します。

```sh:PM2へapp.jsを登録する
$ pm2 start app.js
```
<b>※注意 2023/12/16 : </b>記事下の追記を参照してください。「npm install pm2 -g」ではなく「bun install pm2 -g」などでインストールする場合は「pm2 start app.js」ではなく「bun pm2 start app.js」といった構文になります。

これで app.js が PM2へ登録できてデーモン化し、クラッシュしても自動的に再起動され、様々なPM2の機能が使えるようになります。

そして、Node.js 以外の他の言語でも以下のような感じで登録できます。
```sh:PM2へapp.pyなどを登録する
$ pm2 start app.py # python
$ pm2 start app.sh # シェルスクリプト
```
でも注意してみてください。

これって 拡張子 .js、.py、.sh などで登録されています。拡張子と言語の関連付けがなされていれば特に問題は無いのですが、

「.js」や「.ts」などの場合はどうでしょうか？

現在のサーバー側は、一般的には Node.js がインストールされているケースが多いでしょう。そうすると、「pm2 start app.js」と書いた時には、 Node.js アプリだと判断される可能性が高くなります。

つまり、それでは Bun アプリの明示的な登録ができないのです。

でもまぁ、いろいろな登録方法がありますが、ここでは2つの方法を書いておきます。

# Bun パスからの起動を登録する

PM2は、「pm2 start "コマンド"」と書いて登録することができるので、次のように Bun へのパス＋アプリパス を書くことで app.js を Bun アプリとして起動することができます。

```sh:PM2へBunのパスからのapp.js起動を登録する
$ pm2 start "~/.bun/bin/bun app.js"
```

# シェルコマンドに記述してから登録する

上でシェルスクリプトの起動例「pm2 start app.sh」を書いたので既にお分かりかと思いますが、シェルスクリプトへ Bun による app.js の起動を書いてから PM2 へその .sh を登録する手もあります。

たとえば、こんな感じですね。

```sh:app.sh シェルスクリプトでBunのパスからのapp.js起動を登録する
#!/usr/bin/sh
~/.bun/bin/bun ./app.js
```
この app.sh をPM2へ登録します。

```sh:app.sh をPM2へ登録する
$ pm2 start app.sh # Bun アプリを起動するシェルスクリプト
```

これで、BunもめでたくPM2で管理できるようになります。

# 追記: Bunでpm2をインストールして動かす

上の記事では、pm2のインストールを本家にふって話を勧めたので、npm i pm2 なインストールを前提にしています。

でも bunでも入れられるはずやろ。ということでやってみました。

```sh: Bunでpm2を入れる
bun i pm2 -g
```
これで、インストールできるのですが、このまま「pm2 -v」や「pm2 start app.js」のような記述では動きませんでした。
```sh: Bunでpm2を動かす
$ pm2 -v

Command 'pm2' not found, did you mean:　
```
見つからないと言われます。
そこで、bun を頭に書いてこうしてみると
```sh: Bunでpm2を動かす
$ bun pm2 -v
5.3.0
```
動きました。
したがって、「pm2 start app.js」ではなく、一応上記の通り、このように書けば、
```
$ bun pm2 start "~/.bun/bin/bun app.js"
```
登録できました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7103/d33a6e8e-a487-978a-5de0-a3bfda816047.png)

というわけで、この場合、上の記事で書いた「pm2 start app.js」といった記述は「bun pm2 start "~/.bun/bin/bun app.js"」等と読み替えてください。

しまりがなくてすみません。

でも、もちろん、pm2インストール速度は超速いす。
```
$ bun i pm2 -g
bun add v1.0.18 (36c316a2)

 installed pm2@5.3.0 with binaries:
  - pm2
  - pm2-dev
  - pm2-docker
  - pm2-runtime

[13.00ms] done
```


# 最近 Qiita に書いた Bun 関連の記事10選

https://qiita.com/advent-calendar/2023/bunjs

https://qiita.com/toshirot/items/f6bd561bc2522f1d26e0

https://qiita.com/toshirot/items/a5dc53ef191d20bbeb42

https://qiita.com/toshirot/items/74476af27e67d8534c5a

https://qiita.com/toshirot/items/94961b6dde72be80ab0c

https://qiita.com/toshirot/items/7a0555b46b3a64a4f643

https://qiita.com/toshirot/items/c4d090bc38f9b85d8cdd

https://qiita.com/toshirot/items/4e8e571dd50a45c651f0

https://qiita.com/toshirot/items/e4eb635596ae4f63bdfd

https://qiita.com/toshirot/items/a81f2073e373b0351493

https://qiita.com/toshirot/items/06a992af8cf8aca9ff95