Custom domains
Serve a deploy on your own hostname, such as api.example.com, by verifying the domain once and publishing one CNAME record per hostname. Your hostname keeps working when DevLyft moves your deploy between clusters, rebuilds it, or replaces the machine underneath it.
Quick setup#
You need a deploy that is publicly exposed (its build has a container port, and Publicly expose this deploy (edge ingress) is ticked) and access to your domain's DNS. Claiming and deleting domains needs the Manager or Admin role; any member can verify a domain and attach routes.
Claim the domain
Domains→Claim domain, enter
example.com, choose Claim domain.Publish the TXT record and verify
Add the TXT record the dashboard shows, then choose Verify now. You do this once per domain.
Attach a route to your deploy
Deployments→Routes on your deploy, pick the subdomain and domain, choose Attach route.
Publish the CNAME
Add the CNAME the dashboard shows after attaching. HTTPS is issued automatically once it resolves.
Claim your domain#
A domain belongs to your organisation, not to one project, so every project in the organisation can route hostnames under it.
- Open Domains in the dashboard sidebar (under Infrastructure).
- Choose Claim domain (or Claim your first domain on an empty page).
- Enter the registrable domain, for example
example.com, and choose Claim domain. The dashboard lower-cases it for you.
The domain appears with a Pending badge and the TXT record to publish. With the API:
POST /v1/organizations/{organization_id}/domains
{"domain": "example.com"}
The response includes challenge_record_name and verification_token.
Verify ownership#
Publish a TXT record with your DNS provider. The dashboard shows both values with copy buttons.
_devlyft-challenge.example.com. TXT "<verification_token>"
Then choose Verify now on the domain, or call the API. DevLyft also re-checks pending domains periodically, so you can simply wait.
POST /v1/organizations/{organization_id}/domains/{domain}/verify
- One verification covers every subdomain. Verify
example.comonce and you can routeapi.example.com,www.example.comand so on. - The challenge expires after 72 hours. The dashboard shows a countdown (“Challenge expires in … · by …”). If the record isn't found in time, the domain moves to Failed: delete it and claim it again to get a fresh challenge.
- “DNS TXT record not found yet” means the record hasn't propagated. Try again shortly.
Once verified the badge changes to Verified (or Active) and the card reads “Verified — route example.com or any subdomain to a deploy from Deployments → Routes.”
Attach a hostname#
A route sends a hostname, optionally limited to a path prefix, to one deploy.
- Open Deployments and choose the Routes (link) icon on the deploy's row.
- Enter a Subdomain (optional), such as
api, and pick the verified Domain. Leave the subdomain empty to route the domain itself. - Leave Path prefix (optional) empty to route the whole host, or enter one such as
/api. See Routes and path prefixes. - Check the preview line (“Routes
api.example.comto this deploy.”) and choose Attach route.
If the Routes dialog says “No verified domains yet”, finish verification first. With the API:
POST /v1/deploys/{deploy_id}/routes
{"hostname": "api.example.com", "path_prefix": "/"}
Add the required CNAME#
After you attach a route the dialog shows “Route attached. Now add this DNS CNAME record with your DNS provider”, with the Name and Target to copy. Every route in the list also shows its record (“Point DNS: CNAME … → …”). In the API response it is the cname_target field.
api.example.com. CNAME d0c43d3885064d9a.edge.devlyft.io.
Always copy the target from the dashboard or from cname_target. It's a digest of your hostname, so you can't work it out by hand.
Why the target never changes#
cname_target is derived from your hostname alone. It isn't tied to a deploy, cluster, machine or region, so none of those changing affects it. DevLyft changes what that name resolves to, so you never have to edit your zone again.
- Stable for the life of the hostname. Delete the route and create it again, or move the hostname to a different deploy, and the target stays the same.
- Per hostname, not per deploy.
api.example.comandwww.example.comget different targets, and each needs its own CNAME.
HTTPS certificates#
Your certificate is issued automatically once the CNAME resolves to DevLyft. Until then the hostname won't serve HTTPS. Issuance uses the HTTP-01 challenge, which proves you control the name by answering a request on it, so it can't finish until your DNS points at DevLyft. More in HTTPS and certificates.
Apex domains#
DNS doesn't allow a CNAME at the apex (example.com with no subdomain). It isn't a DevLyft restriction: the apex already holds the records that delegate your zone. Your options, best first:
- Use a subdomain. Serve
www.example.comorapi.example.com, and redirect the apex to it at your registrar or CDN. It's the simplest option. - Use your provider's ALIAS, ANAME or CNAME flattening. Cloudflare, Route 53, DNSimple and others offer it under various names; on Cloudflare it happens automatically for a DNS-only apex CNAME. Make sure it follows more than one hop: your target is itself a CNAME onto a cluster record, and some implementations only follow one. Test it:
dig +short example.comshould return an IP address, not a name or an empty answer. - Ask for addresses to put in an A record. Available on request from info@devlyft.io, and a last resort: an A record puts DevLyft's address in your zone, so a change on our side needs a change on yours. Expect to be asked to update it now and then.
Cloudflare#
If your DNS is on Cloudflare, set every CNAME that points at DevLyft to DNS only, the grey cloud in the Proxy status column. Don't use Proxied (orange cloud).
- Proxied records break certificate issuance. With a proxied record Cloudflare answers the HTTP-01 challenge request itself, so it never reaches DevLyft and no certificate is issued.
- Proxied records hide the target. They resolve to Cloudflare's addresses, not your
cname_target, sodigmakes the record look missing. - Apex domains work when DNS only. Cloudflare lets you create a CNAME at the apex and flattens it automatically. Keep it grey-clouded too.
To check, run dig +short api.example.com. A DNS-only record returns your cname_target followed by an IP address.
Multiple deployments on one hostname#
You can split one hostname across deploys by path prefix, for example one deploy on / and another on /api. They share a single CNAME because the same cluster serves them.
Those deploys must be in the same environment and the same location. One hostname resolves to one cluster, so every deploy serving it must be on that cluster. DevLyft checks this when you attach the route and rejects a hostname attached to a deploy in a different environment or location.
Multiple locations#
To run the same environment in more than one location, give each location its own hostname, such as api.mia.example.com and api.lon.example.com, with one CNAME each. Handle geographic routing on top of those with your DNS provider. DevLyft doesn't currently serve one hostname from several locations at once.
Things that will not work#
- Wildcard hostnames (
*.example.com) are rejected when you attach a route. The issuance method can't cover a wildcard, and a wildcard has no single target. Route each hostname you serve. - Pointing at a cluster name you saw somewhere. Names like
mia-0.edge.devlyft.ioare internal and they move.cname_targetis the only supported target. - Copying another hostname's target. Each target is a digest of its own hostname.
Troubleshooting#
digreturns nothing- The CNAME isn't published or hasn't propagated. Check the target matches
cname_targetcharacter for character. - Resolves to Cloudflare addresses
- The record is proxied. Switch it to DNS only (Cloudflare).
- Resolves but HTTPS fails
- The certificate isn't issued yet. It can't be until the name resolves to DevLyft, so this usually clears within minutes of the CNAME going live.
- Wrong content or 404 on some paths
- If the hostname is split across deploys by path prefix, check every one of them is still exposed. A deploy that stops being exposed stops serving its paths; the others keep working.
- “DNS target pending…”
- The deploy isn't publishing edge DNS yet, so there's no CNAME to show. Reopen Routes in a little while. If it persists, email info@devlyft.io.
placement.state: PENDING- The deploy hasn't been assigned to a cluster yet, usually because the location lacks room for the environment. It retries on its own; contact us if it stays that way.
- Domain shows Failed
- The 72-hour challenge expired. Delete the domain and claim it again.