cd ..
relayd(1)Mizuchi Labs Manualrelayd(1)

NAME

Ditching DNS Duct Tape

DATE

│2 min read

TAGS

#docker#swarm#devops#golang#traefik#selfhosted

At home I run plain Docker with Traefik in front of it. Routing to the containers works fine. The problem was outside it: the DNS records at Cloudflare, Hetzner, and the local Pi-hole went stale every time a container moved or I changed a routing label.

My workaround was cron jobs and scripts hitting the provider APIs. That worked until it did not. Every new container or label change meant another manual sync.

Why the cron jobs lost

Managing records across the home lab and multiple Proxmox environments meant I updated the same domain in three places whenever I moved a service around. I wanted one tool for this one task, not a bigger orchestration platform.

relayd is that tool, a DNS update daemon for Docker and Docker Swarm.

It listens to the Docker daemon through the socket, reads the labels you already put on containers for Traefik, works out what domain points where, and pushes the DNS update. No separate config file listing domains and IPs.

What it does

You pass credentials in through environment variables and mount the Docker socket so it can listen for events. The rest runs on its own.

A service that already has Traefik labels needs one more, relayd.enable=true:

services:
  whoami:
    image: traefik/whoami
    labels:
      - relayd.enable=true
      - traefik.enable=true
      - traefik.http.routers.whoami.rule=Host(`whoami.example.com`)

Without Traefik, list the names in a relayd.hosts label instead.

When the container comes up, relayd checks the current records and creates or updates the A or AAAA records. When the container goes down, it cleans them up.

The libdns tradeoff

Instead of writing per-provider API code, relayd speaks the libdns interfaces. Provider support comes from the libdns implementations, so the list is long without me writing per-provider code. Cloudflare, Hetzner, Route53, Pi-hole, and UniFi are on it, and the README has the rest.

The tradeoff: how a provider behaves depends on its libdns implementation. If a provider does something odd, the fix lives there, not in relayd.

I stopped logging into DNS portals for this. The setup instructions and full Docker Compose examples are in the repository.

relayd on GitHub →

SEE ALSO

relaydA set and forget DNS synchronization agent for Docker and Docker Swarm.