Domains

Your product answers at its own domains: scaledbox gives products no names of its own and refuses its own zones (scaledbox.dev). A name is yours once you prove it with DNS records you create at your DNS provider; scaledbox never writes records in your zone. Browsers see Cloudflare's certificate for your names; nothing per name is issued, renewed or waited for.

Claiming a name

List a service's names in scaledbox.toml, per environment:

[env.prod.services.web]
domains = ["shop.example", "www.shop.example"]

[env.staging.services.web]
domains = ["staging.shop.example"]

The next deploy claims them. scaledbox domains (or the console's Domains tab) lists each name, its status and the records it needs:

_scaledbox-challenge.shop.example  TXT    "<the value shown>"
shop.example                       CNAME  shop--product.<targets>
staging.shop.example               CNAME  shop.example

<targets> is scaledbox's targets domain (a zone of its own, off Cloudflare, so your Cloudflare zone can proxy a CNAME to it); scaledbox domains shows the full names.

scaledbox checks the records every few minutes. A proxied CNAME is hidden from DNS, so scaledbox checks it by fetching http://<your name>/.well-known/scaledbox-check/<token> through it (as Let's Encrypt checks a name): leave that path on plain HTTP, out of any redirect or WAF rule of yours. A name answers, over HTTPS, once both hold.

Certificates

Visitors get Cloudflare's certificate for your names (its free Universal SSL covers your zone's apex and one level below it). Behind it, scaledbox's edge presents a certificate for your target's name, which Cloudflare accepts in any SSL/TLS mode, Full (strict) included: so no name of yours needs a certificate, a record or a wait of its own, and your CAA records only concern Cloudflare's.

When a name points away

A name whose records stop pointing at your product stops answering after its checks have failed for ten minutes, and is released seven days later unless it points at your product again: it answers again then, with no TXT record needed (it was proven once). Each name has one owner across all products and tenants: a name another product or tenant has claimed can't be yours.

Your tenants' domain

If your product runs its customers' apps (Tenants), they answer under one of your proven domains:

[tenants]
domain = "shopapps.example"     # a tenant's app answers at <subdomain>.shopapps.example

It needs one record, also listed by scaledbox domains (and the domain's TXT proof, if it isn't proven yet):

*.shopapps.example                CNAME  tenants.shop.<targets>    (proxied)

Proxied, it puts every tenant's app behind Cloudflare's proxy at no cost per name: each app and each of its environments is one level below your domain (blog--acme.shopapps.example, staging--blog--acme.shopapps.example), which Cloudflare's free certificate covers. Until it holds, your tenants' apps have no names, and their deploys say so. If you set one up before, delete its _acme-challenge.shopapps.example record: it is no longer used, and Cloudflare's own certificate renewals use that name. Submitting the domain to the Public Suffix List makes browsers keep your tenants' cookies apart; that is yours to do, and it takes weeks: start early.

Your previews ([previews] domain) may answer under your tenant domain only while your tenants run on the same cluster as your environments (that wildcard leads to your tenants'); otherwise a preview's deploy is refused, saying so: give previews another of your domains.

A tenant's own domain, for its app, is added through the API and proven by records its owner creates (see Tenants).

Your status page

[status] domain is one of your names too, proven the same way and listed as (status page) (see Status pages).

A public bucket's domain

An environment's public bucket ([bucket] public = true) may answer on a name of yours, [bucket] domain = "files.example.com": listed as (bucket), proven the same way (its CNAME proxied, orange cloud), then GET https://files.example.com/<key> reads the object <key> under its BUCKET_PREFIX, through Cloudflare's CDN. Objects without a Cache-Control of their own are served with public, max-age=3600; set one at upload to change it. Cloudflare caches by file extension unless your zone's Cache Rules say otherwise. Nothing but reading goes there: writes need the bucket's keys, at its S3 endpoint.