Your hostname keeps working when we move your deploy between clusters, rebuild it, or replace the machine underneath it.
The four steps
-
Claim the domain
In the dashboard, open Domains and choose Claim domain. With the API, send
POST /v1/organizations/{organization_id}/domainswith{"domain": "example.com"}. The response includeschallenge_record_nameandverification_token. -
Prove you own it
Publish a TXT record at the
challenge_record_nameyou were given (_devlyft-challenge.example.com). Its value is theverification_token. Then click Verify now, or callPOST /v1/organizations/{organization_id}/domains/{domain}/verify, or just wait, because we re-check periodically. You only do this once per domain. Every subdomain is covered too. -
Route a hostname to a deploy
In Deployments, open a deploy's Routes and attach the hostname. With the API, send
POST /v1/deploys/{deploy_id}/routeswith{"hostname": "api.example.com", "path_prefix": "/"}. The hostname must be the claimed domain or a subdomain of it. The dashboard then shows the CNAME to publish. In the API response it's thecname_targetfield. -
Publish the CNAME
api.example.com. CNAME d0c43d3885064d9a.edge.devlyft.io.Copy the target from the dashboard or from
cname_target. Don't try to build it yourself. It's a digest of your hostname, so you can't work it out by hand.
Your certificate is issued automatically once the CNAME resolves to us. Until then the hostname won't serve HTTPS. Certificate issuance proves you control the name by answering a request on it, so it can't finish until your DNS points here.
Why the target looks like that, and why it never changes
cname_target is derived from your hostname alone. It isn't tied to a deploy, a cluster, a machine or a region, so none of those changing affects it. We change what that name resolves to, so you never have to edit your zone again.
Two consequences:
- It is 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. You don't need to publish it again.
- It is per hostname, not per deploy.
api.example.comandwww.example.comget different targets. Each needs its own CNAME.
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 (the orange cloud).
- Proxied records break certificate issuance. We issue your certificate with the HTTP-01 challenge, which means answering a request for your hostname at our edge. When the record is proxied, Cloudflare answers that request itself, so the challenge never reaches us and no certificate is issued.
- Proxied records hide the target. A proxied record resolves to Cloudflare's own addresses, not to your
cname_target.digwon't show you the target, so a proxied record looks as if it isn't set up. - Apex domains work when DNS only. An apex (
example.com) can't hold a plain CNAME, so it needs CNAME flattening (see Apex domains). Cloudflare lets you create a CNAME at the apex and, with the record set to DNS only, flattens it automatically, answering with the addresses the target resolves to. Keep the apex record grey-clouded for the same reasons as any other.
To check your setup, run dig +short api.example.com. A DNS-only record returns your cname_target followed by an IP address.
Several deploys behind 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 has to be on that cluster. We check this when you attach the route. A hostname attached to a deploy in a different environment or location is rejected, so it can't end up half-working.
Several locations
To run the same environment in more than one location, give each location its own hostname, such as api.mia.example.com, api.lon.example.com and api.fra.example.com, with one CNAME each. Then handle geographic routing on top of those with whatever your DNS provider offers.
We don't currently serve one hostname from several locations at once.
Apex domains (example.com with no subdomain)
DNS doesn't allow a CNAME at the apex. It isn't a DevLyft restriction: the apex already holds the records that delegate your zone, and a CNAME can't sit alongside them. You have three options, best first:
- Use a subdomain. Use
www.example.comorapi.example.com, and redirect the apex to it at your registrar or CDN. It's the simplest option and what almost everyone does. - Use your provider's ALIAS, ANAME or CNAME flattening if it has one. Cloudflare, Route 53, DNSimple and others do, under various names. On Cloudflare this happens automatically for a DNS-only apex CNAME (see Cloudflare).
Make sure it follows more than one hop. Your hostname's target is itself a CNAME onto a cluster record, so resolving it takes two steps. Some flattening implementations only follow one and return nothing. Test before you rely on it:dig +short example.comshould return an IP address, not a name and not an empty answer. - Ask us for addresses to put in an A record. We provide these on request, and they're the last resort for a reason. An A record puts our address in your zone, so a change on our side needs a change on yours, which is exactly what the CNAME avoids. If you choose this option, expect us to ask you to update it now and then.
Things that will not work
- Wildcard hostnames (
*.example.com) are rejected when you attach a route. The method we use can't issue certificates for a wildcard, and a wildcard has no single target to point at. Route each hostname you actually 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, so another hostname's target won't route yours.
When something is not working
dig api.example.comreturns nothing. Your CNAME isn't published yet, or it hasn't propagated. Check that the target matchescname_targetexactly, character for character.- It resolves to Cloudflare addresses, not your target. The record is proxied. Switch it to DNS only (see Cloudflare).
- It resolves but HTTPS fails. The certificate hasn't been issued yet. It can't be issued until the name resolves to us, so this usually clears up on its own within minutes of the CNAME going live.
- It resolves but serves the wrong thing, or 404s on some paths. If you've split the hostname across deploys by path prefix, check that every one of them is still exposed. A deploy that stops being exposed stops serving its paths, and the hostname keeps working for the others.
- The dashboard says “DNS target pending…”. The deploy isn't publishing edge DNS yet, so there's no CNAME target to show. Reopen Routes in a little while. If it stays that way, contact us at info@devlyft.io.
- Your deploy shows
placement.state: PENDING. The deploy hasn't been assigned to a cluster yet, usually because your location doesn't have enough room for the environment. It retries on its own and you don't need to do anything. Contact us if it stays that way.