たねやつの木

Photographs, Keyboards and Programming

【Node.js】foreverコマンドの基本的な使い方まとめ

079A9455.jpg

(過去に書いた記事を大きく修正してまとめなおしたものです。)

できること

node hoge.jsをバックグラウンドで実行、異常終了時に自動で再起動できるようになります。

Raspberry Piの起動時に実行されるスクリプトの中に追加すると起動と同時に実行されるようになります。

Foreverの導入

nodeプロジェクト外使用するコマンドなのでグローバルオプションを指定してインストールします。

$ sudo npm install -g forever

導入自体は以上で完了です。root権限で実行しないとアクセス拒否でエラーとなりインストールが完了しません。

実行する

nodeコマンドの代わりにforever startを使用します。今回の例ではExpressで作成したAPIサーバーを使用します。こちらのページで同様のモノを作成していますので参考にしていただければ幸いです。

$ cd myproj
$ forever start ./bin/www

各コマンド

実行しているスクリプトの一覧を確認

forever listで実行中のスクリプトを確認することができます。このコマンドを実行しているユーザで起動しているスクリプトのみ確認できます。

$ forever list
info:    Forever processes running
data:        uid  command   script forever pid  id logfile                      uptime
data:    [0] v0P9 npm start        3897    3903    /home/user/.forever/v0P9.log 2:0:4:1.657

実行時のコマンドやログが保存されている場所・起動からどれだけ時間が経過しているかなどを確認することができます。uidの前にある追番は次項の停止用コマンドにて使用することができます。

スクリプトの停止

forever listで確認したスクリプトの追番やuidを使用してforever stop [キーとなる値]で停止させることができます。よく間違えるのですがforever killではないので注意です。

$ forever stop 0
info:    Forever stopped process:
    uid  command   script forever pid  id logfile                      uptime
[0] v0P9 npm start        3897    3903    /home/user/.forever/v0P9.log 2:0:11:50.16

$ forever stop v0P9 でも可能

ユーザーのすべてのスクリプトを停止させるときにはforever stopallを使用することが可能です。一つしかスクリプトを実行していないときならばこのコマンドで停止させるのが楽です。

別ユーザーの実行しているスクリプトを確認・停止したいときにはsudo -u [実行しているユーザー] forever ...を使用します。

npm startを実行する

forever start hoge.jsで実行されるコマンドはnode hoge.jsと同義です。が、Expressなどを使用しているとすでに用意されている起動コマンド(プロジェクトルートにてnpm start)を使用した糸気があると思います。

forever start -c "[起動コマンド]" [プロジェクトルートのpath]を使用することで起動コマンドを指定することができます。

$ pwd 
/home/user/express-proj
$ forever start -c "npm start" ./

最後に指定している[プロジェクトルートのpath]ですが絶対パスで指定すると何故かうまく起動してくれません。。同様の現象はほかの方も一部報告されているようですが解決方法は見つかりませんでしたm(__)m

ですので実行する際にはプロジェクトルートまでcdするか現在のディレクトリからの相対パスを指定してあげてください。

一応以下の--workingDir [プロジェクトルートへのpath]オプションを指定することでスクリプトを実行するディレクトリを指定することができ、絶対パスっぽく指定することはできます。

$ forever start --workingDir /home/user/express-proj -c "npm start" ./ 

最後の./は何でもいいのですがここで指定しているディレクトリにログファイルが吐かれます。とりあえずこれで動いているからいいかな程度です。

環境変数を指定する

プロパティ名=値 forever start hoge.jsと実行することでnodeコマンドで実行するときと同じように環境変数を設定することができます。-cオプションなどと組み合わせて使うことができるのですがいずれの場合でもforeverの前に環境変数を指定してあげる必要があります。

$ PORT=9999 forever start -c "npm start" ./
$ forever start -c "PORT=9999 npm start" ./ ←起動しない

(Expressの場合)二つ目のコマンドで実行するとエラーとなり起動できません。foreverコマンド自体は成功しているように見えるので注意が必要です。

マシン起動時に自動で実行するようにする

forever自体とは関係はないのですが、マシンの起動時にスクリプトを実行させるようにする方法です。今回は上記のExpressで構築したサーバーをRaspberry Pi上で動かすような感じで運用していきます。

/etc/rc.localというファイルに書き込んだことが起動時にrootユーザー実行されます。

rc.localの中身はRaspberry Piだと以下のようになっています。

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

exit 0

割り当てられたIPアドレスを表示する処理が書いてあります。HDMIでモニターに接続して起動したときに、ズラズラっと表示される中の最後のほうにこの処理によって出力される文字列があるはずです。

この処理とexit 0の間に今回のforeverでの起動処理を追加します。

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

# Start Express API server 
sudo -u user /usr/bin/forever start --workingDir /home/user/express-proj/ -c "npm start"  ./

exit 0

上のほうでも書きましたが管理者権限でこの処理は実行されるためユーザーを変えるためにはsudo -u [ユーザー名]を使用します。Raspberry Piを再起動させて、問題なくサーバーが起動していることが確認出来たら完了です!