#Custom domains
Every project gets a <project>.coduck.app subdomain with HTTPS automatic. You can also attach one or more domains you own. CoDuck handles DNS verification, SSL via Let's Encrypt, and routing.
#The lifecycle
add → verify ownership → verify routing → activeadd → verify ownership → verify routing → active- Add registers the domain against the project and returns the DNS records you need to set on your registrar.
- Verify ownership confirms you control the domain by looking up a TXT record CoDuck issued on
_coduck.<domain>. - Verify routing confirms traffic for the domain reaches CoDuck by checking the apex
Arecord or subdomainCNAME. - Active means both checks passed, Let's Encrypt has issued a certificate, and the per-project nginx vhost is serving traffic.
#Add a domain
- Open your project at
https://app.coduck.ai/project/<projectId>. - Switch to the Cloud panel, open the Hosting tab, then the Domains sub-tab.
- Click Add domain and enter the domain you want to attach.
- CoDuck displays the DNS records you need to set on your registrar (Namecheap, Cloudflare, GoDaddy, etc.).
- Set the records, then click Verify once DNS has propagated.
#DNS records you need to set
The exact values are shown when you add the domain. They follow this shape:
| Phase | Type | Name | Value |
|---|---|---|---|
| Ownership | TXT | _coduck.<domain> | coduck-verify=<token> (shown when you add the domain) |
| Routing (subdomain) | CNAME | app (or whatever subdomain) | <project>.coduck.app |
| Routing (apex) | A | @ | CoDuck's published IP (shown when you add) |
The TXT record stays in place — CoDuck re-checks it periodically to keep the domain associated with your account.
#Apex vs subdomain
- Apex (
example.com) needs anArecord pointing at CoDuck's IP. Some registrars (Cloudflare, DNSimple) also supportALIASorANAMErecords that emulate CNAMEs at the apex — those work too. - Subdomain (
app.example.com) can use aCNAMEpointing at<project>.coduck.app. This is preferred because IP changes on CoDuck's side propagate automatically without you touching DNS.
#SSL
Let's Encrypt issues a certificate automatically after routing is verified. There's no extra step on your end, and renewals are handled automatically before expiry.
#Managing existing domains
Under Hosting → Domains you can see every domain attached to the project, along with its current status — pending, verifying, active, or failed. From the same view you can:
- Set one domain as primary (the canonical redirect target for the project).
- Remove a domain, which detaches it and tears down the nginx vhost.
- Transfer a domain to a different project you own.
#Common failures
- DNS not propagated — verification ran before your registrar published the record. Check with
dig TXT _coduck.example.comordig example.com, then retry once the record is live. - Wrong record type at apex —
CNAMEat an apex will be rejected by most registrars; useA(orALIAS/ANAMEif supported) instead. - Record at the wrong host — the TXT goes on
_coduck.<domain>, not the apex. Some registrar UIs auto-append the domain; double-check the final hostname. - Let's Encrypt rate limit — if both verifications pass but SSL doesn't issue, you've likely hit Let's Encrypt's per-domain issuance limit. Wait an hour and re-verify.
#For developers
If you'd rather script domain operations than click through the dashboard, the CoDuck CLI exposes the same flow. See CLI commands for the full reference.
#Next
- Deploying — what triggers a re-build vs. a config reload after a domain change.
- Sending email — email uses domain verification too, but with DKIM CNAMEs only and a separate flow from custom domains.