0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

オートロックをDockerに移植してみた

Posted at

はじめに

自宅の玄関に手動でも回せるオートロックを取り付けたいと考え、3Dプリンターとラズパイを駆使し実現できたのですが、機能を増やしたところ、複雑になってしまったためDockerを使って機能ごとにコンテナ化してみました。
オートロックを作成した記事は以下です。

DockerfileやDocker Composeを活用しているので、Dockerを使用する具体例としても見てもらえるといいと思います。

githubにdocker compose用のファイルをまとめているので、詳細はこちらを参照してください。

オートロックの概要

  • オートロックはラズパイからサーボモーターを制御して実現する
  • 解錠や施錠の操作はLINEから行うため、内部ではLINEからWebhookが送信されたら、必要な情報を抜き出し、JSON形式でメインプログラムに渡す。
  • メインプログラムは受け取った情報を見て、ユーザー等をDBに問い合わせる。
  • 内部の情報のやり取りの通信プロトコルはMQTTを使用する。
  • 詳細な設定等をWebアプリで設定できるようにしている。

システム構成

スクリーンショット 2025-08-09 10 10 54

docker-compose.yaml全文

version: "3"

services:
  #--------------- 1. Autolockメインコンテナ---------------
  autolock: # サービスの名前
    container_name: autolock_main
    build:
      context: autolock_main # autolock_mainディレクトリをビルドコンテキストとする
      dockerfile: Dockerfile # ビルドコンテキスト内のDockerfileからイメージを作成する
    image: autolock_main_img #イメージ名をautolock_main_imgとする
    privileged: true # 特権モードを有効にする
    volumes:
      - autolock_setting_volume:/home/pi/autolock/gear_version/etc
    networks:
      - autolock_net #autolock_netブリッジネットワークに所属する
    restart: always #dockerの起動時にコンテナを自動起動する
    
  #--------------- 2. MQTT Brokerコンテナ---------------
  mqtt_broker:
    container_name: autolock_mqtt_broker
    build:
      context: mqtt_broker
      dockerfile: Dockerfile
    image: autolock_mqtt_broker_img
    ports:
      - "1883:1883" #mqtt
    networks:
      - autolock_net
    restart: always

  #--------------- 3. 認証DBコンテナ---------------
  auth_db:
    container_name: autolock_auth_db
    image: mariadb:latest
    environment: #.envファイルから呼び出す
      MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
      MARIADB_DATABASE: ${MARIADB_DATABASE}
      MARIADB_USER: ${MARIADB_USER}
      MARIADB_PASSWORD: ${MARIADB_PASSWORD}
    volumes:
      - auth_db_volume:/var/lib/mysql
      - ./auth_db:/docker-entrypoint-initdb.d
    networks:
      - autolock_net
    restart: always
  #--------------- 4. Node.Js+Express(設定用webアプリ配信)コンテナ ---------------
  setting_webapp:
    container_name: autolock_setting_webapp
    build:
      context: setting_webapp
      dockerfile: Dockerfile
    image: autolock_webapp_img
    environment: #.envファイルから呼び出す
      MARIADB_DATABASE: ${MARIADB_DATABASE}
      MARIADB_USER: ${MARIADB_USER}
      MARIADB_PASSWORD: ${MARIADB_PASSWORD}
      BASE_URL: ${BASE_URL}
    ports:
      - "8080:3000"
    networks:
      - autolock_net
    restart: always
  #--------------- 5. Node.Js+Express(webhook処理)コンテナ---------------
  webhook:
    container_name: autolock_webhook
    build:
      context: webhook
      dockerfile: Dockerfile
    image: autolock_webhook
    ports:
      - "3000:3000"
    networks:
      - autolock_net
    restart: always
    
#A.ブリッジネットワークの作成
networks:
  autolock_net:

#B.ボリュームの作成
volumes:
  auth_db_volume:
  autolock_setting_volume:

※コンテナ間で連携するため、コンテナは全て共通のブリッジネットワークに属する

  • docker-compose.yamlのA.ブリッジネットワークの作成の部分でautolock_netというネットワークの作成を行なっている。
  • B.ボリュームの作成でauth_db_volumeautolock_setting_volumeというボリュームの作成を行なっている。

各コンテナの説明

1.Autolockコンテナ

  • オートロックのメイン処理を担当している
  • 設定を保存するため永続化ボリュームを作成する
  • GPIO制御のため、特権モードで起動する
  • pigpioやautolockのプロセスなど、複数プロセスを動作させている

2.MQTT Brokerコンテナ

  • 内部のAPIはMQTTで実装しているため、NginxとAutolockのデータ送受信、ローカルでのMQTT送受信の中継をしている
  • 1883番ポートはホストの1883番ポートにマッピングしている
  • mosquittoというライブラリでサーバーを立ち上げている

3.認証DBコンテナ

  • ユーザー認証を担当している
  • ユーザー情報は永続化ボリュームで保持する
  • データベースは図のような構造になっており、ユーザー名、lineなどのユーザーID、ユーザーの有効期間を保持している。
    スクリーンショット 0007-10-20 22.38.35.png

4.Node.Js+Express(設定用webアプリ配信)コンテナ

  • オートロックの設定を行うwebアプリの配信を担当する
  • Expressでサーバーを起動し、3000番ポートで待ち受けている
  • 3000番ポートはホストの8080番ポートにマッピングしている
  • 重要なアプリのため、ローカルのみの配信としている
    スクリーンショット 0007-10-20 22.34.39.png

5.Node.Js+Express(webhook処理)コンテナ

  • オートロックの操作をLINEやSlack等のアプリで行うためwebhookを受信する部分を担当する
  • 以下の図のような画面(LINE)でボタンを押すと、webhookが送信される
  • Expressでサーバーを起動し、3000番ポートで待ち受けている
  • 3000番ポートはホストの3000番ポートにマッピングしている
スクリーンショット 2025-08-09 10 10 54

envファイル

以下のような内容のファイルを、docker-compose.yamlと同じディレクトリに.envという名前で配置しておけばyamlファイルから${}の中にキーを入れれば値が呼び出せる。

筆者の環境ではenv_templateというファイルを用意しておき、環境によって値を書き換えて名前を.envにするというスクリプトを初期セットアップで走らせている。

  MARIADB_ROOT_PASSWORD=root
  MARIADB_DATABASE=autolock_user
  MARIADB_USER=pi
  MARIADB_PASSWORD=raspberry
  BASE_URL=http://your_domain.com

autolockコンテナのDockerfile

他のコンテナでもDockerfileを書いているが、参考としてメインのコンテナのDockerfileについて紹介する。このイメージは複数プロセスを同時に実行する。GPIOを制御するpigpioのプロセスとautolockのメインプロセスである。

また、複数プロセスを管理する際Linuxではsystemdが使用されるが、コンテナ上でsystemdを動作させるのは非常に重たい上に、セキュリティ上の危険があるため。そのため、軽量でコンテナ内で完結する複数プロセス管理パッケージとしてsupervisorを利用する。

# ベースイメージを指定
FROM takuteh/raspberrypi-os:2023-05-03_bullseye
#これ以降の操作を/home/piで行う
WORKDIR /home/pi

# 非対話モードでの設定
ENV DEBIAN_FRONTEND=noninteractive

# rootを追加
USER root    

# pi(一般ユーザー)を作成し、必要な設定を行う
# パスワードをraspberryにして、sudoersにpiを追加する
RUN echo "pi:raspberry" | chpasswd && \
    echo "pi ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
    
#/home/piディレクトリの権限をpi:piにする
RUN chown -R pi:pi /home/pi

# パッケージの更新と必要な依存関係のインストール
RUN apt update && \
    apt upgrade -y && \
    apt install -y \
    supervisor \
    git \
    g++\
    cmake \
    pigpio \
    mosquitto-clients \
    libmosquitto-dev \
    libcurl4-openssl-dev\
    libmysqlcppconn-dev

#各種設定ファイルとコンテナ起動時のスクリプトをイメージ内に配置
COPY ./supervisor/supervisor.conf /etc/supervisor/supervisord.conf
COPY ./supervisor/conf.d/* /etc/supervisor/conf.d/
COPY ./src/entry.sh /entry.sh

#起動スクリプトに実行権限を付与
RUN chmod +x /entry.sh

# コンテナ起動時にentry.shを実行する
# 複数プロセスを管理するプロセス(supervisor)をフォアグラウンドで実行するスクリプト
ENTRYPOINT ["/entry.sh"]

#これ以降の操作をpiユーザーで実行
USER pi

#autolockのプログラムをgit clone
RUN git clone https://github.com/takuteh/autolock.git &&\
cd autolock

#プログラムをビルドする
RUN cd autolock/gear_version && \
mkdir build && \
cd build && \
cmake .. && \
make

さいごに

筆者の作成したオートロックシステムを具体例として、docker-compose.yamlやDockerfileで実際にどのような場面でどのような設定を使うのか、Dockerfileを書くのはどんなときなのかみたいな、コンテナ技術の嬉しさがどこなのかわからずモヤモヤしていた人の参考になれば良いと思っています。

疑問点やわかりにくいところがあればぜひコメントください!

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?