HomeKit Love

Apple HomeKit を布教すべく立ち上げた本サイトは、HomeKitに関するニュースや製品のレビューをお伝えしていきます。

Mac で Homebridge を Docker 上に構築してみる

HomeKit Lovers の皆様こんにちは。 実は Homebridge の利用は初めてなのですが、かなり流行っているようですし、情報も豊富にありそうなので遅ればせながら挑戦してみました。

しかし、思い立ったはいいが手元に Raspberry pi などのARMデバイスがありません。 しかし、挑戦したい。

そこでWEB上の情報を調査したところ、Docker上でHomebridgeを運用するプロジェクトが存在しました [sanko href="https://github.com/oznu/docker-homebridge" title="Homebridge Docker. HomeKit support for the impatient using Docker on x86_64, Raspberry Pi (armhf) and ARM64." site="GitHub" target="_blank"]

どうやらアーキテクチャx86_64」でも稼働する記載があるのでMac上で構築できるかなと考えました。 ちょうど、Docker for Mac でプロキシサーバなどを稼働中なので、追加コンテナとして Homebridge を稼働させるには準備が整っていました。

しかし、そんな期待とは裏腹にREADMEにはこんな記載が... 「Currently this image will not work when using Docker for Mac or Docker for Windows due to this and this.」 どうやら、ネットワーク的な理由で Docker for Mac では運用できないようです...

手持ちのMac上にとりあえず、Homebridgeを構築したい...いろいろと検討した結果、以下の構成に挑戦して見ました。

Docker Machine は VMWare Fusion にも対応(VMWare FusionはDocker Machineにも対応とも言える)しているので、ネットワークを分離したい場合は、こちらの方法ですでに運用していました。 Homebridge on Dockerは「host」モードというDockerのネットワークモードで稼働する必要があるので、この選択は理にかなっていると言えます。 確か、Docker for Mac はhostモードに対応していなかったような...

前提

今回、この方法で構築するためには以下の条件が必要になってきます。

  • Mac
  • Docker for Mac (docker-machine コマンドを利用する為)
  • VMWare Fusion (docker machine を構築する為)

VMWare Fusion は有料の仮想マシン構築環境なので、注意が必要です。 おそらくですが、VirtualBoxでの代替も可能かと思われます。

VMWare イメージ作成

まずは、Docker Machine のコマンドを利用してVMWareイメージを作成します。 コマンドラインで以下を実行します。

[codebox title="Docker Machine"]

docker-machine create \
  --driver vmwarefusion \
  --vmwarefusion-cpu-count "1" \
  --vmwarefusion-memory-size "2048" \
  --vmwarefusion-disk-size "10000" \
  homebridge-on-vmware

[/codebox]

[timeline] [tl label='--driverオプション' title='仮想マシンの指定'] 「vmwarefusion」を指定してVMWare FusionでMachineを作成することを明示します。 [/tl] [tl label='--vmwarefusion-cpu-countオプション' title='CPU数の指定'] 今回はCPU数を1つでイメージを構築します。 [/tl] [tl label='--vmwarefusion-memory-sizeオプション' title='メモリサイズの指定'] 今回はメモリサイズを2GBでイメージを構築します。 [/tl] [tl label='--vmwarefusion-disk-sizeオプション' title='ディスクサイズの指定'] 今回はディスクサイズを10GBでイメージを構築します。 [/tl] [tl label='イメージ名' title='イメージ名の指定'] 最終行の文字列はVMWareイメージの名称になります。今回は「homebridge-on-vmware」としました。 [/tl] [/timeline]

仮想マシン再起動

いろいろ試した結果、ポイントの一つが仮想マシンの再起動です。 docker-machineコマンドで、作成した仮想マシンは現状、VMWare Fusionでは安定しないイメージです。 上記コマンド実施後に仮想マシンは起動した状態になりますが、1度停止します。

VMWare Fusionアプリ上で仮想マシンを起動してあげます。 多くの場合、Docker Machine は以下に格納されています。

  • ~/.docker/machine/machines/homebridge-on-vmware/

通常、MacのFinder上では上記のパスは見えないと思いますので、「open」コマンドで開いてあげるといいかと思います。 上記の「homebridge-on-vmware」は今回作成したイメージ名です。

[codebox title="Shell"]

open ~/.docker/machine/machines/homebridge-on-vmware/

[/codebox]

Finderで開かれたフォルダの中に拡張子「vmx」のファイルがありますので、そちらをダブルクリックすることでVMWare Fusionアプリから管理することができるようになります。

まずはVMWare Fusionアプリから仮想マシンをシャットダウンしましょう。 その後、起動します。 ▲このメッセージに従い、仮想マシンをアップグレードします。 いろいろ試した結果であり、根拠はありませんが、このアップグレードを行わないとネットワークがうまく動作しないことがありました。 ※根拠があるわけではありませんので、全ての方の環境で適用できるかはわかりません

ネットワークインターフェース追加

通常、仮想マシンを作成するとネットワークインターフェースが一つ用意されています。 Docker Machine上では「eth0」に当たるインターフェースです。 しかし、こちらが曲者で、デフォルトではインターフェース形式が「Mac を共有」になっています。 ▲「Mac を共有」とはホストOS(VMWare FusionがインストールしてあるMac)がネットワークを共有することで通信を行います。 要するに、ホストOSと仮想マシン間でしか通信できない為、iPhoneやその他、物理的に離れたマシンとは通信することができません。

そこで、「ブリッジされたネットワーキング」というセクションにある「自動検出」を選択したいところです。 通常、こちらを選択することでホストOSが属するネットワークにゲストOS(今回はDocker Machine)が参加することができます。 要するに iPhone などと通信できるようになります。

しかし、Docker Machineにおいては、この設定にしてしまうと問題が発生します。 なぜかDocker Machine自体のIPアドレスが変わらず、Docker MachineにSSH経由でログインできなくなってしまうのです。 具体的には「docker-machine ssh <マシン名>」というコマンドが動かなくなります。 このコマンドを利用して、マシン上で各種設定をしたいのですが、利用できないので大変不便です。

そこで、既存のネットワークインターフェースはそのままとし、新たにインターフェースを追加します。 ▲ネットワークの種類は「自動検出」に設定します。 これにより、物理的に別のデバイスとも通信できるようになりました。 Docker Machine上では「eth1」に割り当てられています。

[codebox title="Shell"]

docker-machine ssh homebridge-on-vmware

[/codebox]

上記コマンドで、Docker Machineにログインし、

[codebox title="Shell"]

ifconfig eth1

[/codebox]

上記コマンドでIPアドレスを確認してください。 PINGなどで、疎通確認をしてください。

データ永続化

この先の手順で、Docker Machine上にデータを保存していきます。 しかし、そもそもDockerとはデフォルト状態では、データが永続化されず、仮想マシンが再起動するたびにまっさらな状態になります。 作って、起動して、停止して、捨てて、また作って...という振る舞いがDockerになります。 そのため、明示的に保存したいデータは「永続化する」という設定が必要になってきます。

Docker Machineにおいては、マシン上で以下のコマンドを実施しておきます。

[codebox title="Shell"]

# Change super user
sudo su - 

# Create script
cat > /var/lib/boot2docker/bootlocal.sh <<EOF
echo "tar cf /var/lib/boot2docker/userdata.tar . -C /home/docker/" >> /opt/shutdown.sh
EOF

# Change permission
chmod +x /var/lib/boot2docker/bootlocal.sh

# Change normal user
exit

[/codebox]

上記のコマンドで「/var/lib/boot2docker/bootlocal.sh」というスクリプトが生成されて、マシンの停止時に「/home/docker/」ディレクトリ配下のデータを永続化することになります。

ついでに永続化するデータのフォルダを作っておきます。 今回は「/home/docker/data/var/lib/homebridge」ディレクトリを作っておきます。 マシン上で以下のコマンドを投入します。

[codebox title="Shell"]

mkdir -p /home/docker/data/var/lib/homebridge

[/codebox]

コンテナの作成

docker-composeコマンドで、マシン上にコンテナを配置していきます。 下記する手順は、ホストOS側で実施します。 まずは以下のようなdocker-composeコマンド用コンフィグファイルを用意します。 ファイル名は「docker-compose.yml」とします。

[codebox title="docker-compose.ym"]

version: '3'

volumes:
  homebridge-dat:
    driver_opts:
      type: none
      device: /home/docker/data/var/lib/homebridge
      o: bind

services:
  homebridge:
    image: "oznu/homebridge:latest"
    container_name: "homebridge"
    restart: always
    network_mode: host
    environment:
      - TZ=Asia/Tokyo
      - PGID=1000
      - PUID=1000
    volumes:
      - homebridge-dat:/homebridge

[/codebox]

「device: /home/docker/data/var/lib/homebridge」という記載が、マシン上の永続化対象データが格納されるパスです。 これを「homebridge-dat」というエイリアスに設定しています。

「image: "oznu/homebridge:latest"」という記載で、「latest」がポイントです。 「latest」がx86アーキテクチャ用のDockerイメージになっているからです。

「network_mode: host」という記載で当該コンテナは全てのネットワークを属するネットワークと疎通することになります。

「- homebridge-dat:/homebridge」という記載はマシン上のパスと、コンテナ上のパスをマッピングしています。 Dockerの仕組みがわかるとピンとくるかと思いますが、よくわからない場合はこういうものだと思ってもらえればいいかと思います。

さて、ファイルが生成できたら以下のコマンドを実行してコンテナを稼働させましょう。

[codebox title="Shell"]

eval $(docker-machine env homebridge-on-vmware)
docker-compose up -d

[/codebox] 上記の1行目がポイントなので、間違えないでください。 1行目のコマンドで、コンテナのデプロイ先がDocker Machineになります。 コマンドがエラーになったりした状態で、「docker-compose up -d」を実施するとホストOS側にコンテナをデプロイしてしまうので、失敗です。

HomeKitアクセサリ追加

実はこの状態で、すでにHomebridgeが稼働しています。 アクセサリに追加するには当該HomebridgeのQRコードを表示してあげましょう。

[codebox title="Shell"]

docker-machine ssh homebridge-on-vmware

[/codebox] ▲マシンにログインします。

[codebox title="Shell"]

docker-machine ps

[/codebox] ▲HomebridgeコンテナのコンテナIDを確認します。「CONTAINER ID」という列の文字列がコンテナIDになります。

[codebox title="Shell"]

docker-machine logs <コンテナID>

[/codebox]

▲ターミナル上でQRコードが表示されるので、これらをiPhoneのHomeアプリで読み込んで追加していきます。

無事追加されました。 現状は、何にもアクセサリを追加していないので、これから追加方法を調査したいと思います。 そもそも初めて Homebridge を触るので、まだまだ調査が必要ですしそもそもこの環境で利用できるのか...

[say]使えなくても構築できて満足...[/say]