Docker/Homekit + Bridge/Unifi/IoT Network/HTTPS reverse proxy

After quite a bit of research/troubleshooting i wanted to share how i was able to get Home Assistant working in Docker setup for bridge networking with a private IoT network running on Unifi hardware behind an nginx reverse proxy. It is a bit complicated, but has been rock solid.

Starting on the UNIFI side

  1. create your IoT network and IoT wifi (if you have not already) and join your devices to it
    (As an optional step, disable the network from being able to communicate out to the internet)
  2. Once that is setup, on the network where you have your docker host and your IoT network check the the IGMP snooping and Multicast DNS checkboxes.
  3. In the wifi configurations for your regular-use wifi and your IoT wifi check the Multicast Enhancement box.

The below docker-compose.yml file does the following things:

  1. sets up an nginx-proxy container
  2. sets up a container that will dynamically update the docker config if you want to add more containers to be proxied
  3. sets up a container that will automatically take care of ssl certificates using lets encrypt
  4. sets up a mdns relay
  5. sets up a homeassistant container

Docker Notes

First create the “web” network for docker
docker network create -d bridge web

Next, find the bridge adapter identifier
docker network ls|grep web

Use the identifier to get the NIC (change identifier to what you got in the previous step)
ip addr show|grep identifier

Get the non-docker NIC (change 192.168.x.y to your ip address)
ip addr show|grep 192.168.x.y

Using this docker-compose.yml change the volume paths/fqdn/nics to match your setup

version: '3.9'

services:
  nginx-proxy:
    image: nginx:alpine
    container_name: nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /data/web/nginx-proxy/conf:/etc/nginx/conf.d
      - /data/web/nginx-proxy/certs:/etc/nginx/certs
      - /data/web/nginx-proxy/vhost:/etc/nginx/vhost.d
      - /data/web/nginx-proxy/well-known:/usr/share/nginx/html/.well-known
    networks:
      - web
    restart: always

  nginx-proxy-gen:
    image: nginxproxy/docker-gen
    container_name: nginx-proxy-gen
    environment:
      - RESOLVERS=192.168.1.1 valid=300s
    command: -notify-sighup nginx-proxy -watch /etc/nginx-proxy-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
    volumes_from:
      - nginx-proxy
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - /data/web/nginx-proxy/nginx.tmpl:/etc/nginx-proxy-gen/templates/nginx.tmpl
    depends_on:
      - nginx-proxy
    networks:
      - web
    restart: always

  acme-companion:
    image: nginxproxy/acme-companion
    container_name: nginx-proxy-acme
    environment:
      - NGINX_DOCKER_GEN_CONTAINER=nginx-proxy-gen
      - NGINX_PROXY_CONTAINER=nginx-proxy
    volumes_from:
      - nginx-proxy
    volumes:
      - /data/web/nginx-proxy/acme.sh:/etc/acme.sh
      - /data/web/nginx-proxy/well-known:/usr/share/nginx/html/.well-known
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - web
    restart: always

  home-assistant:
    image: homeassistant/home-assistant
    container_name: home-assistant
    environment:
      - VIRTUAL_HOST=my.domain.fqdn
      - VIRTUAL_PORT=8123
      - LETSENCRYPT_HOST=my.domain.fqdn
    volumes:
      - /data/web/home-assistant/config:/config
      - /etc/localtime:/etc/localtime:ro
    ports:
      - 8123
      - 21063:21063
    networks:
      - web
    restart: always

  home-assistant_mdns-repeater:
    image: angelnu/mdns_repeater
    container_name: home-assistant_mdns-repeater
    network_mode: host
    environment:
      - hostNIC=myNIC
      - dockerNIC=myDockerBridgeNIC
    restart: always

networks:
  web:
    driver: bridge
    name: web
    external: true

once your docker containers are up, go through the home assistant setup steps as necessary and then in integrations you should see autodiscovered devices populating. (You may have to manually add the homekit device integration, i was impatient and didn’t want to wait for the homekit devices i was adding to show up, so i’m not sure if you will have to manually add them)

Once your devices are added into home assistant, the next step is to create the bridge in the configuration.yml - you will have to add the include/excludes as you see fit (i included the light domain for this example). Also, make sure the port for the bridge is the same as what you published in the docker-compose.yml above (i used the default of 21063) and change 192.168.x.y to the ip address of your docker host

homekit:
  advertise_ip: "192.168.x.y"
  name: HA Bridge
  port: 21063
  filter:
    include_domains:
      - light

Once you reload home assistant, you should see a notification that there is a bridge and it will give you the QR code that you can use to add the bridge to your homekit app.

References:
https://community.home-assistant.io/t/unable-to-setup-homekit-bridge/235520/12
https://github.com/home-assistant/core/issues/15692#issuecomment-1571768731
https://www.home-assistant.io/integrations/homekit/
https://github.com/nginx-proxy/nginx-proxy/
https://github.com/nginx-proxy/acme-companion/
https://github.com/acmesh-official/acme.sh/