Documentation
Private networks: mDNS discovery
On a home or office LAN there is usually no DNS server you control and no public
domain — but the image backend is still host-routed, so clients need a hostname
that resolves to the box. Everlock solves this with mDNS: any image instance
whose vhost ends in .local is announced on the local link, so every device on
the network can reach it by name with zero DNS configuration. The same instances
are also advertised over SSDP/UPnP, so they show up as clickable entries in
Windows "Network".
This is the counterpart to public DNS + ACME hosting: same vhost mechanism, opposite environment.
When to use this
Reach for mDNS instead of public DNS when:
- you are behind NAT on a typical home line (Fritz!Box and similar) and don't want to expose anything to the internet;
- there is no DNS server on the LAN, or you don't want to edit
/etc/hostson every device; - you want the gallery to "just appear" on phones and laptops on the same network;
- you are running several galleries and want each reachable by its own name across the LAN.
How it works
The mDNS frontend (frontend-mdns) is a separate, announcement-only transport.
It does not serve traffic itself — it publishes records that point clients at the
HTTP frontend.
flowchart LR
IMG["image instance (vhost: photos.local)"] -->|publishes .local vhost| REG["vhost registry"]
REG --> MDNS["frontend-mdns"]
MDNS -->|http / https service| LAN[("local link")]
MDNS -->|SSDP / UPnP device| LAN
Phone["phone / laptop / TV"] -->|resolves photos.local| LAN
Phone -->|request to photos.local| HTTP["frontend-http"]
HTTP --> IMGOn startup the mDNS frontend:
- collects every vhost ending in
.localfrom the running backends (image instances included); - detects a suitable local IPv4 address (skipping loopback and link-local), or
uses the one named by
--frontend-mdns-interface; - announces each
.localhost as an_http._tcpor_https._tcpservice —_https._tcponly when the HTTP frontend has HTTPS enabled, which for a purely local setup it usually does not; - additionally advertises each
.localvhost over SSDP/UPnP as a UPnP Basic device, so it appears as a clickable entry in Windows "Network" that opens the gallery in the browser.
The instance label is derived from the hostname by stripping .local — so
photos.local is announced as the photos service on the link.
Enabling it
Turn on the mDNS frontend and give your image instance a .local vhost. The
backend flags shown here bootstrap a single default instance; for several
galleries use config/image-http.toml.
./everlock serve \ --frontend-mdns \ --backend-image-http \ --backend-image-http-vhost photos.local \ --backend-image-http-store family-images \ --admin-user admin --admin-password change-me
Once running, any device on the LAN can open:
http://photos.local:8080/
Multiple galleries, multiple names
This is where mDNS shines for a household. Give each instance its own .local
vhost and every one becomes independently discoverable — no DNS server, no
certificates, no /etc/hosts edits on any device:
enabled = true [instances.family] store = "family-images" vhosts = ["photos.local"] [instances.kids] store = "kids-images" vhosts = ["kids.local"] [instances.archive] store = "archive-images" vhosts = ["archive.local"]
After a restart, photos.local, kids.local, and archive.local all resolve
across the LAN and each appears as its own entry in Windows "Network". Access is still scoped
per instance via http/image/<instance>
grants, so a .local name being visible does not mean it is open — a user still
needs at least Reader to log in.
.local vhosts are always plain HTTP
A .local name can never hold a publicly-trusted TLS certificate, so Everlock
never tries to issue one for it. localhost, *.local, and raw IPs are
explicitly skipped by ACME and served over plain HTTP even when an HTTPS listener
is configured. This is exactly what you want on a trusted LAN: no certificate
warnings, no setup.
If an instance carries both a .local vhost and a public one, the public name is
ACME-managed while the .local name stays plain HTTP — the frontend decides
per-host. In that mixed case, remember that
public_url derives from the
first vhost, so list the routable public name first if you want share links to
use it.
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 |
--frontend-mdns-instance / …_INSTANCE | everlock | label for non-HTTP service records (e.g. SSH) |
--frontend-mdns-ipv6 / …_IPV6 | off | reserved — IPv6 announcements are not yet implemented and the flag is currently ignored with a warning |
If no .local vhosts are configured, the frontend logs a warning and announces
nothing — there is simply nothing for it to publish.
SSDP / UPnP specifics
Each .local vhost is exposed as a UPnP Basic device. That is what makes a
gallery appear under Windows "Network" without typing a URL. The device's
presentation URL points at http://<vhost>:<port> so the client sends the
correct Host header and the request routes to the right instance. SSDP
advertisement is limited to .local vhosts; public hostnames are not announced
this way.