Using homekit component inside Docker

I saw that mentioned as a workaround option, but I’m hesitant as I just switched to Docker for Mac to get away from running VMs in VMWare Fusion. What are you using as the VM in VirtualBox, is it https://github.com/boot2docker/boot2docker?

Had the same feeling, moved from a RPI to Mac and thought it was a step back using virtualbox. However I use a Ubuntu 18.04 VM and am pretty happy with it as it uses little resources and is very stable. A more lightweight OS could be interresting though.

I’ve got it up and running now in a Container Linux VM running in VMWare Fusion. The networking works as expected in host mode, including the mDNS for Homekit.

I’m digging the container approach so far, but I wouldn’t recommend Docker for Mac. On top of the network weirdness, it had some kind of memory leak that ate up all of the available RAM on the host.

Thanks for discovering what this problem is/was! I was having the same trouble (with ‘–net=host’ set for the Docker container).

I managed to get around it by running the Home Assistant Docker container through Traefik (reverse proxy), which I was doing anyway with my original/previous container running Home Assistant, to enable SSL and redirect HA to my domain.

did you find a solution for homekit with hass in docker with traefik?

Yes, here’s my config that works for me

Strange, my config is the same but no respons of hass in homekit.

Presumably you added/enabled entities to expose to HomeKit under homekit: in configuration.yaml?

If so, do you see the Home Assistant Bridge in any of the HomeKit apps?

yes I put some entities in homekit, but when I look it up in the iOS app I don’t see the bridge and I can’t connect when I type in the number from hass.

Have you tried disabling/removing traefik and just running Home Assistant via Docker without it? Does HomeKit wire then?

Nope, when i use hass in macos python3 under brew it works, has something to do with docker i think

…I’ve just remembered I had to change the port to get it working. In my homekit.yaml file I set port: 51829

Maybe try that, or a different port?

Tried that, how do you do this with traefik?

This is a dated topic, but I looked around and didnt find a clear solution. After a bit of digging it looks like the solution here is two fold:

  1. Open (publish) port 51827 in HA container (or, as it turns out, any port as its configurable on either side)

  2. Publish (advertise) HA’s HAP (“Homekit Accessory Protocol”) service (port 51827) to mDNS

The latter can be accomplished in a couple of different ways depending on the host system. In my case its a Synology NAS which doesnt come with avahi-pubilsh installed.

One (somewhat hacky in this scenario) way to announce a service to mDNS is to configure it in /etc/avahi/services.

I named mine as homeassistant.service and populated as follows:

root@nas:~# cat /etc/avahi/services/homeassistant.service
<service-group>
  <name>Home Assistant Bridge</name>
  <service>
    <type>_hap._tcp</type>
    <port>51827</port>
    <txt-record>md=HA Bridge</txt-record>         <!-- friendly name                 -->

    <!-- the following appear to be mandatory -->
    <txt-record>pv=1.0</txt-record>               <!-- HAP version                   -->
    <txt-record>id=00:11:22:33:44:55</txt-record> <!-- MAC (from `.homekit.state`)   -->
    <txt-record>c#=2</txt-record>                 <!-- config version                -->

    <!-- the following appear to be optional -->
    <txt-record>s#=1</txt-record>                 <!-- accessory state               -->
    <txt-record>ff=0</txt-record>                 <!-- unimportant                   -->
    <txt-record>ci=2</txt-record>                 <!-- accessory category (2=bridge) -->
    <txt-record>sf=1</txt-record>                 <!-- 0=not paired, 1=paired        -->
    <txt-record>sh=UaTxqQ==</txt-record>          <!-- setup hash (used for pairing) -->
  </service>
</service-group>

MAC address should be the same that was provided to HomeKit at pairing. It is stored in .homekit.state located in HA configuration folder. At least in my version of Home Assistant. I believe older versions keep it elsewhere, should be easy to find.

Config version (c#) is an integer, also stored in .homekit.state however the value in the service descriptor for c# doesnt appear to have to match whatever is in .homekit.state.

Setup hash (sh) is used for pairing with new accessories. I omitted it, as well as the rest of optional TXT records.

For completeness here’s my rather unremarkable docker-compose.yaml:

version: '3.2'
networks:
  homeassistant:
    external: true
services:
  homeassistant:
    container_name: home-assistant
    image: homeassistant/home-assistant
    restart: always
    volumes:
      - ./config:/config
      - /etc/localtime:/etc/localtime:ro
    devices:
      - /dev/ttyACM0:/dev/ttyACM0
    ports:
      - 51827:51827
    networks:
      - homeassistant

Hope this helps.

5 Likes

Thank you so much. I was looking around for days and trying different things found in various posts but yours worked perfect for me. Now I got my stuff working with home kit. Thanks again.

Hey first of all thank you for this info. I still have a few questions. After configuring the HomeKit component to use safe mode, I was able to pair it within the home.app, but I’ve got issues to populate accessories within the latter. The HomeKit integration seems to work after inspecting the logs. So here are my questions:

You’re not running the container in host mode, right (that’s what I see at least in your compose file)?

Did you have to configure anything else for the accessories to show up?

You’re not running the container in host mode, right (that’s what I see at least in your compose file)?

Correct.

Did you have to configure anything else for the accessories to show up?

Not in the context of this topic of getting mDNS to work with services inside docker containers.

So… digressing off topic here.

There are two issues with getting homekit accessories to show up (that i’ve encountered).

One, the need to postpone homekit start until after zwave network has initialized. Which can take as long as 5-10 minutes. Even longer.

I use this automation to start homekit:

- id: homekit-start
  alias: 'Start HomeKit'
  initial_state: true
  trigger:
    - platform: event
      event_type: zwave.network_ready
    - platform: event
      event_type: zwave.network_complete
  action:
    - service: homekit.start

The second issue is to do with filtering (including) accessory entities. Thats done as part of homekit: config key:

homekit:
  auto_start: False
  filter:
    include_entities:
      - climate.thermostat
      - sensor.thermostat_temperature
      - ...
      - switch.outside_floodlight_switch

Note that here auto_start is set to False. This is because homekit service is expected to start by automation shown above.

Lastly, this is an old hack, for all I know, this has been fixed in recent version(s) of HA.

mhhh I definitely have trouble with it running reliable. I suspect that I miss iptable rules since the bridge is seen and the hass HomeKit logs don’t look off at all.
The avahi service you posted is meant to be run on the host, right?
Thanks for sharing though. I’ll definitely tinker with it!

edit: may I ask how you configured your external network?

yes avahi service is configured on the host, that is, on the synology nas box.

as for network configuration if you mean docker network, there’s a ui in synology docker app that allows creation of external networks, i’m sure its not much more than a facade to docker network create. in fact, here:

root@nas:~# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
...
e239xxxxxxxx        homeassistant       bridge              local
57efxxxxxxxx        ingress             bridge              local
...

Hi @rzen! You are such a big help in this and I have the feeling I almost got it working for me.
Can you show how you configure your homekit component in configuration.yaml?
I am on the latest Home Assistant version, have everything running in Docker behind a NGINX reverse proxy. I want to avoid having network_mode: host at all cost.

With the homeassistant.service I managed to get the bridge published, however, I cannot connect to it from Home.app. It seems, that I somehow need to get from the docker-ip (172.xxx) to the host-ip (192.168.1.8). Any ideas? How did you solve that part?

Thanks again!