Skip to content
NebulaCtrldocs
Guides

Add a custom domain

Route a hostname you own to one HTTP or reverse-proxy process of a service, point its DNS at the cluster and get a certificate. DNS is either yours (manual) or managed in a connected Cloudflare account.

A custom domain sends traffic for one hostname to one process of one service, over HTTPS. This guide adds a domain, points DNS at it, and fixes it when it stays short of Live.

Before you begin

  • You have the deployer role or higher. A viewer can see domains but not add, check or remove them. See Members and teams.
  • The service has an HTTP or reverse-proxy process. Worker, cron and job processes are not offered. See Processes.
  • The environment is bound to a cluster that has reported an ingress address.
  • The hostname uses lowercase letters, digits, hyphens and dots, up to 253 characters, and each label starts and ends with a letter or a digit. NebulaCtrl lowercases what you type. A wildcard or an underscore is refused with an error that begins hostname must be an RFC 1123 hostname.
  • No other domain in the installation routes the hostname. If one does, the error begins hostname "app.example.com" is already routed.

Add the domain

Connect Cloudflare (optional)

Skip this step to manage DNS yourself and use HTTP-01 certificates. Connect Cloudflare to have NebulaCtrl create the DNS records and issue certificates over DNS-01. An organization has one connection, and deployers and above can create it.

  1. Select Settings, then Integrations. In the DNS group, select Connect on the Cloudflare row.
  2. Paste an API token with Zone > Zone > Read and Zone > DNS > Edit on the zones you want managed. Fill Account ID only for an account-owned token.
  3. Select Connect Cloudflare.

A toast reads Cloudflare connected and the row shows Connected. If it reads Saved, but Cloudflare could not be verified, the token cannot edit DNS. Fix the token, select Manage, then Verify again.

Open the dialog

Select the service on the canvas, open its Settings tab, scroll to Networking and select Add domain. Enter the Hostname and choose the Process. A service with one eligible process has it preselected. Leave Exposure on Public.

FieldChoicesNotes
Serve throughThis environment's cluster, or another clusterSee Serve a domain through another cluster.
DNSManual, CloudflareCloudflare is disabled until Cloudflare is connected, and preselected once it is. Proxy through Cloudflare keeps the orange cloud on.
CertificateHTTP-01, DNS-01HTTP-01: Traefik in the cluster answers Let's Encrypt on port 80. DNS-01: NebulaCtrl answers through Cloudflare DNS, which works when port 80 is unreachable.

DNS-01 needs a connected Cloudflare account that can see the hostname's zone, and an agent that can install certificates. Otherwise the option shows why. With Cloudflare DNS, DNS-01 (default) is preselected, because Cloudflare's proxy can block Let's Encrypt's HTTP check.

Submit

Select Add domain. A toast reads Domain added. A card for the hostname appears with a progress row: DNS, Ownership, Certificate, Live. The current step pulses amber.

To add the domain over the API:

curl -X POST "BASE_URL/api/v1/environments/ENVIRONMENT_ID/domains" \
  -H "Authorization: Bearer NEBULA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"hostname":"app.example.com","serviceId":"SERVICE_ID","processId":"PROCESS_ID","dnsProvider":"cloudflare"}'

BASE_URL is your control plane address and NEBULA_TOKEN an API token. ENVIRONMENT_ID, SERVICE_ID and PROCESS_ID are the ids of the environment, service and process. Over the API, dnsProvider defaults to manual and certificateMethod to http-01, except that a cloudflare domain with no explicit certificateMethod gets dns-01 when that is usable. The call answers 201.

Point DNS at the cluster

With Manual DNS, the card under Add this A record lists the records to create at your DNS provider, with a TTL of 300 seconds. Create one A or AAAA record per address listed, or select Copy records. The card under Add this TXT record gives the ownership record: the name is _nebula. followed by the hostname, and the value starts with nbl-verify=.

With Cloudflare DNS, there is nothing to create. The card shows Managed in Cloudflare, the zone and Last synced.

Check the domain

Select Check now. NebulaCtrl looks up the hostname and the TXT record, and rechecks every public domain every 15 minutes. A toast reports app.example.com points at the cluster or app.example.com is proxied through Cloudflare when the DNS step is done. Otherwise its body says which record to create. A second toast, app.example.com ownership isn't verified yet, gives the TXT record.

Verify

The status beside the hostname reads Live and all four steps are green. A line under it shows when the certificate renews, for example renews in 62d. Open https://app.example.com in a browser.

Serve a domain through another cluster

Use this when the environment's cluster is not reachable from the internet. An edge cluster is a connected cluster of your organization with a public address. It forwards the domain's TLS untouched, and the certificate stays on the service's own cluster. See Edge clusters.

  1. In the dialog, open Serve through. If the environment's cluster has no public address, the first usable edge cluster is preselected.
  2. Choose a cluster. A disabled cluster shows why: not connected, no public address, agent too old or needs Cloudflare DNS-01.
  3. Point the hostname at the edge cluster's public address. The card's records list it. The card reads Served through and the cluster name.

A domain served this way always uses DNS-01, so Cloudflare must be connected.

Change a domain's settings

Open Actions for HOSTNAME, select Domain settings…, change Exposure, Serve through, DNS, Proxy through Cloudflare or Certificate, and select Save. Save stays disabled until something changes. Switching DNS to Manual removes the records NebulaCtrl created in Cloudflare. Switching Certificate to DNS-01 requests a certificate within a minute.

Fix a domain that is not live

The status beside the hostname names the step that is stuck.

StatusWhat it meansWhat to do
Needs DNSThe hostname does not resolve to the cluster.Create the records under Add this A record and select Check now. With no cluster bound, the card offers a button named Bind plus a cluster name. It needs the admin role.
Publishing DNSCloudflare holds the records and resolvers have not caught up.Wait a few minutes.
DNS sync needs attentionNebulaCtrl could not write the records. The card shows the reason.See the reasons below.
Needs ownership checkThe _nebula TXT record is missing.Create it under Add this TXT record and select Check now. With Cloudflare DNS, the card reads Ownership is automatic.
Waiting on certificateDNS and ownership are done and no certificate is served yet.See the certificate cases below.

Reasons under DNS sync needs attention:

  • Cloudflare already has 1 record(s) at this hostname that NebulaCtrl doesn't manage (A 203.0.113.7). Delete them in Cloudflare, or adopt them so NebulaCtrl manages them. Delete the records, or select Adopt existing records and confirm.
  • cannot manage DNS: the cluster has reported no ingress addresses yet; DNS will be published once it does, or you can publish it manually. Wait for the cluster to report an address.
  • cannot manage DNS: the cluster reported ADDRESSES, none of which is publicly routable; …. Add a public gateway (Clusters, Add server, Public gateway), serve the domain through a public cluster, or publish DNS manually.

Adopting hands the existing A and AAAA records, and a matching ownership TXT record, to NebulaCtrl. The dialog says it will "keep them pointed at the cluster from now on". The button appears only for the doesn't manage reason.

Certificate cases for an HTTP-01 domain:

  • No certificate issued yet: the cluster serves a placeholder and visitors see an error (Cloudflare shows 526). With Cloudflare DNS, select Issue through Cloudflare DNS instead.
  • No cert resolver on this cluster: the cluster cannot issue HTTP-01 certificates. Switch Certificate to DNS-01 in Domain settings….
  • Waiting for a certificate: select Check now. Issuing can take a minute.

A DNS-01 domain reads Requesting a certificate over DNS-01… while it waits. Certificate request failing shows the error, the attempt count and the next retry. Retries start at 15 minutes, double per attempt and stop doubling at 24 hours. To retry sooner, select Renew now. It is disabled while a request is pending. If the error mentions the token, select Verify again in Settings, Integrations, Manage.

Remove a domain

Removing a domain cannot be undone. Traffic to the hostname stops, and adding it again starts the DNS checks from scratch.

Open Actions for HOSTNAME, select Remove domain, and confirm. A toast reads Domain removed. For a Cloudflare-managed domain, NebulaCtrl first tries to delete the records it created. A record Cloudflare refuses to delete stays in the zone until you delete it.

To disconnect Cloudflare, select Manage, then Disconnect. It is refused while a domain uses it: this cloudflare connection is used by 1 domain for managed dns or dns-01 certificates; switch them to manual dns and http-01 first.

Next steps

On this page