Standalone domains have the same features as normal app domains: DNS checks, go-live and automatic DNS records, certificate issuance, domain doctor, redirects, maintenance mode, basic auth, WAF and rate limiting, custom error pages, search visibility, and traffic controls (headers, forwarders, country rules, caching).
Add one from the dashboard
Open Domains, click Add domain, and pick Proxy to a port or URL. Type the domain, pick the target, and check the live preview (for examplehttps://tools.example.com -> http://127.0.0.1:3000). On Linux the port picker lists the ports something is listening on.
Advanced options holds the rest: TLS to the target (with certificate verification on or off for self-signed upstreams), the TLS server name, the Host header sent upstream (keep the visitor’s, use the target’s, or a fixed name), websockets (on by default), connect and read timeouts, and a path prefix to strip before proxying.
After you add it, the dialog shows the exact DNS record to create and the live DNS status, then runs go-live: with a connected DNS provider the record is created for you.
In the Domains list a standalone domain shows an Unlinked badge with its target in the App column. Its actions menu edits the target or removes the domain; the domain page carries the same tabs as any other domain.
Add one from the CLI
add prints the DNS record to create. Every per-domain command takes _standalone as the app name for a standalone domain:
Safety rules
A standalone domain lets anyone on the internet reach whatever the target is, so the API is strict about what it accepts:- Creating, editing or removing one needs the
write:sensitiveability, the same tier as firewall rules. Every change is recorded in the audit log and shows in the domain’s activity timeline. - Cloud metadata and link-local addresses (
169.254.0.0/16,fe80::/10,fd00:ec2::254) are always refused, including through a hostname that resolves to one. Names are resolved again on every ingress pass, so a DNS change cannot slip one in later. - Loopback, private, mesh and container targets are allowed on purpose, but need an explicit confirmation (
confirm: truein the API,--confirmin the CLI, a checkbox in the dashboard) that names the address this server will connect to. Editing other settings later does not ask again; a new target does. - This platform’s own dashboard and agent ports need the same confirmation. The ingress admin API port can never be a target.
- A target that resolves to this server’s own public address on 80 or 443, or to a local ingress port, is refused as a loop.
- The domain must be free: an app, environment, preview, static site, the dashboard’s primary domain, the built-in registry, the status page or an AI model already using it is named in the error.
Server address and DNS records
The Server address card on the Domains page shows this server’s public IPv4 and IPv6 with copy buttons. They come fromAPP_PUBLIC_HOST or detection (APP_PUBLIC_IP_DETECT), and you can override them by hand when the server sits behind a load balancer or detection is wrong. The override also drives every DNS check and go-live.
The card warns when:
- the public IPv4 is not on any network interface here, which means NAT or a cloud address mapping: ports 80 and 443 must be forwarded to this server;
- a proxy in front terminates TLS, in which case DNS should point at that proxy.
--domain it prints the exact records to create: A and AAAA for the domain, or a CNAME to the apps base domain as an alternative when one is set.
Behind another proxy
When a proxy such as Traefik in front owns ports 80 and 443 and managed proxy routes are on, standalone domains get a route file in that proxy’s directory like app domains do, pointing at the ingress listener.API
GET /api/v1/domains includes standalone domains with kind: "standalone" and target. A create body looks like:
409 with needs_confirmation, a list of plain sentences naming what this server would connect to.