LoginSignup
22
26

More than 5 years have passed since last update.

【Node.js】 RaspberryPiのプログラムを自動起動・永続化・SSH ログアウト後もプロセスを残す

Last updated at Posted at 2018-06-26

前回記事→ LINE BOTでラズパイから部屋の温度を教えてもらう【Push API】【Node.js】

現状と課題

  • ラズパイにはMacからwifiでSSH接続している
  • SSH接続が切れる・Macがスリープするとプログラムも止まってしまう
    • Botが使えなくなる

要件

  • Nodeのプログラムを自動起動&永続化させる
  • RaspberryPiをサーバーに常時接続させる(ngrokの永続化)

ngrok(トンネリングツール)については→ ngrokでトンネリング

作業概要

  1. Foreverをインストールし、プログラムを自動起動&永続化
  2. 無線LANの省電力機能をオフ
  3. ngrokがタイムアウトしないようにする
  4. ngrokの永続化(screen コマンドの利用)

1. Foreverをインストールし、プログラムを自動起動&永続化

Raspberry Piにはプログラムを自動起動する方法がたくさんある

  • /etc/rc.local
  • autostart
  • crontab
  • /etc/init.d
  • systemd

など・・
参照記事 Raspberry Piでプログラムを自動起動する5種類の方法を比較・解説

今回はNodeのプログラムなので、foreverを利用します。
foreverとは、nodeをデーモンとして動かすためのモジュール。バックグラウンドでnodeを動作させるためにインストールします。

デーモン (英語: Daemon) は、UNIX, Linux, MacOSXなどUnix系ののマルチタスクオペレーティングシステム (OS) において動作するプロセス(プログラム)で、主にバックグラウンドで動作するプロセス。- Wikipedia

foreverのインストール
グローバルオプションをつけてインストールします。

$ sudo npm install -g forever

foreverのパスを確認

$ which forever

(例)もちさんの場合

/usr/local/nvm/versions/node/v10.0.0/bin/forever

/etc/rc.localを編集
rc.localはRaspberry Pi起動時に管理者権限で実行されるファイルです

$ sudo nano /etc/rc.local

下記のようなファイルです

rc.local
#!/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

ファイル末尾「exit 0」の手前に起動時に実行したいプログラムを指定する

$ sudo -u [ユーザ名] [nodeのパス] [forever のパス] start -a -d [動かしたいスクリプトのパス]

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

sudo -u username /usr/local/nvm/versions/node/v10.0.0/bin/node /usr/local/nvm/versions/node/v10.0.0/bin/forever start -a -d /home/username/workspace/mylinebot/server.js

exit 0

正しく実行されるか確認

$ sudo /etc/rc.local

info:Forever processing file: 動かしたいスクリプトのパスと出たら成功!

$ sudo /etc/rc.local
My IP address is 192.000.0.0 000.00.00.00 
warn:    --minUptime not set. Defaulting to: 1000ms
warn:    --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
info:    Forever processing file: /home/username/workspace/mylinebot/server.js

Raspberry Piを再起動する

$ sudo reboot

再度ラズパイに接続し、サービスが起動しているか確認しましょう

Foreverのプロセスを確認するコマンド

$ forever list

失敗だと

$ forever list
info:    No forever processes running

成功

$ forever list
info:    Forever processes running
data:        uid  command                                       script                                     forever pid id logfile                        uptime       
data:    [0] f70E /usr/local/nvm/versions/node/v10.0.0/bin/node /home/username/workspace/mylinebot/server.js 770     941    /home/username/.forever/f70E.log 0:0:0:46.495 

参照記事 ラズパイ再起動時にNode.jsアプリを自動起動する

2. 無線LANの省電力機能をオフ

/etc/rc.localに以下を追記する

iwconfig wlan0 power off

無線LANの省電力機能の状態確認。 Power save: offと表示されたらOK

$ iw dev wlan0 get power_save
Power save: off

Raspberry Piを再起動、再接続し、状態確認しましょう

3. ngrokがタイムアウトしないようにする

ngrokは一定の時間が立つと、接続を解除してしまいます。
ngrokで無料のアカウントを作成し設定ファイルを作成すれば、時間がたってもトンネルが解除されなくなります。

ngrokでアカウントを作成 https://ngrok.com/

作成したアカウントでngrokのwebページへログインするとConnect your accoutというところにauthtokenが表示されます。
authtoken.png

設定ファイルの作成。以下のコマンドを実行します。
[ngrokのパス] authtoken [自分のアカウント用Authtoken]

$ ngrok authtoken XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

設定ファイルが、~/.ngrok2/ngrok.yml に作成されます。これでタイムアウトはなくなります!

$ ngrok authtoken XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Authtoken saved to configuration file: /root/.ngrok2/ngrok.yml

4. ngrokの永続化(screen コマンドの利用)

ngrok(トンネリングサーバー)を常時起動させてラズパイをグローバルに接続しっぱなしにしましょう

Linux では仮想端末を作成するscreenというコマンドがあります。
「SSH をログアウトしても仮想端末を残す」ことで、仮想端末上にプロセスを残すことができます。

参照記事 Raspberry pi で SSH ログアウト後もプロセスを残したい

インストール

$ sudo apt-get install screen

プロセスを残す

screen を起動

$ screen

ngrokを起動

$ ngrok http 3000(任意のポート)

ngrokのURLを確認。
Ctrl + A、Ctrl + Dで仮想端末からデタッチ(抜け出す)。デタッチ後もプロセスは残り続けます。
デタッチできたら以下のようなメッセージが出ます

[detached from 17974.pts-0.raspberrypi]

仮想端末の確認

$ screen -list

数字(この場合17974)がプロセス番号です

$ screen -list
There is a screen on:
    17974.pts-0.raspberrypimochi    (2018年06月22日 11時26分49秒) (Detached)
1 Socket in /var/run/screen/S-user.

仮想端末にアタッチ(再接続)したい時は

$ screen -r [プロセス番号]

# もし、セッションが1つだけの時は
$ screen -r

参照 screenコマンドの要点

完了です!
前回記事・LINE BOTで利用する場合は、このngrokのURLをLINE DevelopersのWebHookURLに登録すれば、常時BOTが使用できるようになります。

課題

  • サーバーを起動しなおしたり、RaspberryPiの再起動が発生したとき、ngrokのURLが変わってしまう
    • 有料アカウントにすれば固定ドメインが利用可能
    • とりあえず今は保留

参照記事
google-home-notifier周りをほぼ自動化した
10分でSlackからGoogleHomeを喋らせるめちゃ速レシピ

22
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
26