はじめてのDocker + nginx + lirc
家庭内IoTシステムで、ラズパイが担当している機能は以下の通り。
- 室内温度を定期的に計測し一定温度を閾値としてクーラーをON/OFFする(夏季限定)
- CPU温度が閾値を上下したときCPU FanをON/OFFする
- 室内温度・湿度・気圧、CPU温度を計測しDBに登録する
- リクエストに応じてIR機器(エアコン、照明)をON/OFFする
- リクエストに応じて室内温度・湿度・気圧、CPU温度を表示する
- リクエストに応じて上記機能の設定をDBに登録する
- DBはMySQL、WebサーバはApache、常駐プログラムおよびAPIはPython
ラズパイは2016年に導入したとき noobs を使用してそのままアップデートを重ねてきた。IR機器のコントロールには lirc を用いている。
2年ほど前、rpi-update で kernelバージョンが4.9になったとき、lircが動かなくなるという事態に遭遇した。対処法を見ても解決せず、kernel バージョンを上げない選択を取り続けてきた。折を見て幾度か試行したが何をやってもダメ。当時は kernel 4.9 にするとダメという認識でいたが、jessie から stretch にアップデートするとダメというカンジ?
kernelバージョンアップは必須ではないと考えているが、いずれ対応を迫られることもあろう。ということで、ちょっと気合を入れて調査しようと思い立ち、余ってたラズパイに 2019-04-08-raspbian-stretch-full.zip を適用してみた。特にどうということもなく lirc が動作する。同じ方法を rpi-update した noobs に試してみたがうまくいかない。どうも noobs から rpi-update でバージョンアップする場合と、最初から raspbian stretch をインストールした場合とではなんか違うらしい。Windows系アップデートあるあるだが、linux も免れ得ないものであったか。
lirc という観点における移行の目途はたったが、いろいろ遊んでるサーバでもあるので、容易にはリプレイスできない。最低限、冒頭に述べた機能が満たされる必要がある。単なる移行ではつまらないので、Dockerとnginxを試してみることにした。Pythonで書いていたところは、特に必要はないが node.js でリプレイスしてみることにする。
言葉にするとわずかだが、なにも知らないところから始めると切り分けが割と大変で、Dockerを使用する意味にまで戻って幾度も検討しなおすことになった。一つのコンテナにアレコレ詰め込むような実装なら、コピペ移行と大差ない。
最終的に、docker-compose の内容は、mysql、nginx、API、常駐アプリをそれぞれ個別のコンテナとして、必要な設定ファイルをコピー、あるいは自作プログラムをマウントして実行するという構成にした。
切り分けがうまくいっても、コンテナ同士の連携とかで頭を悩ましてはdocker を使用する意義へと立ち返るということを繰り返し、ようやく同等の機能を実現した。同等の機能といっても、BME280センサからの情報取得やMySQLとのやりとりなど、node.js では非同期処理で書かないといけないっぽいところがあり、ソースコードが見やすくなったと思いもするが、非同期処理をする必要がないので Python の方が書きやすいのではないかと思いもする。
一番ハマったのはコンテナ側で実行した irsend をホスト側に到達させること。コンテナ側で irsend を実行しても以下のようなエラーが表示されるばかりで困り果てていた。
hardware does not support sending Error running command: Input/output error
ホスト側のlircdが起動していてはいけないというのが正解。
docker-compose.yml の設定は以下の通り。
privileged: true devices: - "/dev/gpiomem:/dev/gpiomem" - "/dev/lirc0:/dev/lirc0:rwm"
参考までに、docker-compose のインストール方法。ネット上にいろんな方法が散見されたが、これしかうまくいかなかった。
sudo pip install -I docker-compose
俺環。
$ uname -a Linux raspberrypi02 4.19.34-v7+ #1211 SMP Mon Apr 8 22:56:37 BST 2019 armv7l GNU/Linux $ lsb_release -a No LSB modules are available. Distributor ID: Raspbian Description: Raspbian GNU/Linux 9.8 (stretch) Release: 9.8 Codename: stretch
Dockerのいいところは体感できたが、DBのコンテナはどう扱うんじゃろと思いもする。例えば開発環境としてこれ使ってねと docker-compose.yml を渡されたとして、データは別途移行ということでいいのだろうか。
おまけ。
ラズパイのlircdを止めるのに一苦労。最後のやつでやっと自動起動しなくなった。
sudo systemctl disable lircd sudo systemctl disable lircd-setup.service sudo systemctl disable lircd-uinput.service sudo systemctl disable lircd.service sudo systemctl disable lircd.socket sudo systemctl disable lircd.socket lircd.service sudo systemctl disable lircmd.service