DockerでMosquitto MQTTをセルフホストする:堅牢なプライベートIoTハブの構築

HomeLab tutorial - IT technology blog
HomeLab tutorial - IT technology blog

「クラウド依存」なスマートホームの不満

インターネットが切断され、仕事が捗らなかった夜のことを今でも覚えています。書斎に入り、照明のスイッチを入れましたが……何も起きませんでした。それは大きな気づきでした。私の「スマート」な照明は、わずか数十センチ先にあるリレーを作動させるために、数千キロも離れたサーバーにアクセスできなければ、ただの箱に過ぎなかったのです。スマートフォンをタップしてから照明が点灯するまでに2秒の遅延を感じたことがあるなら、それはクラウドの遅延という罠に陥っている証拠です。

このラグは、多くの消費者向けデバイスがTuyaやSonoffなどの独自のクラウドブローカーに縛られているために発生します。センサーが増え、デバイスが20台、30台と増えるにつれ、ネットワークは外部への依存関係で乱雑になっていきます。解決策は?

ローカルの MQTT (Message Queuing Telemetry Transport) ブローカーです。MQTTは、自宅のための高速な郵便サービスのようなものだと考えてください。センサー、Home Assistant、Node-REDが、ローカルネットワークを一歩も出ることなく、瞬時にデータをやり取りできるようにする軽量なプロトコールです。

私の経験上、Docker上で専用のMosquittoインスタンスに移行した瞬間が、単なるガジェット収集家からホームラボ(HomeLab)エンジニアへと進化する時です。ISPがダウンしても動作し続ける、モジュール式でポータブルな基盤を提供してくれます。

デプロイ方法の選択

ブローカーをどこに置くかは、長期的な視点での決定になります。私はDockerに落ち着く前に、数週間かけてさまざまな構成をテストしました。一般的な方法の比較は以下の通りです:

方法 メリット デメリット
Home Assistant アドオン ワンクリックで簡単に設定可能。 アップデートでHome Assistantを再起動すると、IoTネットワーク全体が数分間停止する。
ベアメタル (Ubuntu) オーバーヘッドが少ない。 設定ファイルが /etc/ 内に散乱し、バックアップや移行が面倒。
スタンドアロン Docker 完全に分離されており、移植が容易。 ボリュームとネットワークに関する基本的な理解が必要。

なぜMQTTにDockerが最適なのか

  • 独立したライフサイクル: ブローカーからZigbee2MQTTやTasmotaデバイスを切断することなく、オートメーションエンジン(Home Assistant)を再起動できます。
  • シームレスな移行: Raspberry Piでは力不足になった場合でも、より強力なN100ミニPCへの移行は5分もかかりません。フォルダをコピーしてコンテナを実行するだけです。
  • 権限問題の解決: Dockerはファイル権限が扱いにくいことがありますが、特定のユーザーID (UID) を使用することで恒久的に解決できます。

堅牢なセットアップのための設計図

信頼性の高いホームラボを構築するために、Docker Compose経由で Eclipse Mosquitto を使用します。停電が発生しても「照明:オン」といったデバイスの状態を維持するための「永続化」と、ネットワークを安全に保つための「パスワード認証」を有効にします。

ステップバイステップの実装

1. ディレクトリ構造の作成

設定ファイルが整理されていないと後で苦労することを、私は身をもって学びました。バックアップを容易にするために、すべてを ~/docker ディレクトリにまとめます。以下のコマンドを実行して環境を準備しましょう:

mkdir -p ~/docker/mosquitto/config
mkdir -p ~/docker/mosquitto/data
mkdir -p ~/docker/mosquitto/log
touch ~/docker/mosquitto/config/mosquitto.conf
touch ~/docker/mosquitto/config/pwfile

2. ブローカーの設定

お好みのエディタで mosquitto.conf を開きます。データの保存先とセキュリティ設定を定義する必要があります。Mosquitto 2.0以降では、外部トラフィック用のリスナーを明示的に定義しなければなりません。

# ~/docker/mosquitto/config/mosquitto.conf

persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log

# 標準のMQTTポートを開放
listener 1883

# セキュリティ設定は必須
allow_anonymous false
password_file /mosquitto/config/pwfile

ローカルのラボであっても、私は決して allow_anonymous true は使いません。設定を誤ったESP32デバイスが1台あるだけで、ブローカーがゴミデータで溢れかえり、デバッグが地獄に変わる可能性があるからです。

3. Docker Composeファイルの定義

次に、~/docker/mosquitto 内に docker-compose.yml ファイルを作成します。これがコンテナの設計図になります。

version: '3.8'
services:
  mosquitto:
    image: eclipse-mosquitto:latest
    container_name: mosquitto
    restart: unless-stopped
    ports:
      - "1883:1883"
      - "9001:9001"
    volumes:
      - ./config:/mosquitto/config
      - ./data:/mosquitto/data
      - ./log:/mosquitto/log
    user: "1883:1883" # 内部のMosquittoユーザーIDに合わせる

プロのアドバイス: user1883:1883 に設定することが、「Permission Denied(権限拒否)」エラーを避ける秘訣です。これにより、コンテナがホストマシンにログやデータベースを確実に書き込めるようになります。

4. パスワードで保護する

脆弱なパスワードは避けてください。MosquittoはDockerで動作しているため、一時的なコンテナを使用して認証情報を安全にハッシュ化できます:

docker run --rm -it -v ~/docker/mosquitto/config:/mosquitto/config eclipse-mosquitto mosquitto_passwd -c /mosquitto/config/pwfile my_iot_user

強力なパスワードを選んでください。この認証情報は、自宅のあらゆるスマートデバイスのマスターキーとなります。

5. サービスの起動

次のコマンド1つで起動します:

cd ~/docker/mosquitto && docker-compose up -d

新しいハブのテスト

デバイスを追加し始める前に、接続を確認しましょう。MQTT Explorer を強くお勧めします。50以上のセンサーが一斉にレポートしているような状況でも、データをツリー状に視覚化してくれるので不可欠なツールです。

  1. サーバーのIPアドレスとポート 1883 に接続します。
  2. 先ほど作成した認証情報を入力します。
  3. メッセージが流れてくるのを確認します。

ターミナル派の方は、コンテナから直接トラフィックを監視することもできます:

docker exec -it mosquitto mosquitto_sub -u "my_iot_user" -P "your_password" -t "#" -v

最終的な統合

これでブローカーは自宅の心臓部になりました。サービスとの連携は簡単です:

  • Home Assistant: 「設定 > デバイス > MQTT」に移動します。IPアドレスと認証情報を入力してください。
  • Node-RED: “mqtt in” ノードを使用します。サーバーを指定すれば、複雑なオートメーションを構築する準備は完了です。

MQTTブローカーを独自のDockerコンテナに移行することで、プロフェッショナルグレードのアーキテクチャを構築できました。オートメーションは高速化し、データはプライベートに保たれ、インターネットが繋がらなくてもスマートホームがついに正常に動作するようになります。

Share: