It seems most media servers (Jellyfin, Emby, Plex, UMS…etc) recommend using docker host networking (-net=host) when running within a container so that it can see UDP traffic on port 1900 for DLNA discovery.
This is undesirable for a number of reasons, not the least of which is that a reverse proxy (Traefik, perhaps?) running in docker can’t talk to anything running directly on the host (or containers using the host network).
Below I’m using a macvlan network to put the Jellyfin container on the same network as my host so Traefik can properly proxy to it while still receiving broadcast network traffic.
- Create macvlan network that mirrors your hosts’ internal network
Warning: Assign containers static IPs that are outside your DHCP range (or use a smaller, non-overlapping CIDR range)docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=eno1 home-net
- Create Traefik container
Use macvlan network, assign static IP, use static MAC for DHCP address reservation:--net=home-net \
--ip=192.168.1.13 \
--mac-address=02:42:c0:a8:01:0d \
--label traefik.docker.network=home-net \
- Connect Traefik container to
bridge
network (or traefik docker network)
docker network connect bridge traefik
- Create Jellyfin container
Use macvlan network, assign static IP, use static MAC for DHCP address reservation:--net=home-net \
--mac-address=02:42:c0:a8:01:0f \
--ip=192.168.1.15 \
Publish DLNA port
-p 1900:1900/udp
Minimal Approach
The most simplistic approach to solving this problem seems to be using the net=host network, but creating a static rule in Traefik that points to the internal docker host/gateway IP (http://172.17.0.1:8096)…
# traefik.toml [backends] [backends.backend-jellyfin] [backends.backend-jellyfin.servers] [backends.backend-jellyfin.servers.server-1] url = "http://172.17.0.1:8096" [frontends] [frontends.jellyfin] backend = "backend-jellyfin" passHostHeader = true [frontends.jellyfin.routes] [frontends.jellyfin.routes.route-jellyfin-ext] rule = "Host:jellyfin.domain.tld" [frontends.jellyfin.headers] SSLRedirect = true SSLHost = "jellyfin.domain.tld" SSLForceHost = true STSSeconds = 315360000 STSIncludeSubdomains = true STSPreload = true forceSTSHeader = true frameDeny = true contentTypeNosniff = true browserXSSFilter = true customResponseHeaders = "X-Robots-Tag:noindex,nofollow,nosnippet,noarchive,notranslate,noimageindex" customFrameOptionsValue = "allow-from https://domain.tld"