Thursday, 14 May 2026

Using hosts mDns/Avahi for Docker images

I’ve been trying to run Docker containers at home with one specific requirement: they need to resolve .local hostnames via mDNS so I can avoid the headache of managing static IPs.

The catch is that many of the containers I use aren't mine. They are standard images from the community, and I didn't want to maintain my own forks or modify their internal configurations just to get networking to work. I wanted a way to make mDNS "just work" from the host side.

Since I’m not a "networking guy," this proved more difficult than I expected. I spent a few evenings asking AI for advice and manually punching in commands based on its suggestions, but that didn't go anywhere.

Enter Gemini CLI and --yolo

After a bit of frustration, I decided to eliminate the middleman (me) and let the AI work directly on the system. I spun up a fresh, empty VM, installed the Gemini CLI, and spec'd exactly what I wanted.

I asked the AI what permissions it needed to achieve the goal autonomously in --yolo mode, which turned out to be passwordless sudo access. I granted the privileges and let it rip. After a bit of processing, it produced a working solution that I could then safely apply to my actual host.

TASK.md

Task: Configure Docker for mDNS/Avahi Resolution

Objective

Configure the Linux VM so that Docker containers can resolve .local mDNS addresses (specifically roope.local) without modifying existing container images.

Steps

  1. Logging: Maintain mdns_setup_log.txt with all actions, including failures.
  2. Host Setup:
    • Install/Ensure avahi-daemon and systemd-resolved are active.
    • Configure systemd-resolved to act as a bridge for mDNS to standard DNS.
  3. Docker Setup:
    • Identify Docker bridge IP (docker0).
    • Update /etc/docker/daemon.json to use the host’s bridge IP as the DNS server.
  4. Validation:
    • Verify roope.local resolution from an unmodified alpine container.
    • Verify connectivity via ping.
  5. Output: Write the successful configuration steps to SOLUTIONS.md.

Required Permissions

  • Sudo access (NOPASSWD) for system configuration.
  • Docker CLI access.
  • Workspace write access.

 SOLUTION.md

Solutions: Docker mDNS/Avahi Resolution

To enable Docker containers to resolve .local mDNS addresses without modifying images, the following steps were taken:

1. Configure systemd-resolved

A drop-in configuration was created to enable mDNS support and allow the stub listener to respond on the Docker bridge IP.

File: /etc/systemd/resolved.conf.d/mdns.conf

[Resolve]
MulticastDNS=yes
DNSStubListenerExtra=172.17.0.1

2. Enable mDNS on Network Interfaces

mDNS was enabled on the main network interface (ens18) to allow systemd-resolved to send/receive mDNS packets.

File: /etc/systemd/network/10-netplan-ens18.network.d/override.conf

[Network]
MulticastDNS=yes

3. Configure Docker

Docker was configured to use the host’s systemd-resolved stub listener (on the bridge IP) as the default DNS server for containers.

File: /etc/docker/daemon.json

{
  "dns": ["172.17.0.1"]
}

4. Services Restarted

The following services were restarted to apply changes:

sudo systemctl restart systemd-networkd
sudo systemctl restart systemd-resolved
sudo systemctl restart docker

5. Validation

Resolution was verified from an unmodified alpine container:

sudo docker run --rm alpine ping -c 1 roope.local

Output:

PING roope.local (192.168.0.106): 56 data bytes
64 bytes from 192.168.0.106: seq=0 ttl=63 time=0.714 ms

A Note on Security

I can't stress this enough: do not run AI in a production environment, especially with root privileges and --yolo mode enabled. Don't even do it on your primary development machine.

By using a throwaway VM, the risks were zero. If the AI decided to rm -rf / or wipe the partition, I'd just revert to a snapshot and try again. The absolute worst it could do was try to flood my LAN, which is a much smaller headache than a deleted home directory.