Local URLs
How the .test domain system works, how to enable it, and what to do when it breaks.
How it works
With local URLs on, you visit http://shop.test instead of
http://localhost:8081. Three pieces make it work:
- A Traefik container on host port 80 with a file provider. For each project, there's a route mapping
Host(<name>.<tld>)tohost.docker.internal:<APP_PORT>. - A dnsmasq container on
127.0.0.1:5354answeringaddress=/.<tld>/127.0.0.1, so anything ending in.<tld>resolves to your machine. - A small file at
/etc/resolver/<tld>that tells macOS to use that dnsmasq container for any lookup ending in.<tld>. Port 5354 is used so it doesn't collide with Herd or Valet on :53.
Step 3 is the only one that needs your password. Once. After that, every project you
ever create gets its own .<tld> URL with no further prompts.
Enable or change the TLD
Go to Settings, then Local URLs.
- Enable toggle. Turning it on installs the Traefik + dnsmasq containers and writes the resolver file. The first time, you'll get one macOS password prompt.
- TLD input. Defaults to
sail. You can use any short alphanumeric string.testis the most common choice. Avoid real TLDs (com,net) since they'd hijack real DNS. - Resync. Rebuilds the proxy config for every project, restarts the containers, and re-checks the resolver. Useful if something feels off.
Disabling local URLs tears all of that down. Project URLs fall back to localhost:<port>.
HTTPS
With the HTTPS toggle on, the app generates a local certificate authority, installs it
into your macOS login keychain, and produces a wildcard cert for *.<tld>.
Traefik switches to serving on :443, and your browser stops complaining.
The CA is local to your machine and only trusted by your account. Nothing leaves the laptop.
When things break
If a container got removed or the resolver file went missing, the app notices and surfaces a "Local URLs need repair" toast. Click Fix it and it runs the full resync (which may need your password to re-write the resolver file).
Common causes:
- Docker Desktop was reset. All containers are gone. Run Resync.
- Port 80 already in use by Apache, Nginx, Herd, or another service. Stop the conflicting service or change Traefik's port (Resync detects the conflict).
- Stale resolver file from a previous install of Valet or Herd. Settings, then Resync rewrites it.