Created: 2025-12-29
#docker #iobroker #yahka #homekit #avahi #zeroconf #bonjour
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.
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.
- ioBroker (v11) in a Docker container, I tried it
- in
network_mode=hostand - in bridged network mode
- in
- Linux host
- iOS 26.2
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}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-iobrokerThis configuration reflects the bridged network mode. Host host*mode ommit thenetworks` section and add following line
services:
iobroker:
network_mode: host
...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.
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._tcpbut 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.localThis 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._tcpIt 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.
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.
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! :)