Dual-Run: Zone Push to Route53 / Cloudflare / Bunny
Paid tier. Config-file / GitOps driven.
Nexus can continuously export each service's effective zone to a big-cloud DNS provider and keep it in sync. You run Nexus and a provider secondary at the same time. This gives you two things:
- A zero-risk path to migrate into Nexus. Point Nexus at your members, turn on dual-run, and watch the provider zone fill in with the same answers Nexus is serving. When you're confident, cut your
NSrecords over to Nexus on your schedule — with the provider zone still there as a safety net. No flag day, no "delete the old thing and hope." - An answer to the one question every buyer asks: "what if Nexus falls over — it's my DNS." If every Nexus node dies, the provider keeps answering from the last records Nexus pushed. Your domain still resolves.
octoDNS does this kind of export as an external batch CLI. Nexus does it inside the daemon, live, off the same health signals that drive resolution.
What gets pushed (read this twice)
The pushed zone is a degraded static approximation, not a mirror of Nexus:
- Every currently-healthy, enabled member becomes a low-TTL
A/AAAArecord. It's a flat round-robin. - Apex
NSrecords you configure, and (future)TXTrecords. Exception: Bunny does not allow custom apex NS (it always serves its own), so the Bunny provider silently skips them — on Bunny the fallback delegation is Bunny's own nameservers, which is what you want anyway. - No geo-routing, no filter chains, no weighting, no RUM, no rollouts. None of the smart routing survives the export — the provider can't do any of it.
So dual-run answers exactly one question: "will my domain resolve if Nexus is gone?" It is a fallback, not a replica. While Nexus is up and authoritative, your clients get the smart answers; the provider zone only matters if you've delegated to it or if you fail over to it.
When Nexus is down, pushes stop. The provider records freeze at the last values Nexus pushed. That freeze is the entire point: stale-but-resolving beats SERVFAIL.
Configure
Add a zonesync block. Credentials are never in this file (or the database) — they come from the environment.
zonesync:
enabled: true
debounceSec: 15 # coalesce bursts of health changes (default 15s)
intervalSec: 600 # full drift-repair sweep (default 600s)
apexNS:
- ns1.yourprovider.net
- ns2.yourprovider.net
providers:
- name: bunny1 # identifier; also selects the env-var group
type: bunny # bunny | cloudflare | route53
zone: example.com # the provider-side zone
- name: cf1
type: cloudflare
zone: example.comCredentials (environment only)
For a provider named <NAME>, upper-cased:
| Provider | Environment variables |
|---|---|
bunny |
NEXUS_ZONESYNC_<NAME>_TOKEN (Bunny AccessKey) |
cloudflare |
NEXUS_ZONESYNC_<NAME>_TOKEN (scoped token, Zone:DNS:Edit) |
route53 |
NEXUS_ZONESYNC_<NAME>_KEYID + NEXUS_ZONESYNC_<NAME>_SECRET |
Example for the bunny1 provider above, in /etc/gslb/env:
NEXUS_ZONESYNC_BUNNY1_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxA provider whose credentials are missing is logged and skipped; the rest keep running.
Curated providers. Bunny, Cloudflare, and Route53 are supported because they're what we and our users run. There is deliberately no 90-provider plugin registry — each provider is a few hundred lines and adds binary size. Need another? Ask; it's a small addition.
How it stays in sync
- On every member health transition (debounced by
debounceSec), Nexus re-renders the fallback zone and pushes the diff. - Every
intervalSec, it does a full reconcile as drift repair — so a record someone changed by hand in the provider console is corrected. - Nexus only touches records under names it manages. Other records in the provider zone (your
MX, unrelated subdomains) are never modified or deleted.
Migrating into Nexus, step by step
- Create your pools, members, and services in Nexus. Leave your existing DNS authoritative for now.
- Turn on
zonesyncpointing at a provider zone you control (can be the same provider that's currently authoritative). - Watch the provider zone converge to Nexus's answers (see below).
- When you trust it, delegate the domain to Nexus's nameservers.
- Keep dual-run on permanently as your disaster fallback.
Check status
- CLI:
gslbctl zonesync status - API:
GET /api/v1/zonesync/status(requirespools:read) - Web UI: the Dual-Run Zone Push card on the cluster admin page — a green/red dot, record count, last push time, and last error per provider.
$ gslbctl zonesync status
Dual-run zone push (zonesync) status
────────────────────────────────────────────────────────────────────
Enabled: yes
PROVIDER RECORDS LAST PUSH LAST ERROR
────────────────────────────────────────────────────────────────
bunny1 7 2026-07-05 14:41:02 —
cf1 7 2026-07-05 14:41:02 —
A non-empty LAST ERROR means the last push to that provider failed (bad token, zone not found, API outage). Nexus keeps retrying on the interval; the provider's records simply stop updating until it recovers.