Using homekit component inside Docker

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:

[email protected]:~# 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.

3 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:

[email protected]:~# 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!

my homekit config is very straightforward:

homekit:
  port: 51827
  auto_start: False
  filter:
    include_entities:
      - climate.thermostat
      - sensor.thermostat_temperature
      - sensor.thermostat_humidity
      - ...all entities for homekit listed here...

this is my complete docker-compose.yaml for HA (except for Host:xxx which is used to ingress traffic for HA via traefik):

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/ttyACM1:/dev/ttyACM1
    ports:
      - 8123:8123
      - 51827:51827
    networks:
      - homeassistant
    labels:
      traefik.port: '8123'
      traefik.frontend.rule: Host:xxx
1 Like

Hi, thanks for the info, 3 questions

Are you running avahi native or in docker?
Wat is your avahi config?
What ip do you fill in the config yaml under advertise_ip, from the os, docker or hass container?

I’m using native avahi that came pre-installed on my Synology nas.

 $ cat /etc/avahi/avahi-daemon.conf
# This file is part of avahi.
#
# avahi is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# avahi is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with avahi; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA.

# See avahi-daemon.conf(5) for more information on this configuration
# file!

[server]
loglevel=0
#host-name=foo
#domain-name=local
#browse-domains=0pointer.de, zeroconf.org
use-ipv4=yes
use-ipv6=yes
#allow-interfaces=eth0
#deny-interfaces=eth1
#check-response-ttl=no
#use-iff-running=no
#enable-dbus=yes
#disallow-other-stacks=no
#allow-point-to-point=no
#cache-entries-max=4096
#clients-max=4096
#objects-per-client-max=1024
#entries-per-entry-group-max=32
ratelimit-interval-usec=1000000
ratelimit-burst=1000
aliases-conf=/var/tmp/nginx/avahi-aliases.conf

[wide-area]
enable-wide-area=yes

[publish]
#disable-publishing=no
#disable-user-service-publishing=no
#add-service-cookie=no
#publish-addresses=yes
#publish-hinfo=yes
#publish-workstation=yes
#publish-domain=yes
#publish-dns-servers=192.168.50.1, 192.168.50.2
#publish-resolv-conf-dns-servers=yes
#publish-aaaa-on-ipv4=yes
#publish-a-on-ipv6=no

[reflector]
#enable-reflector=no
#reflect-ipv=no

[rlimits]
#rlimit-as=
#rlimit-core=0
rlimit-data=4194304
#rlimit-fsize=0
rlimit-nofile=768
rlimit-stack=4194304
rlimit-nproc=3

[synology]
resolve-raop=yes
resolve-airplay=yes
resolve-airport=yes

This is a service descriptor for HA:

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

In this configuration advertise_ip isn’t necessary. You can see my homekit config above in its entirety.

Best of luck!

1 Like

Thank you @rzen for all the tips! I finally got mine working!

For anyone on Raspberry Pi using Docker, here are additional pointers:

  • Don’t forget to clear out .homekit.state
  • I followed @rzen’s instructions but needed to update the MAC (id) on the host’s avahi service after home-assistant started

Thanks for the help.

On Mac os i used this command to get mDNS to work correctly.

dns-sd -R Homeassistant _hap._tcp local 51827 md=”HA Bridge” pv=1.0 c#=2 id=00:11:22:33:44:55 s#=1 sf=1 ci=2 ff=0 sh=UaTxqQ== 

MAC-adress, as mentioned by others, should be the same as in .homekit.state

2 Likes

It works link a charm! You just save my day. :smiley:

Now I am having trouble adding HomeKit controller devices to HA.

Does anyone have HA running in Docker and HomeKit accessories (ecobee in my case) paired with HA?

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.