Skip to content

Instantly share code, notes, and snippets.

@treblada
Last active December 29, 2025 11:23
Show Gist options
  • Select an option

  • Save treblada/4ca4cdf820d4073051681fb63b40ff8f to your computer and use it in GitHub Desktop.

Select an option

Save treblada/4ca4cdf820d4073051681fb63b40ff8f to your computer and use it in GitHub Desktop.
How to configure Yahka on dockerised ioBroker with Avahi/Zeroconf (Dec 2025)

Dockerised ioBroker (v11) + Yahka + HomeKit (iOS 26)

Created: 2025-12-29

#docker #iobroker #yahka #homekit #avahi #zeroconf #bonjour

Abstract

It is generally possible control devices in ioBroker via Yahka on your iOS device, but with some limitation, i.e. home controls cannot be shared with others without an HomeHub device like an AppleTV (4.Gen) or HomePod.

General Architecture (as I understand it)

Yahka is a HomeKit bridge, it exposes a HomeKit API and allow control of devices in ioBroker which are not HomeKit capable.

Yahka anounces itself on the configured network interfaces using Zeroconf (aka Bonjour). That happens usually via Avahi, Yahka and Avahi communicate via D-BUS. This is also one possible obstacle if ioBroker runs in a docker container - more about it later.

You iOS device picks up the anouncement and knows where your service lives. It can then contact it and add it into your home configuration. Devices you have configured in Yahka become visible in your Home app. How to do it is beside the scope of this document. That will allow you to control your devices if your iOS device can contact Yahka - usually it means you have to be in the same network. The configuration will be available all devices sharing the same iCloud account.

It is not possible to share this configuration with others any more (aka invites) because Apple does not want you to. For that you need a HomeHub device, i.e. an AppleTV (4.Gen) or HomePod. Since I have none I cannot further elaborate on that topic.

My setup and the limitations which come with it

  • ioBroker (v11) in a Docker container, I tried it
    • in network_mode=host and
    • in bridged network mode
  • Linux host
  • iOS 26.2

Firewall configuration (iptables)

This is not an essential part of the documentation and may be skipped.

I have disabled the automatic firewall configuration by docker because - in my opinion - it

  • behaved unpredictable
  • opened the system more than I was comfortable with and
  • was not managable in combination with iptables-save.

Instead I manage the necessary rules manually.

To disable firewall management by docker create the file /etc/docker/daemon.json with following content

{"iptables": false}

Docker configuration

For easier management I like to use docker compose, even if ioBroker is only one container.

services:
  iobroker:
    restart: unless-stopped
    image: buanet/iobroker:v11.0.0
    container_name: iobroker
    hostname: iobroker
    ports:
      - "8081:8081"
      - "8090:8090"
      # additional ports you might want to expose
    environment:
      - USBDEVICES=/dev/ttyACM0
      - AVAHI=true
    devices:
      - /dev/ttyACM0
    volumes:
      - /share/iobroker/data:/opt/iobroker
      # use following if you want to provide a custom avahi configuration
      # - /share/iobroker/conf/setup_avahi.sh:/opt/scripts/setup_avahi.sh
    networks:
      - iobroker-net

networks:
  iobroker-net:
    driver: bridge
    name: br-iobroker
    enable_ipv4: true
    enable_ipv6: false
    driver_opts:
      com.docker.network.bridge.name: br-iobroker

This configuration reflects the bridged network mode. Host host*mode ommit thenetworks` section and add following line

services:
  iobroker:
    network_mode: host
    ...

ioBroker in host network mode

This basically connects you container directly to your host's networks. It makes some things very simple, e.g. you do not have to explicitly configure port forwardings from the host to the container. On the other hand it is regarded as less secure that a dedicated networks.

In this case it comes at the price: Zeroconf. Usually there is an Zeroconf daemon (typically: avahi) which runs constantly, listens on UDP port 5353 (mDNS) collects information, removes outdated entries and makes this database avaiable via D-BUS socket on the host.

This makes it impossible to operate avahi both on the host and in the container. If you do not need avahi on your host: great, problem solved. But otherwise any UDP datagram can be only consumed by one avahi instance.

There are some articles suggesting you can expose the host's D-BUS socket to the container, but it requires running your container in priviledged mode (probably). I did not try it.

If you want to go with that option and you want your own version of avahi-daemon.conf you might want to consider to provide your own version of /opt/scripts/setup_avahi.sh in the docker container, it can be injected using volume configuration. The iobroker image does not include the avahi daemon. So each time you spin up a new container (e.g. after a container shutdown), a new avahi service will be installed with a defailt configuration. You cannot inject the configuration directly because that will interfere with the service installation. The only way I found was to have a copy of the avahi-configuration in the data directory, adapt the setup_avahi.sh script and copy the configuration in place after the package has been installed.

For me the host network mode was out.

ioBroker in bridged network mode

This creates an internal docker network (e.g. 172.11.0.0/24) with an explicit interface on the host side. For every exposed port docker will spawn a docker-proxy instance. Communication is predictable - if you want to contact your container, use its internal IP address. If automatic firewall rule updates are disabled, you have to configure a masquerading rule in the postrouting table and in the FORWARDING chain.

This works great for the usual operations, but now there is another issue: avahi in the container can annouce the _hap._tcp service, but only on the internal network. You will see it on the host if you run

avahi-browse _hap._tcp

but that's how far the message gets. It won't be visible on your network.

To distribute the message in my local network I have configured an avahi reflector on my host in /etc/avahi/avahi-daemon.conf

[reflector]
enable-reflector=yes
reflect-ipv=no
reflect-filters=_hap._tcp.local

This works, but the forwarded message still carries the original information, especially the internal container IP address. It will not be usable in your network without additional routing configuration. Your iOS device will try to contact 172.11.0.2 (assuming that is your container's IP address), it will send it to your default gateway (usually the router) and if the router does not know where to find that network, it will be discarded.

THIS WORKED: What worked was to duplicate the message and let the host distribute it. First you need details of the sent message. You can get them using

avahi-browse -v -r _hap._tcp

It will give you the resolved message which should look similar to

hostname = [iobroker.local]
address = [172.11.0.2]
port = [8090]
txt = ["sh=XtZrig==" "ci=2" "sf=1" "s#=1" "pv=1.1" "md=ioBroker" "id=00:11:22:33:44:55" "ff=0" "c#=2"]

You can use that information and create your own service description as /etc/avahi/services/hap.service

<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
  <name replace-wildcards="no">HomeKit on ioBroker</name>
  <service protocol="ipv4">
    <type>_hap._tcp</type>
    <port>8090</port>
    <txt-record>sh=XtZrig==</txt-record>
    <txt-record>ci=2</txt-record>
    <txt-record>sf=0</txt-record>
    <txt-record>s#=1</txt-record>
    <txt-record>pv=1.1</txt-record>
    <txt-record>md=ioBroker</txt-record>
    <txt-record>id=26:0b:bc:cc:73:f6</txt-record>
    <txt-record>ff=0</txt-record>
    <txt-record>c#=6</txt-record>
  </service>
</service-group>

Now the distributed message will have your host as origin and any recipient will try to contact your host on port 8090. The connection will be forwarded to your docker container, thanks to the forwarding rules.

Limitation by Apple

Regardless how you decide to configure Yahka, avahi and your host, one limitations remains. The setup is only usable by one person; more precisely: by one iCloud account.

Once you have added the bridge to your home configuration, nobody else can add it.

Sharing of the configuration is not possible, that requires a HomeHub device.

One could work around that limitation by configuring a second Yahka instance, which is fairly easy in ioBroker. Both instances have to be configured separately and there is no standardized or easy way to share configuration between Yahka instances.

Summary

Ultimately, Apple's limitation was the reason why I cancelled the project. It was fun to find out all those details and workarounds, but in the end I already have a working web UI in ioBroker where I can control all of my devices. Having the controls in a HomeApp instead of the browser for the price of supporting two configurations in Yahka does not seem like a huge win to me. But you do you! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment