HomeAssistant + Docker Swarm + Homekit

The magic is twofold:

On each docker swarm node, run:

docker network create --config-only --subnet 192.168.1.0/24 -o parent=eth0 --ip-range 192.168.1.200/30 --gateway 192.168.1.1 physical-config

Where:

192.168.1.0/24 is the network that the docker host runs on

eth0 is the physical interface on the docker host that has access to the above network

192.168.1.200/30 is a set of unused addresses on the network above. Note, this range MUST be different for each docker host you're using. Make sure this is outside your DHCP reservation range.

192.168.1.1 is the gateway for the network described above.

This command must be run on ALL nodes in the swarm that you want the service to float to.

Second step:

Run the following on one of your docker swarm manager nodes.

docker network create -d macvlan --scope swarm --attachable --config-from physical-config physical

Third step:

Alter your compose file that contains your Home Assistant to look like this

version: '3.7'
services:
  homeassistant:
    hostname: hass
    image: homeassistant/home-assistant:latest
    environment:
      TZ: America/New_York
    ports:
     - 8123:8123
     - 5353:5353 #homebridge
     - 21064:21064 #homebridge, default is 21063

    volumes:
     - /dockerVolumes/hass/:/config
    networks:
     - default
     - physical
    logging:
      driver: json-file

networks:
  default:
    driver: overlay
    attachable: true
  physical:
    external: true

The additional network in the "networks" section allows your Home Assistant container to break out of the docker side networking and listen for mdns messages on your lan.

Bonus step:

If your docker hosts are on a different network than your IoT devices (a good practice), you will need an avahi reflector to bridge those networks. For me that is a simple LXC container that roams my cluster.