Skip to Content
DocsCloud OSDomain Wizard

Domain Wizard

Phase С.2 of the GA roadmap: paste a Cloudflare API token, and 30 seconds later your apps live at *.example.com with a green padlock. The wizard collapses “DNS provider → A records → ACME → Caddy reload” into a single screen.

Walkthrough

  1. Open Settings → Networking → Domain wizard (or browse to /setup/domain).
  2. Provider — Cloudflare is the first shipped adapter. Route53 / Google Cloud DNS / ACME-DNS land in С.2.b.
  3. Token — paste your Cloudflare API token. (In Cloudflare: My Profile → API Tokens → Create Token → Edit zone DNS scoped to the relevant zones.)
  4. Zone & target — pick your zone (example.com). The NAT card shows the public IP and NAT type (Open / FullCone / Restricted / Symmetric) detected via STUN against stun.cloudflare.com:3478. If nat_type=open, single CTA “Use my public IP”. Otherwise two paths: “Use Quazzar tunnel (Pro+)” or “Configure port forwarding”.
  5. Confirm — preview of the records that’ll be written and the ACME wait.
  6. Run — SSE-backed step list (verify_token → create_records → configure_caddy → wait_acme → done).
  7. Done — green check + “Open https://example.com ” CTA.

Re-running

Idempotent — re-running for the same zone:

  • Skips DNS writes if the records already point at the right IP.
  • Skips the Caddy reconfigure if Caddy is already serving the domain.
  • Just re-runs the health check.

Useful when your public IP changes (DDNS auto-refresh is a follow-up).

How it works

internal/dnsprovider/ — Provider interface + registry cloudflare/ — first adapter (raw net/http; ~250 LOC) internal/netprobe/stun.go — RFC 5780 STUN probe (pion/stun/v2) internal/domainwizard/ — Service orchestrator (Probe / Start / Get / Subscribe) internal/proxy/routemgr/ — existing route manager; the wizard hands routes off here

The wizard never runs ACME itself — Caddy already does, via the existing routemgr integration. We just create the A record and poll the new hostname for a 200 as the success signal.

Grey-IP path

When nat_type != "open" the wizard offers two options:

  • Quazzar public tunnel (Pro+) — provisions a tunnel slot via internal/tunnel (frpc + CP-side relay). The A record points at the tunnel’s exit IP.
  • Port forwarding — auto-detected NAT type, a one-click UPnP attempt, plus a printable cheat sheet for common router models (best-effort; most users still need to follow generic instructions).

Plans

TierPublic IPTunnelBYO DNS
Free (Community)
Pro✅ (1 tunnel)
Team✅ (5 tunnels)
Enterprise✅ unlimited

License gates: domain_wizard (always on for everyone), public_tunnel (Pro+, count-capped). Both surfaced in /api/license/orbit-features.

API

POST /api/domainwizard/probe { provider, token } → { zones, public_ip, nat_type } POST /api/domainwizard/start { provider, token, zone, target_ip, mode } → 202 { run_id } GET /api/domainwizard/runs/:id → snapshot or SSE stream POST /api/domainwizard/runs/:id/cancel → 204

mode is "public_ip" | "tunnel" | "manual_ip"; the wizard sets it based on what you pick on the NAT card.

Admin-only — touches Caddy + DNS records. Audit-logged via the existing internal/audit channel.

Future providers

С.2.b drop adds Route53 + Google Cloud DNS + ACME-DNS adapters using the same Provider interface. Each new adapter is ~250 lines on average. The wizard UI auto-discovers registered adapters via dnsprovider.Available().