Slackアプリで作った自作ラズパイゼロ定点カメラをSystemdデーモンで自動起動するやり方
※ 当ページには【広告/PR】を含む場合があります。
2022/03/04

以前の記事で、
ラズパイの最近の機種はCPUのアーキテクチャはARMv8となり、Dockerやk8sも簡単にインストールできるし、安定して動作するようになりました。 このことで常駐プログラムがDockerコンテナで安定して動くので、著者的には普段Dockerコンテナ化して自動起動するサービスも作成しています。
対して、ラズパイゼロWは初期のアーキテクチャであるARMv6ですので、DockerコンテナにNode.jsを入れて常駐プログラムをデバッグしたり動かすのがかなり大変です。 そこで常駐プログラムは昔ながらの
定点カメラである以上は、電源を入れたらSlackサーバーが自動で起動状態になっていることが好ましいことですので、今回はSystemdデーモンとしてSlackアプリを立ち上げるまでの設定を軽く解説します。
はじめに
そもそもラズパイゼロWはマシンスペックも低く、Dockerコンテナの中からではホストOSに接続した周辺機器の権限周りを設定するのも難儀になります。
低スペックなマシーンにわざわざ無理にDockerコンテナ化するとパフォーマンスもかなり落ちるので、ここは昔ながらのSystemdに登録するやり方を採用して、電源投入時にSlackアプリが立ち上がるようにした方が良い選択になります。
なお、ラズパイゼロの正規品はかなり価格が高騰して、通常の4〜5倍の価格で推移しております。
現状で少しでも価格を押さえてラズパイゼロを入手したい方は、サードパーティ製互換商品を検討することもできます。
また、ラズパイゼロWの後継機である
最近ではネットショップなどで比較的入手できるようになっていますが、世界的な情勢不安が続いており半導体部品の供給が十分とは言えないため、まだまだ購入するには高価と感じてしまう状況が続いています。
こちらならSystemdでもDockerコンテナサービスでも常駐プログラム化を検討しても良いかも知れません。
Slackアプリ用のSystemdデーモンを仕込む
では早速電源投入後にSlackアプリが自動起動するようにSystemdサービスを自作していきます。
なお、ネット検索で「Systemd」とすると解説記事は山ほど出てきますので、一体どんなプログラムなのかの詳細は説明しませんが、ザックリと以下のようなものです。
+ Linux系OSの起動直後に走る主要な起動プロセスの一つ
+ Systemd自身のプロセスIDはinitプロセスと呼ばれ、
常に1(PID=1)で実行状態になる
+ 登録しておいた複数のアプリケーションを
子プロセス(ユニットプロセス)として起動することができる
ラッパースクリプトを準備する
まずは起動時に開始したい子プロセスの中身を記述したシェルスクリプト、通称ラッパースクリプトから作成してみましょう。
start-slack-app.sh
#!/bin/bash
export SLACK_BOT_TOKEN=xoxb-xxxxxxx-xxxxxxx-xxxxxxxxxxxxx
export SLACK_APP_TOKEN=xapp-x-xxxxxxxx-xxxxxxxx-xxxxxxxxxxxxxxx
WORK_DIR=[index.jsが存在するフォルダまでの絶対パス]
node $WORK_DIR/index.js
Systemdで走らせるための子プロセス(ユニットプロセス)を作る際のポイントとしては、Systemdがルートユーザーの権限で起動しているプロセスですので、個別のユーザーの使っている
.bashrc
したがって、Slackアプリで認証に使われるクレデンシャルが有効になっていないままnodeコマンドを実行してしまうと、当然Slackアプリは起動しないので、ラッパースクリプトの最初に
SLACK_BOT_TOKEN
SLACK_APP_TOKEN
また、リソースファイルにアクセスする場合、ユーザーからの
$HOME
このためルートユーザーからファイルの位置が分かるように絶対パスで引数に与えます。
serviceファイルの作成と設置
次に
このファイルで、どのようなユニットプロセスを走らせるのかを記述するファイルで、
.service
自作のSystemdサービスを作る場所は決まっていて、
/etc/systemd/sytem/
試しに
/etc/systemd/system
$ ls -la /etc/systemd/system
-rw-r--r-- 1 root root 1552 Jul 20 2021 autologin@.service
drwxr-xr-x 2 root root 4096 May 7 2021 bluetooth.target.wants
lrwxrwxrwx 1 root root 42 May 7 2021 dbus-fi.w1.wpa_supplicant1.service -> /lib/systemd/system/wpa_supplicant.service
lrwxrwxrwx 1 root root 37 May 7 2021 dbus-org.bluez.service -> /lib/systemd/system/bluetooth.service
lrwxrwxrwx 1 root root 40 May 7 2021 dbus-org.freedesktop.Avahi.service -> /lib/systemd/system/avahi-daemon.service
lrwxrwxrwx 1 root root 45 May 7 2021 dbus-org.freedesktop.timesync1.service -> /lib/systemd/system/systemd-timesyncd.service
lrwxrwxrwx 1 root root 34 May 7 2021 dhcpcd5.service -> /lib/systemd/system/dhcpcd.service
drwxr-xr-x 2 root root 4096 May 7 2021 dhcpcd.service.d
drwxr-xr-x 2 root root 4096 May 7 2021 getty.target.wants
drwxr-xr-x 2 root root 4096 May 7 2021 getty@tty1.service.d
drwxr-xr-x 2 root root 4096 May 7 2021 halt.target.wants
drwxr-xr-x 2 root root 4096 Mar 3 02:09 multi-user.target.wants
drwxr-xr-x 2 root root 4096 May 7 2021 network-online.target.wants
drwxr-xr-x 2 root root 4096 May 7 2021 poweroff.target.wants
drwxr-xr-x 2 root root 4096 May 7 2021 rc-local.service.d
drwxr-xr-x 2 root root 4096 May 7 2021 reboot.target.wants
drwxr-xr-x 2 root root 4096 May 7 2021 remote-fs.target.wants
drwxr-xr-x 2 root root 4096 Feb 6 05:23 sockets.target.wants
lrwxrwxrwx 1 root root 31 Jul 20 2021 sshd.service -> /lib/systemd/system/ssh.service
drwxr-xr-x 2 root root 4096 May 7 2021 sysinit.target.wants
lrwxrwxrwx 1 root root 35 May 7 2021 syslog.service -> /lib/systemd/system/rsyslog.service
drwxr-xr-x 2 root root 4096 May 7 2021 timers.target.wants
みたいに既にOSデフォルトで登録されているユニットサービスが沢山あるようです。
ちなみに
[⭕⭕.service.d]
[⭕⭕.service]
このservice.dファイルを使うことで一つのユニットプロセスが使うリソースファイルをまとめて整理できるので、
/etc/systemd/system
他はファイルリンクを使ってserviceファイルごと別の場所に置くことも可能です。
今回はあまり良い方法ではありませんが、大したserviceファイルではありませんので、
/etc/systemd/system
まずは以下のようにserviceファイルを
slack-cam.service
[Unit]
Description=Slack Remoted Camera Service
After=network-online.target local-fs.target
ConditionPathExists=/root
[Service]
Type=simple
User=root
Group=root
Restart=no
ExecStart=[ラッパースクリプトが存在するフォルダまでの絶対パス]/start-slack-app.sh
[Install]
WantedBy=multi-user.target
これを
/etc/systemd/system
$ sudo mv slack-cam.service /etc/systemd/system/
$ sudo chown root:root /etc/systemd/system/slack-cam.service
$ sudo chmod 644 /etc/systemd/system/slack-cam.service
$ ls -la /etc/systemd/system/ | grep slack-cam
-rw-r--r-- 1 root root 482 Mar 3 02:48 slack-cam.service
移動した後は、ルートユーザーに所有権と実行権限の書き換えも済ませます。
起動テスト
まずは追加したサービスの設定ファイルを読み込んでみます。
$ sudo systemctl daemon-reload
でユニットプロセスを手動で走らせてみましょう。
$ sudo systemctl start slack-cam
内部で起動完了するまで少し待ってから、プロセスの状態を確認してみます。
$ systemctl status slack-cam
● slack-cam.service - Slack Remoted Camera Service
Loaded: loaded (/etc/systemd/system/slack-cam.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2022-03-03 03:07:09 GMT; 24h ago
Main PID: 426 (start-slack-app)
Tasks: 12 (limit: 725)
CGroup: /system.slice/slack-cam.service
├─426 /bin/bash /*****************/start-slack-cam.sh
└─430 node /*****************/index.js
Mar 03 03:07:46 raspberrypi start-slack-app.sh[426]: ⚡️ Bolt app is running!
で正常に動作しているようなら、次に常駐プログラムとして登録していきます。
Systemdサービスの有効化
上記までで常駐プログラム化のスタンバイはOKですので、起動時に立ち上がるようにします。
$ sudo systemctl enable slack-cam
として常駐化が有効になります。
後は再起動してバックグラウンドでユニットプロセスが起動状態になれば完了です。
なお常駐化を無効化したい場合には、
$ sudo systemctl disable slack-cam
として登録を解除もできます。
まとめ
今回はラズパイゼロWで特定のプログラム常駐化させたい場合に利用するSystemdの使い方をおさらいしていきました。
電源投入すると監視カメラが立ち上がるように出来るだけでも、グッと市販の監視カメラっぽい動作になると思います。