External-DNS for plain Docker hosts

DNS records that follow your containers.

DockRoute watches your Docker containers, reads dockroute.* labels and keeps your DNS provider in sync. Your Compose file is the source of truth. No Kubernetes required.

MIT licensed · single container · Cloudflare DNS + Tunnel today, more providers on the route

compose.yamlwatching
services:
  whoami:
    image: traefik/whoami
    labels:
      dockroute.enabled: "true"
      dockroute.hostname: "whoami.example.com"
      dockroute.tunnel.service: "http://whoami:80"

create CNAME whoami.example.com → tunnel

create TXT _dockroute-cname.whoami.example.com

route published — in sync

The route

  1. Docker Compose

    your labels

  2. DockRoute

    watch + reconcile

  3. DNS provider

    records + routes

  4. Your domain

    live

How it works

From Docker labels to live DNS.

01

Label your containers

Add dockroute.enabled and dockroute.hostname to any service in your Compose file. That label is the whole contract — no sidecar config, no templates.

02

DockRoute watches Docker

It streams container lifecycle events — start, die, stop, destroy — from the Docker socket, with a periodic full resync as a safety net. Desired state always comes from what is actually running.

03

Records reconcile

The provider diffs desired against actual and creates, updates or removes records — plus Cloudflare Tunnel ingress routes when you ask for them.

Safety model

It never alters what it cannot prove it manages.

Your DNS zone usually holds more than your containers. DockRoute treats everything it did not create as someone else's — including records made by another DockRoute instance.

owned

Ownership is proven, not assumed

Every record DockRoute creates gets a companion TXT record carrying its owner id — the same registry model as Kubernetes ExternalDNS.

conflict → skipped

Unowned records are untouchable

A record without proof of ownership is never modified, deleted or adopted. Conflicts are logged and skipped, under every policy.

sync policy

Cleanup only when you allow it

Orphaned records are removed only under the default sync policy, and only when ownership is proven. upsert-only and create-only never delete.

preserved

Your tunnel rules stay yours

Tunnel ingress rules DockRoute did not create are preserved verbatim, in their original order, ahead of managed rules.

Configuration

One more service in your stack.

DockRoute runs as a single container next to your services. Point it at the Docker socket, pick a provider, and it starts reconciling. Start with the log provider for a zero-credential dry run.

Full configuration reference →
compose.yaml
services:
  dockroute:
    image: ghcr.io/dockroute/dockroute:latest
    environment:
      DOCKROUTE_PROVIDER: cloudflare
      DOCKROUTE_OWNER_ID: home-lab
      CLOUDFLARE_API_TOKEN: ${CLOUDFLARE_API_TOKEN}
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

Simple enough for a homelab. Reliable enough for your SaaS.

Homelab

Expose services without the ritual

Publish through an existing Cloudflare Tunnel with one label — no port forwarding, no dynamic-DNS scripts, no hand-edited zone files. Take a service down and its records follow.

Small teams

Compose in production, safely

Sync policies, per-instance owner ids and a domain allowlist let several stacks share one zone without stepping on each other — or on the records you manage by hand.

Open source

MIT licensed, built in the open.

DockRoute borrows its safety model from Kubernetes ExternalDNS and applies it where most homelabs actually live: plain Docker hosts. Providers are pluggable behind one interface — Cloudflare works end to end today, and the planner, ownership rules and tests are provider-agnostic so new ones slot in cleanly.

Eating our own dog food

This site runs from a Docker Compose stack in a homelab, and the DNS record you used to reach it was published by DockRoute itself — from a dockroute.hostname label on the site's own container.

Your services know where to go.

Start with the dry-run provider — no credentials, no risk — and see the records DockRoute computes before it ever touches a zone.