Skip to main content
DNZ manages reverse proxies as well as DNS. When your DNS lives somewhere else (Cloudflare, your registrar, your own servers) and you only want the proxies, start DNZ with --proxy-only: no DNS server, and none of its pages, commands or tools.
The same as DNZ_PROXY_ONLY=true, or at the top of the config file:
It is the same dnz and the same database. Starting the same data folder without --proxy-only later turns DNS on, and everything made meanwhile is still there.

In one container

docker-compose.proxy-only.yml
At its first start (no proxy yet) DNZ turns proxying on, makes a DNZ Proxy called Default and runs a node of it in the same container, which serves your routes on ports 80 and 443. Open http://<host>:8080, create the admin (two steps: the admin and the first division), connect Cloudflare if your domains are there (optional: Skip goes straight in) and add a route under Proxy → Routes. More nodes on other servers join the same proxy as always (DNZ Proxy). To use HTTP/3 for visitors, turn it on at the entry point, uncomment the 443:443/udp line above and open UDP 443 on the host’s firewall. On a Linux server without Docker, the installer sets up the service the same way:

What stays

  • Proxies: every kind, nodes, routes (HTTP, TCP, UDP), groups, batch edit, route history, configuration as code, upstreams (health checks, servers from a DNS name), middlewares, rules, the WAF, the firewall, Under attack, rate limits, the waiting room, sign-in, caching, analytics, request logs, visitors and status pages.
  • Certificates: ACME (Let’s Encrypt, ZeroSSL, any ACME CA), uploads, the private CA, DNZ’s own certificate (Settings → General → Certificate).
  • Operations: Uptime and the public status page, proxy alerts, notifications, the cluster, backups, the audit log, diagnostics, Prometheus.
  • Access: users, roles, divisions, API tokens, two-factor, sign-in with Google, the CLI, the CLI in the browser, MCP.
  • Cloudflare: connections per division and the Cloudflare zones (DNS → Zones): records, traffic, SSL/TLS, DNSSEC, cache purge, tunnels.

What is off

  • Port 53, and DNS over TLS, HTTPS (/dns-query), QUIC and HTTP/3. HTTP/3 for visitors is DNZ Proxy’s and stays.
  • Local zones and records, changes and approvals, views, forwarding, filtering, threats, DHCP & IPAM, typo help, and decoy names, which are turned on per local zone.
  • The query log, Live Capture, Query Explain.
  • DNS replication (primary and secondary servers); proxy-only servers have standbys instead.
  • DNS alerts (upstreams, NXDOMAIN spikes, domain expiry, the daily summary) and DNS metrics.
Their pages are gone from the menu (their addresses lead to the Overview), their API endpoints answer 404 with DNS is off on this server (--proxy-only), the CLI prints the same, and MCP lists none of their tools. The Overview opens on Proxy. Local zones a server had before it was started with --proxy-only are kept, but not served or shown.

What works differently

  • Name checks: origins that can be reached without the proxy and exposed files are checked; CNAMEs pointing at targets that are gone or can be claimed are not, since DNZ holds no zones here.
  • Private CA’s ACME server: http-01 works as always. For dns-01 DNZ answers nothing itself: the client publishes the TXT record in your DNS, and DNZ reads it through the server’s resolvers.
  • Log push: only DNZ Proxy’s request log can be pushed.

DNS records for your routes

DNZ answers no DNS here, so a route’s name has to point at the proxy where its DNS is:
  • With a Cloudflare connection (Settings → Integrations), Keep its DNS records on Cloudflare in the route dialog writes them: one A/AAAA record per address of the proxy (for a DNZ Proxy, its healthy nodes that aren’t drained), in the name’s Cloudflare zone, DNS only, with the comment Synced from DNZ. When a node comes or goes the records follow within about a minute and a half (a node that flaps doesn’t rewrite them), and they go with the route.
  • The route dialog’s hostname field offers the connected accounts’ zones as you type and tags a name in one of them new (records will be added there), or with the record types DNZ already keeps for it; a name in none of them is no zone and can still be routed. Without a connection every name is no zone. dnz proxy hosts <proxy> [name] lists the same.
  • Records made on Cloudflare by hand for the same name are never changed: the route says so, and the name keeps pointing where it did.
  • Proxied by Cloudflare, under the same option, writes them through Cloudflare’s proxy instead: visitors reach Cloudflare, which forwards them to the proxy. Trust Cloudflare’s addresses on the entry point (its forwarded-from list), or the firewall, rate limits and logs see Cloudflare instead of the visitor; DNS-01 proves names behind it most reliably. Switch it on an existing route in its dialog, or with dnz proxy routes cloudflare <proxy> <host> --proxied on|off.
  • Without one (or for a name in no connected zone), the route dialog and dnz proxy routes add show the addresses to point the name at yourself.
Read-only proxies (a Caddy or Traefik DNZ doesn’t configure) write their names’ records on Cloudflare the same way.

Certificates

Automatic certificates never use DNZ’s own zones here. Prove names with (Proxy → Certificates) picks the order:
Wildcards (*.example.com) always take DNS-01; without a way for it, the route dialog says how to add one. See Certificates.

Upstreams from a DNS name

DNZ looks an upstream’s name up through the server’s own resolvers (/etc/resolv.conf), with their TTLs. Names each proxy looks up itself (Docker Swarm’s tasks.<service>) work as always.

A standby

A second proxy-only DNZ, on another server with its own database, can hold a copy of this one and take over when it is gone.
1

Make its join code

On this server: High availability → Standby → Add standby, or:
Give this server’s address as the standby reaches it. DNZ shows the join code once.
2

Follow from the standby

On the second server (a fresh DNZ started with --proxy-only): High availability → Standby → Follow a primary and paste the code, or:
The standby then copies everything every 30 seconds: proxies, routes, upstreams, middlewares, nodes (with their tokens), certificates with their keys, the private CA, ACME accounts, DNS credentials, Cloudflare connections, notifications, uptime monitors, incidents and their history, users and roles. Each server keeps its own sessions, audit log and diagnostics. An unchanged copy costs one small request. While it follows, the standby leaves the install’s jobs to its primary, so nothing is done twice: alerts and reports, uptime and name checks, renewing and signing certificates, writing records on Cloudflare, updating nodes and scheduled backups. It starts doing them once it is promoted or takes over.
The join code carries a secret: anyone with it can copy the server, keys included. When the two servers talk over the internet, give the standby an https:// address of the primary.
While it follows, the standby is read-only (it refuses changes and says so) and tells DNZ Proxy nodes that call it where the primary is. Its own node serves no traffic by default. Serve traffic while standby (on its Standby page, or dnz standby serve on) makes that node one more node of the primary’s proxy: both hosts take visitors, and nothing stops when the standby takes over. DNS, or the records on Cloudflare, then answer with the standby’s address too.

Swapping the two while the primary runs

Moving the primary to new hardware, or upgrading it: take over from the standby (Take over, or dnz standby take-over --url <this server's address>). The primary stops taking changes, sends its last copy and follows the standby from then on; the standby becomes the primary, with the old primary and the other standbys as its standbys. Standbys and DNZ Proxy nodes that still call the old primary are told where the new one is and go there by themselves. If the standby can’t finish, the old primary is the primary again.

When the primary is gone

Promote the standby (Promote, or dnz standby promote). It takes changes from then on. The DNZ Proxy nodes know where it is: the primary lists its standbys to them, and a node that can’t reach its DNZ three times in a row tries the next one, so they move by themselves and keep serving their last configuration meanwhile. If the old primary comes back, stop it: two primaries would each think they manage the nodes. To make it a standby of the new one, start it fresh (an empty data folder) and follow the new primary. Both servers must run the same DNZ version, or the standby a newer one: a standby refuses a copy from a newer primary until it is updated.

A cluster

Every server of a cluster runs in the same mode: a server started with --proxy-only next to full ones (or the other way) refuses to start and says why.