Documentation
Private networks: mDNS discovery
On a home or office LAN there is often no DNS server you control. The OCI backend
is still host-routed, so clients need a hostname that resolves to the box.
Everlock solves this with mDNS: any registry whose vhost ends in .local is
announced on the local link, so every machine on the network can reach the
registry by name with zero DNS configuration.
This is the counterpart to public DNS + ACME hosting: the same vhost mechanism, for the private-network case.
When to use this
Reach for mDNS instead of public DNS when:
- you run a build/CI box or a cluster on a trusted LAN and want a local registry reachable by name;
- there is no DNS server on the LAN, and you would rather avoid editing
/etc/hostson every machine; - you want the registry to resolve the same way from laptops, build agents, and nodes on the same network.
How it works
The mDNS frontend (frontend-mdns) is an announcement-only transport. It
publishes records that point clients at the HTTP frontend, where the registry is
served.
flowchart LR
OCI["registry instance (vhost: registry.local)"] -->|publishes .local vhost| REG["vhost registry"]
REG --> MDNS["frontend-mdns"]
MDNS -->|http service record| LAN[("local link")]
Client["docker / podman host"] -->|resolves registry.local| LAN
Client -->|pull / push registry.local| HTTP["frontend-http"]
HTTP --> OCIOn startup the mDNS frontend collects every .local vhost from the running
backends — registries included — detects a local IPv4 address, and announces each
one as an _http._tcp (or _https._tcp) service on the link. The service label
is derived from the hostname by stripping .local, so registry.local is
announced as the registry service.
Enabling it
Turn on the mDNS frontend and give the registry a .local vhost. The flags below
bootstrap a single default registry; for several registries use
config/oci-http.toml.
docker run -it --rm \ --network host \ cr.everlock.sh/everlock \ serve \ --frontend-mdns \ --backend-oci-http \ --backend-oci-http-vhost registry.local \ --backend-oci-http-store everlock-oci-local \ --admin-user admin --admin-password change-me
Once running, any machine on the LAN can resolve registry.local and reach the
registry at the HTTP frontend's port (for example registry.local:8080).
Configuring OCI clients for a .local registry
A .local name is served over plain HTTP, because publicly-trusted certificates
exist only for public hostnames. docker and podman treat localhost and
127.0.0.1 as plain-HTTP registries automatically, and they reach any other
plain-HTTP registry once you list it as insecure.
For Docker, add the registry to /etc/docker/daemon.json and restart the daemon:
{ "insecure-registries": ["registry.local:8080"] }
For Podman, add it to /etc/containers/registries.conf:
[[registry]] location = "registry.local:8080" insecure = true
Then log in and push as usual:
docker login registry.local:8080 docker push registry.local:8080/library/alpine:latest
Multiple registries, multiple names
Give each registry its own .local vhost and every one becomes independently
discoverable across the LAN — no DNS server, no per-machine host edits:
enabled = true [registries.builds] store = "builds-oci" vhosts = ["builds.local"] [registries.cache] store = "cache-oci" vhosts = ["cache.local"]
After a restart, builds.local and cache.local both resolve on the LAN. Access
stays scoped per registry via
http/oci/<instance> grants, so a name
being visible on the network still requires a grant to pull or push.
Tuning the announcement
The mDNS frontend exposes a few knobs:
| Flag / env | Default | Purpose |
|---|---|---|
--frontend-mdns / EVERLOCK_FRONTEND_MDNS | off | enable the frontend |
--frontend-mdns-interface / …_INTERFACE | all suitable | restrict announcements to one interface |
--frontend-mdns-ttl / …_TTL | 75 | record TTL in seconds |
When no .local vhosts are configured anywhere, the frontend has nothing to
publish and announces nothing.