SEAGIT DOCS
Domains

Domains

A domain is the shared namespace that ties an environment to a cluster. It is the hosted zone every deployment lives under — and the thing the cluster's external-dns and cert-manager add-ons keep in sync with real DNS records and TLS certificates.

What is a domain in SeaGit?

A domain is a DNS zone that SeaGit manages on your behalf — for example example.com — backed by a DNS provider. It is a first-class resource, exactly like a provider, network, or cluster. You attach a domain to an environment, and from then on every deployment in that environment gets its own subdomain under it — my-app.example.com, api.example.com, pr-42.example.com — each with DNS and HTTPS handled for you.

Domain vs. DNS provider vs. zone

  • DNS provider — the credential to a DNS service (Route 53, Cloudflare, PowerDNS). Added once.
  • Domain — a specific hosted zone inside that provider that SeaGit is allowed to manage. You can have several.
  • Managed subdomain — a SeaGit-provided, PowerDNS-backed subdomain if you don't want to bring your own domain.

The two add-ons that make a domain live

A domain on its own is just a zone and some credentials. What makes it actually resolve and serve HTTPS are two controllers running inside the cluster attached to the environment. This is the link between a domain and your clusters:

external-dns

Writes the DNS records

Watches every ingress in the cluster and creates or updates the individual record for each subdomain in the domain's zone, pointing it at the load balancer that is live right now. If the load balancer changes, it re-points the record — your URLs never change.

cert-manager

Issues the TLS certificates

Issues and renews a certificate for the domain and any subdomain under it — typically a wildcard (*.example.com) validated with a DNS-01 challenge in the same zone. Every new subdomain is already covered, with no per-app certificate work.

Key point: a domain is inert until a cluster running these add-ons is attached to an environment that uses it. external-dns is who updates the DNS records; cert-manager is who issues the certificates; the domain is the shared zone they both act on.

How it all connects: the flow

Put together, a domain is the hub that connects a DNS provider, an environment, and a cluster. Reading it end to end:

DNS Provider
Route 53 · Cloudflare · PowerDNS
↓ backs
Domain (zone)
example.com
attached to
Environment
root domain = example.com · cluster attached
runs on
Cluster
↓ hosts
external-dns
writes records into the zone
cert-manager
issues certs for *.example.com
result
Every deployment gets my-app.example.com
automatic DNS record + valid HTTPS
  1. You connect a DNS provider and add a domain (zone) to it.
  2. You create an environment and set that domain as its root domain, then attach one or more clusters.
  3. Each attached cluster runs external-dns (writes records into the zone) and cert-manager (issues the wildcard certificate for the domain).
  4. Now every deployment to that environment is published under the domain — dep-name.example.com — resolving to the cluster and served over HTTPS, with zero manual DNS or certificate steps.

The records SeaGit creates in your zone

You never edit records by hand, but it helps to know what appears in the zone. For each exposed deployment, external-dns writes an address record pointing the subdomain at the live load balancer, plus a TXT ownership record so it can tell which records it manages — and safely leave any records you created yourself untouched.

; ── managed automatically by external-dns ──

; address records — one per exposed subdomain, pointed at the live LB
my-app.example.com.        A      ALIAS → k8s-abc123….elb.amazonaws.com
api.example.com.           A      ALIAS → k8s-abc123….elb.amazonaws.com
pr-42.example.com.         A      ALIAS → k8s-abc123….elb.amazonaws.com

; ownership records — external-dns uses these to track what it owns
my-app.example.com.        TXT    "heritage=external-dns,external-dns/owner=…"

; on non-AWS DNS (Cloudflare / PowerDNS) the address record is a CNAME:
; my-app.example.com.      CNAME  <load-balancer-hostname>

Because the address record targets the load balancer indirectly, external-dns can silently re-point it if the load balancer is ever rebuilt (for example after a cluster stop/start) — your subdomain never changes.

How a request resolves, end to end

Following a single request to my-app.example.com shows how the domain, the add-ons, and the cluster fit together:

  1. DNS lookup — the domain is delegated to its zone, where external-dns has published the address record. The name resolves to the cluster's load balancer.
  2. TLS handshake — the load balancer (or in-cluster NGINX) presents the wildcard certificate cert-manager issued for *.example.com, so HTTPS is valid with no per-subdomain setup.
  3. Ingress routing — inside the cluster the ingress controller matches the host header and forwards the request to the right service and pod.
  4. Response — your app answers. Every other subdomain under the domain follows the exact same path.

Wildcards & per-deployment subdomains

Because cert-manager issues a wildcard for the domain and external-dns writes a record per ingress, anything under the domain is covered the moment it exists. This is what makes ephemeral deployments and preview environments work: a new preview slot such as pr-42.example.com gets its own record and is already inside the wildcard certificate — no new certificate request, no DNS edit.

One domain across multiple clusters

When an environment has more than one cluster attached, the same hostname is served from several clusters at once. Each cluster's external-dns contributes its own record for that hostname, and SeaGit distinguishes them with a routing policy so they don't collide:

  • Weighted — used for multiple clusters in the same region. Each cluster gets a weighted record for the hostname, so traffic is spread across them.
  • Latency-based — used across different regions. Each region's record is tagged with its region, and visitors resolve to the nearest one. See the multi-region guide.
  • Failover — one cluster serves traffic; another is a standby that only receives traffic if the primary is unhealthy.

In every case there is still one domain and one wildcard certificate — only the record shape underneath differs. Routing policies are configured on the environment and require a paid plan.

Bring your own vs. managed subdomain

OptionBacked byPlanYou set upTLS
Your own domainexample.comRoute 53 / Cloudflare / PowerDNSPaid onlyPro up to 5 · Startup/Enterprise up to 15Connect the DNS provider onceAuto wildcard (Let's Encrypt) or ACM on ALB
Managed subdomainyour-id.segt.ioSeaGit PowerDNSAll plansincl. Free — one per accountNothing — provided for youFully managed wildcard

Plan note: connecting a custom domain — with any provider (AWS Route 53, Cloudflare, PowerDNS) — requires a paid plan. Free accounts can still ship: every account is given a managed *.segt.io subdomain at signup, with DNS and a wildcard certificate fully handled. Upgrade to add your own domain — Pro allows up to 5, Startup and Enterprise up to 15 (per-account overrides aside). See pricing.

The ingress class you choose decides which authority issues the cert (cert-manager/Let's Encrypt on nginx, AWS ACM on ALB). See Certificates & TLS for the full matrix.

Provider-specific setup & delegation

Adding the DNS provider is a one-time step. What each needs — and the delegation gotchas to know:

🟧 AWS Route 53

SeaGit manages a hosted zone for the domain. If the domain is registered elsewhere, delegate it by setting the registrar's NS records to the Route 53 zone's name servers. Address records are created as A/ALIAS, which is why ALB and ACM are available on this path.

🟠 Cloudflare

Provide an API token with Zone.DNS (Edit) permission on the zone. Records external-dns creates for the load balancer and the DNS-01 challenge must be DNS-only (grey cloud), not proxied — a proxied record breaks the load-balancer CNAME and certificate issuance.

🔷 PowerDNS

Self-hosted DNS, and what backs SeaGit-managed subdomains. If you use a managed subdomain there is nothing to set up — delegation and the wildcard certificate are handled for you.

Domain lifecycle

A domain moves through a few clear states:

  1. Connect — add the DNS provider and register the domain (zone) against it.
  2. Delegate — for a bring-your-own domain, point the registrar's name servers at the zone so it becomes authoritative. Managed subdomains skip this.
  3. Active — attach the domain to an environment. As deployments go out, external-dns and cert-manager populate records and certificates automatically.
  4. Destroy — tears down the cloud-side zone and the records SeaGit created. A domain must be destroyed before it can be deleted.
  5. Delete — removes the domain from SeaGit entirely.

Detach before you destroy. A domain that is still the root domain of an active environment is in use — remove or re-point that environment first so live deployments don't lose DNS.

Cross-account domains

The domain's zone does not have to live in the same cloud account as the cluster. When they differ, external-dns assumes a role into the account that owns the zone to write records, and cert-manager solves its DNS-01 challenge in that same zone to issue the certificate. This is common in multi-account setups and in multi-region clusters, where one shared domain fronts clusters in several accounts or regions.

Troubleshooting

A subdomain doesn't resolve

Check three things in order: (1) the domain is delegated to the right zone (registrar NS records match); (2) the cluster's external-dns add-on is installed and healthy, with write access to the zone; (3) enough time has passed for propagation. A freshly started cluster also needs a few minutes to rebuild its load balancer before records update.

My TLS certificate is stuck "pending"

cert-manager issues wildcard certs with a DNS-01 challenge, so it needs solver access to the same zone external-dns writes to. If the zone lives in another account, confirm the cross-account role is in place. On Cloudflare, make sure the relevant records are DNS-only (grey cloud). See Certificates & TLS.

A record points at the wrong load balancer

Never CNAME anything directly at the raw *.elb.amazonaws.com hostname — it changes on stop/start. Point custom domains at your stable SeaGit subdomain instead, and let external-dns own the underlying record. Full detail in DNS in Practice.

Frequently Asked Questions

What is a domain in SeaGit?

A domain is a DNS zone that SeaGit manages on your behalf — for example example.com — backed by a DNS provider (AWS Route 53, Cloudflare, or a self-hosted PowerDNS). It is a first-class resource, like a provider, network, or cluster. Once attached to an environment, every deployment in that environment gets its own subdomain under the domain, with DNS and TLS handled automatically.

What is the difference between a domain and a DNS provider?

A DNS provider is the credential to a DNS service (Route 53, Cloudflare, PowerDNS). A domain is a specific hosted zone within that provider that SeaGit is allowed to manage. You add the provider once, then add one or more domains that live in it.

What role do external-dns and cert-manager play?

They are the two cluster add-ons that make a domain live. external-dns watches your ingresses and writes the individual DNS records into the domain zone, pointing each at the current load balancer. cert-manager issues and renews TLS certificates for the domain and any subdomain under it. A domain with no cluster running these add-ons is inert — nothing writes records or issues certificates.

Do I need my own domain, or can SeaGit provide one?

Both work. Every account — including Free — is given a managed *.segt.io subdomain at signup with DNS and a wildcard certificate fully handled, so you can ship without owning a domain. To use your own domain instead, connect Route 53, Cloudflare, or PowerDNS on a paid plan.

Are custom domains available on the free plan?

No. Connecting a custom domain with any provider (AWS Route 53, Cloudflare, PowerDNS) requires a paid plan — the free tier is limited to its managed *.segt.io subdomain. Pro allows up to 5 custom domains and Startup/Enterprise up to 15. This is enforced server-side on both create and delete.

Can the domain zone live in a different cloud account than the cluster?

Yes. external-dns assumes a role into the account that owns the zone, and cert-manager solves the DNS-01 challenge in that same zone. The cluster and the domain can sit in different AWS accounts.

What DNS records does SeaGit create in my zone?

For each exposed deployment, external-dns creates an address record (an A/ALIAS record on AWS, or a CNAME) pointing the subdomain at the live load balancer, plus a companion TXT ownership record so it knows which records it manages and never touches ones you created by hand. You do not create or edit any of these manually.

I registered my domain elsewhere — how do I use it?

Connect the DNS provider that will host the zone (e.g. Route 53), then delegate the domain by pointing the name server (NS) records at your registrar to that zone’s name servers. Once delegation propagates, SeaGit’s zone is authoritative and external-dns can manage records under it.

My subdomain does not resolve, or my certificate is stuck pending. Why?

Almost always a permissions or delegation issue: the cluster’s external-dns and cert-manager add-ons need write/solver access to the domain’s zone, and the domain must be delegated to that zone. On Cloudflare, records used for the load balancer and DNS-01 challenge must be DNS-only (grey cloud), not proxied. Give new records a few minutes to propagate.

Related