From de65dffc7c82fde3cc07bfd4ac9b693668ea3f61 Mon Sep 17 00:00:00 2001 From: Pankaj Rupani Date: Thu, 16 Apr 2026 10:59:36 -0400 Subject: [PATCH] docs: clarify avahi config for host vs bridge networking (#2014) * docs: clarify avahi config for host vs bridge networking The HomeKit plugin's MDNSServer binds UDP port 5353 directly on every network interface. With network_mode: host (the default), this conflicts with any system avahi-daemon running on the host, causing EADDRINUSE on all interfaces and silently breaking HomeKit mDNS discovery. The previous comments implied the host socket mount and SCRYPTED_DOCKER_AVAHI=true were equivalent alternatives ("choose one or the other"), which is misleading. Clarify the two distinct use cases: - Option A (host networking): SCRYPTED_DOCKER_AVAHI=true is required. The host avahi-daemon must be stopped. The /var/run socket mounts are incompatible with this mode. Add a note about mounting /etc/avahi/services to preserve host service advertisements. - Option B (bridge networking only): host socket mount works because Scrypted registers via D-Bus without binding 5353. Does not work with host networking. Fixes #2013 * fix: use SCRYPTED_DOCKER_AVAHI=true for avahi setup with host networking The install script was configuring the host avahi socket mount (Option B) while the template uses network_mode: host. This is a broken combination: the HomeKit plugin's MDNSServer binds UDP 5353 directly on every interface, conflicting with the system avahi-daemon, causing EADDRINUSE on all interfaces and silently breaking HomeKit mDNS discovery. Fix: when the user opts in to avahi, use SCRYPTED_DOCKER_AVAHI=true (Option A) instead. This makes Scrypted run its own internal avahi. Also stop/disable the host avahi-daemon so it doesn't conflict, and mount /etc/avahi/services:ro so Scrypted's avahi picks up existing host service definitions (e.g. Time Machine, Samba). Fixes #2013 --- install/docker/docker-compose.yml | 45 ++++++++++++++----- .../docker/install-scrypted-docker-compose.sh | 14 ++++-- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/install/docker/docker-compose.yml b/install/docker/docker-compose.yml index ded69993b..a36496cae 100644 --- a/install/docker/docker-compose.yml +++ b/install/docker/docker-compose.yml @@ -38,11 +38,28 @@ services: # LXC usage only # lxc - SCRYPTED_INSTALL_ENVIRONMENT=lxc-docker - # Avahi can be used for network discovery by passing in the host daemon - # or running the daemon inside the container. Choose one or the other. - # Uncomment next line to run avahi-daemon inside the container. - # See volumes and security_opt section below to use the host daemon. + # Avahi is used by the HomeKit plugin for mDNS advertisement. + # Two options depending on your network_mode: + # + # Option A — host networking (network_mode: host, the default): + # SCRYPTED_DOCKER_AVAHI=true is required. The HomeKit plugin binds + # UDP port 5353 directly; with host networking this conflicts with + # any system avahi-daemon. This variable makes Scrypted run its own + # internal avahi (via dbus) instead. + # You must stop/disable the host avahi-daemon before enabling this: + # sudo systemctl disable --now avahi-daemon avahi-daemon.socket + # To preserve host mDNS services (e.g. Time Machine), mount the + # host services dir into the container (see volumes section below). + # Do NOT use the /var/run/dbus or /var/run/avahi-daemon/socket + # volume mounts with this option — they are incompatible. # - SCRYPTED_DOCKER_AVAHI=true + # + # Option B — bridge networking only: + # Leave SCRYPTED_DOCKER_AVAHI commented out and instead mount the + # host avahi socket (see volumes section below). Scrypted will + # register mDNS services via the host avahi daemon over D-Bus + # without needing to bind port 5353 directly. + # This does NOT work with host networking — use Option A instead. # NVIDIA (Part 1 of 2) # nvidia runtime: nvidia @@ -70,14 +87,19 @@ services: # volume: # nocopy: true - # Uncomment the following lines to use Avahi daemon from the host. - # Ensure Avahi is running on the host machine: - # It can be installed with: sudo apt-get install avahi-daemon - # This is not compatible with running avahi inside the container (see above). - # Also, uncomment the lines under security_opt + # Avahi Option B (bridge networking only): use host avahi daemon. + # Scrypted registers mDNS services over D-Bus via the host socket. + # Requires avahi-daemon running on the host and apparmor:unconfined + # (see security_opt below). Not compatible with SCRYPTED_DOCKER_AVAHI=true + # or with host networking — see environment section above. # - /var/run/dbus:/var/run/dbus # - /var/run/avahi-daemon/socket:/var/run/avahi-daemon/socket + # Avahi Option A (host networking + SCRYPTED_DOCKER_AVAHI=true): + # Mount host avahi service definitions so Scrypted's internal avahi + # advertises them (e.g. Time Machine, custom services). + # - /etc/avahi/services:/etc/avahi/services:ro + # Default volume for the Scrypted database. Typically should not be changed. # The volume will be placed relative to this docker-compose.yml. - ./volume:/server/volume @@ -89,8 +111,9 @@ services: # lxc - /root/.scrypted/.env:/root/.scrypted/.env # lxc - /mnt:/mnt - # Uncomment the following lines to use Avahi daemon from the host - # Without this, AppArmor will block the container's attempt to talk to Avahi via dbus + # Required for Avahi Option B (bridge networking + host avahi socket). + # Without this, AppArmor blocks the container's D-Bus access to avahi. + # Not needed for Option A (SCRYPTED_DOCKER_AVAHI=true). # security_opt: # - apparmor:unconfined devices: [ diff --git a/install/docker/install-scrypted-docker-compose.sh b/install/docker/install-scrypted-docker-compose.sh index 87d5924b7..1824ac607 100755 --- a/install/docker/install-scrypted-docker-compose.sh +++ b/install/docker/install-scrypted-docker-compose.sh @@ -116,12 +116,20 @@ then fi fi -readyn "Install avahi-daemon? This is the recommended for reliable HomeKit discovery and pairing." +readyn "Enable avahi for HomeKit discovery? This is recommended for reliable HomeKit pairing." if [ "$yn" == "y" ] then + # With network_mode: host (the default), the HomeKit plugin binds UDP port + # 5353 directly. This conflicts with a running system avahi-daemon. + # The correct setup is SCRYPTED_DOCKER_AVAHI=true, which makes Scrypted + # run its own internal avahi. The host avahi-daemon must be stopped. sudo apt-get -y install avahi-daemon - sed -i 's/'#' - \/var\/run\/dbus/- \/var\/run\/dbus/g' $DOCKER_COMPOSE_YML - sed -i 's/'#' - \/var\/run\/avahi-daemon/- \/var\/run\/avahi-daemon/g' $DOCKER_COMPOSE_YML + sed -i 's/'#' - SCRYPTED_DOCKER_AVAHI=true/- SCRYPTED_DOCKER_AVAHI=true/g' $DOCKER_COMPOSE_YML + # Uncomment the avahi services mount so Scrypted's internal avahi picks up + # host service definitions (e.g. Time Machine, Samba). + sed -i 's/'#' - \/etc\/avahi\/services/- \/etc\/avahi\/services/g' $DOCKER_COMPOSE_YML + # Stop and disable the host avahi-daemon — Scrypted now owns port 5353. + sudo systemctl disable --now avahi-daemon avahi-daemon.socket 2>/dev/null || true sed -i 's/'#' security_opt:/security_opt:/g' $DOCKER_COMPOSE_YML sed -i 's/'#' - apparmor:unconfined/ - apparmor:unconfined/g' $DOCKER_COMPOSE_YML fi