.pm2との付き合い方
これはなに
pm2をEC2環境で動かすにあたって.pm2の扱いに工夫が必要だったので知見をメモしておく。
はじめに
はじめにpm2と.pm2について。
pm2とは
PM2 は、アプリケーションを 24 時間 365 日オンラインで管理および維持するのに役立つデーモン プロセス マネージャーです。
https://pm2.keymetrics.io/
PM2を動かしているホスト(EC2インスタンスとか)が24 時間 365 日動き続けた場合ですよね?
.pm2とは
- pm2を起動(
pm2 start app.js
)した時に生成されるpidやログ等が保管されるフォルダ
本編
置き場所
.pm2の置き場所について。
仕組みと困りごと
- pm2を起動(
pm2 start app.js
)すると.pm2フォルダが作成され、その中にpidやログ等が保管される。 - .pm2は最初にpm2を実行したユーザのホームディレクトリに作成される。
例)/home/ec2-user/.pm2
これだと、例えばjulietユーザがログインしてpm2 status
を実行しても同じサーバで動いているnodejsアプリは表示されない。
解決策
.pm2フォルダはPM2_HOME環境変数の中に作成される。
/etc/environment にPM2_HOMEを定義する。
ここにexport PM2_HOME=/opt/app/.pm2
と記載しておけば、どのユーザでログインしても共通の.pm2
を参照するためpm2 statusで状況を確認することができる。
同じ機能を提供する/etc/profileもあるが、これはBashなどのシェルを起動した時だけ読み込まれるため、コマンド実行アカウントにより読み込まれない可能性がある。
pm2 startup
仕組みと困りごと
pm2 startup の --hp <home-path>
について。
pm2 startup
は --hp
に何も指定しないと$HOME
の値を参照する。
例えばこれを起動スクリプト等でrootユーザで実行すると、systemdから起動してくる時の.pm2は/root/.pm2
となる。
この値は当初定めた/opt/app/.pm2
と異なるため、systemctl restart
を実行すると、.pm2を参照することができず起動しない。
解決策
よって、pm2 startup
を起動する時は下記例の通り.pm2を削除したパスを指定する必要がある。
HOME=$(dirname $PM2_HOME)
pm2 startup <distribution> -u <user> --hp $HOME
アクセス権
仕組みと困りごと
.pm2はpm2を起動(pm2 start app.js
)したユーザのアクセス権で作成される。
そのため、「置き場所」の解決策で複数ユーザがpm2コマンドを実行できるようにした場合でもpm2 status
でステータスを見ることはできるけど、pm2 restart all
等のプロセスを操作するコマンドが権限不足で実行できない。
解決策
pm2を起動(pm2 start app.js
)を実行した後、chown -R user:wheel $PM2_HOME
しておく。
例えば、EC2(実際はAuto Scalingで構成する)にpm2を構成する場合は以下の通り。
systemdをセットアップする起動テンプレート(Launch Template)のシェルは以下の通り作成する。
function setupPM2(){
echo setupPM2
# PM2_HOME環境変数を読み込んで設定する
source /etc/environment
# systemd設定を行う
# このコマンドでpm2-ec2-user.serviceというサービスが作成&有効化される
pm2 startup systemd -u ec2-user --hp /opt/app
# アプリフォルダに移動
cd /opt/app
# pm2 startを実行してアプリを起動する
pm2 start ecosystem.config.js --env $NODE_ENV
# 上記で作成したpm2-ec2-user.serviceは.pm2フォルダの内容を参照して起動する
# pm2 startした結果を保存する
pm2 save
# 起動テンプレートはrootユーザで実行されるため、所有者をec2-user:wheelに変更する
chown -R ec2-user:wheel /opt/app
}
Discussion