Using homekit component inside Docker

Thanks, this command is working for me

Question, is ik posible to use dns-sd as deamon or something that runs automatic on the background?

edit:
For now I made an automator program that runs with the startup of macOS.

Just wanted to drop in here and post my solution. I’ve spent a lot of time getting a simple solution worked out, given the amount of time spent I feel that I must share.

Issue:
Running in network_mode: host would allow me to control my Ecobee3 Lite thermostat. This seems to use things related to mDNS, multicast, Bonjour, Homekit; I may be slightly wrong about that part.

How to pinpoint if you have the same issue:

  1. With Home Assistant running with network_mode: host, run:
docker exec [your home assistant docker container id here] python3 -m netdisco
  1. With Home Assistant running WITHOUT network_mode: host, run:
docker exec [your home assistant docker container id here] python3 -m netdisco

If #1 returns results but #2 does not, then you have the same situation as me and the solution below will probably work!

(side note: netdisco is documented here: https://www.home-assistant.io/integrations/homekit_controller/#home-assistant-cannot-discover-my-device)

Solution:
Add a container that repeats mDNS traffic from one network interface to another network interface. In my case I ran

docker exec [your home assistant docker container id here] ifconfig

and found that my Home Assistant container had a ip address of 192.168.80.7. To determine what network interface that’s on, I ran route -n and then found the 80 subnet (192.168.80.0) in the Destination column and then grabbed the interface name from the Iface column. I did the same for my host; find 0.0.0.0 and then grabbed the interface name from Iface.

Once you have the two network interface names, you can run a container to repeat mDNS between the two network interfaces.

Here’s a docker-compose example:

version: '3.8'

services:
  home-assistant:
    image: homeassistant/home-assistant
    ports:
    - 8123:8123

  mdns-repeater:
    image: angelnu/mdns_repeater
    network_mode: host
    environment:
    - hostNIC=enp4s0
    - dockerNIC=br-de87821a94e9

Also, here’s a link to my solution: https://github.com/TonyBrobston/tbro-server/blob/e3ff788e81c68848e20a5d325fe5c2e2484bf65d/home-automation/docker-compose.yml#L34-L40

I personally felt this was the best way to handle this problem, I feel like running network_mode: host on my Home Assistant container is opening up a bunch of things unbeknownst to me. I prefer to open only exactly as much as necessary. I realize that the mdns-repeater in my solution is running in network_mode: host, however I assume (probably a bad assumption) that the mdns-repeater isn’t doing anything more than repeating mDNS. I may look further into that repo later to be sure.

Hope this helps someone else!

8 Likes

Hey @TonyB . Appreciate you posting this. I really hope you are on Mac? because this solution may be just what I’m looking for.

Edit: NVM. #2 Does return results for me :confused:

Any solutions available for MacOS? I’m about to throw Docker out the window for this, but I really like the idea of having everything containerized.

To everyone who has HASS running in docker on Synology DSM
The Avahi Reflector doesn’t want to join docker mutlicast group for some reason. I suspect synology has modified it this way. I spent way to much time on it.
The only thing that helped me was

mdns-repeater:
    image: angelnu/mdns_repeater
    network_mode: host
    environment:
    - hostNIC=enp4s0
    - dockerNIC=br-de87821a94e9
1 Like

@TonyB Amazing tips on running HA without host network! I just have one more thing to add.

I am also running Home Assistant in a Docker bridge network (without wanting to use network: host). The mdns-repeater sidecar container works amazingly well to forward mDNS packets in and out of a Docker bridge network.

However, I realise that in my setup, I had to also install avahi-daemon WITHIN the homeassistant container so that discovery would work. I don’t understand too much about the Avahi/Bonjour/SSDP protocols to explain why this is required.

I found out that this was required when following this guide on how to resolve mDNS queries from within a Docker container: mDNS, avahi and docker non-root containers. Basically, with the mdns-repeater container in the same bridge network, I was able to discover other devices using avahi-browse -alr with the above method.


My setup is thus as follows, after taking everything into account:

  1. Create a dedicated Docker bridge network homeassistant with docker network create homeassistant.
  2. The network interface of the newly created network is given by br-$(docker network ls | grep homeassistant | cut -d' ' -f1). You can use this to automatically substitute the value of the bridge network into the docker-compose file.
  3. In the HA Dockerfile, install avahi-daemon like as follows. This assumes we are using the Alpine-based images, which are default:
FROM homeassistant/home-assistant:2021.12.7

# Install avahi-daemon in container
# https://gnanesh.me/avahi-docker-non-root.html
RUN set -ex \
  && apk --no-cache --no-progress add avahi avahi-tools dbus \
  # Disable default Avahi services
  && rm /etc/avahi/services/* \
  && rm -rf /var/cache/apk/*

# Add our custom entrypoint
COPY docker-entrypoint.sh /usr/local/sbin/
ENTRYPOINT ["/usr/local/sbin/docker-entrypoint.sh"]

# Rest of your dockerfile here...
  1. Create a custom entrypoint entrypoint.sh:
#!/bin/bash
set -euxo pipefail

# Start dbus and avahi-daemon
dbus-uuidgen > /var/lib/dbus/machine-id
dbus-daemon --config-file=/usr/share/dbus-1/system.conf --print-address
avahi-daemon --daemonize

# Run anything else you want to run before HA starts...

# Run original entrypoint
exec /init

And voila, you should now be able to see integrations like HomeKit and Google Cast appearing in the integrations page automatically :slight_smile:

You can also verify this by running avahi-browse -alr in the HA container now, since avahi-tools is installed above.

2 Likes

Wow this works for me, many thanks, it’s a simple solution. Do you know if the docker NIC (Iface) can change? I set a static IP to my HA container.

Trying to get Homekit working while running HA without --net=host. Tried all the solutions from above and Homekit not working with docker · Issue #15692 · home-assistant/core · GitHub but could not get it working. Pairing does not succeed: Accessory Not Found.

Should these methods still work?

Could not edit previous post.

The mdsn repeater container solution still works. Not a fan because of the --net=host that it needs.

At this moment the Avahi reflector mode started working out of nowhere. Will test more.

I try my luck and hope somebody can help:

iam running HA in a bride network and have the mens repeater as container running in host network.

the HomeKit App does show the new bridge I can start the setup process but than it timed out and I can’t find where the problem is :confused: any idea ?

I also stuck at the same issue. Here’s what I found by far:

After I added mDNS repeater to my docker-compose.yml, the error message when adding HA Bridge to was changed from

Accessory Not Found
Make sure your accessory is powered on and connected to your router with an Ethernet cable, then ty again.

to

Unable to Add Accessory 
Accessory is not reachable.

And I check the network packets with Wireshark. Looks like the mDNS packets did be forwarded from cotnainer bridge network to host network. However, since HA Homekit Controller was listening on bridge network:

2023-01-30 05:09:36 INFO (MainThread) [pyhap.accessory_driver] Starting accessory HASS Bridge on address 172.27.0.2, port 21063.

The forwarded mDNS record was also advertising the IP in bridge network:

5cb632a6036f4874bfdcd61455d9c48d-hap.local: type A, class IN, cache flush, addr 172.27.0.2
HASS Bridge Bedroom EF3D24._hap._tcp.local: type SRV, class IN, cache flush, priority 0, weight 0, port 21063, target 5cb632a6036f4874bfdcd61455d9c48d-hap.local

So when adding HA Bridge to Homekit, the IP address that Homekit got from mDNS record was the IP in docker network (172.27.0.2), which is not reached able outside the bridge network, rather than the host IP.

I think forwarding mDNS traffic between docker bridge network to host network only allowed HA to discover devices on local network. If the goal is to add HA Bridge to Homekit, we might need to find a way to change the advertised IP in mDNS to Host IP or use another solution in this thread that manually advertise mDNS with avahi, however it’s kind of hack in my opinion.

Looks like HAP-python does have the option to specify advertised_address, but I haven’t look into how to configure this in HA.

Update:

Just noticed that HA Homekit Controller also has the advertised_address config.
https://github.com/home-assistant/core/blob/cb13418babd21a1e9584978b0c523f1b1e4e1cb0/homeassistant/components/homekit/init.py#L304

I added this line to my configureation.yaml and it started to work.

homekit:
  - name: HASS Bridge
    advertise_ip: YOUR_HOST_IP # <---- Add this line to configuration.yaml

I can see the advertised IP address in mDNS is now my host IP:

5cb632a6036f4874bfdcd61455d9c48d-hap.local: type A, class IN, cache flush, addr 192.168.50.101
HASS Bridge Bedroom EF3D24._hap._tcp.local: type SRV, class IN, cache flush, priority 0, weight 0, port 21063, target 5cb632a6036f4874bfdcd61455d9c48d-hap.local

I hope this helps!

This had been working for months for me. Now, after I updated HA docker I seem to get stuck on ‘dbus-daemon --config-file=/usr/share/dbus-1/system.conf --print-address’ which has no output and never ends

It helped a lot :heart:

Thank you so much.

1 Like

Can anyone help me figure out what the correct environment entries for hostNIC and dockerNIC are? I’m stumped…
Running docker on macOS.

I’ve given up on docker :slight_smile:
Tried UTM but that one is not able to idle the CPU cores that are reserved for the VM (but Homekit integration worked great).
So settled on VMWare Fusion which can idle the CPU cores and I already had a license. All works great now.

1 Like

Did you find any workaround for it?
Having my home assistant run on docker in mac os, but cant install now homekit on iPhone as the mDNS traffic wont go out from the container.

I was able to configure by using combination of two methods above:

  • Link on gists Home Assistant Docker on Mac OS · GitHub
  • You need to use custom docker image with installed avahi to automation of mdns redirect (see docker-entrypoint.sh)
  • Then you need to register homekit bridge in mac os mDns responser by using dns-sd (see dns-sd.sh)
  • And finally you need to configure Home Assistant to advertise real IP address of host machine (see configure.yml)
1 Like

Oh great! Months, too late :slight_smile:
But seriously thank you, I’m going to give it a try. As I have other docker images running, I’d very much still like to run that than having to run a VM for HA as well (as I’m doing now).

Questions:

  • Running dns-sd.sh ← that will run as a daemon in macOS, it’s not just a one time registering?
  • Updates to HA will mean having to build a new image via the dockerfile, right? (that’s one thing I like about the VM - it just updates the image, restarts and done)

Thanks again!

  • Running dns-sd.sh ← that will run as a daemon in macOS, it’s not just a one time registering?

yes, dns-sd script trying to prepare right parameters to run dns-sd -R to announce HA as homekit device in your network. it basically mDns retranslator.

Updates to HA will mean having to build a new image via the dockerfile, right?

right, homeassistant/home-assistant:stable it will always rebuild from latest stable version, but I don’t know how migration will happens.

Thank you!