Set up a local storefront domain
This quickstart configures shop.localhost.alvine.dev for a site in the Docker demo. When complete, DNS, TLS, DNS TXT verification, and the site domain binding are ready. The live host serves content only after you publish a site release.
Work in the intended business tenant. A tenant domain does not belong in the System Tenant or in the setup field System Domains (CSV). In that label, CSV means comma-separated administration hostnames, not a file upload. System domains open the administration interface; tenant domains belong to one tenant and bind to a public site.
Prerequisites
You need a ready Start the Docker demo, a fully provisioned tenant, a site in that tenant, and a nucli profile with the required Site and tenant-domain scopes. Check the active context first:
nucli --tenant <tenant> whoami --scopes
nucli --tenant <tenant> sites listStart local DNS and TLS
The optional overlay adds CoreDNS and Caddy. The regular ./start.sh does not enable it automatically.
Run the Storefront commands in the same Docker context as the running base demo. The wrapper identifies that runtime through its Compose service and the local data mount. It preserves the Compose project, image, container UID/GID, public URL, and administration port, including rootless runtimes on high ports. If the base runtime is missing or multiple running containers use the same data directory, the wrapper stops without creating a second Compose project.
./storefront-demo/start.sh init
./storefront-demo/start.sh start --detach
./storefront-demo/start.sh statusInitialization creates the local CA, leaf certificate, and DNS zone under data/storefront-demo/. Private keys use mode 0600 and remain on the server. Never pass ca.key or storefront.key to browsers, CLI programs, or agents.
The public DNS zone uses mode 0644 so the unprivileged CoreDNS container can read it. On the next command, the wrapper upgrades an existing zone from 0600 to 0644. Private keys remain unchanged at 0600.
Public wildcard DNS resolves the standard host to 127.0.0.1. Inside the Compose network, CoreDNS provides the A record and later the TXT record. The standard host therefore requires no hosts-file entry.
Verify the tenant domain
Create the domain with the cms_public surface in the business tenant, then start verification:
The following Bash example requires jq for safe extraction. Continue only when the capture block completes successfully.
nucli --tenant <tenant> web domains create shop.localhost.alvine.dev --surface cms_public --json
if command -v jq >/dev/null 2>&1 &&
VERIFICATION_JSON="$(nucli --tenant <tenant> web domains start-verification <tenant-domain-id> --json)" &&
IFS=$'\t' read -r VERIFICATION_TOKEN VERIFICATION_NAME VERIFICATION_VALUE < <(
jq -er '[.data.token, .data.verificationName, .data.verificationValue] | select(all(.[]; type == "string" and length > 0)) | @tsv' <<<"$VERIFICATION_JSON"
)
then
unset VERIFICATION_JSON
printf 'DNS name: %s\nDNS value: %s\n' "$VERIFICATION_NAME" "$VERIFICATION_VALUE"
else
unset VERIFICATION_JSON VERIFICATION_TOKEN VERIFICATION_NAME VERIFICATION_VALUE
printf '%s\n' 'The verification data could not be read safely. Check jq and the nucli command.' >&2
false
fiverificationName and verificationValue form the public DNS proof. Only the raw token returned once is a protected, short-lived secret; do not store it in the repository or diagnostic logs. Pass the TXT value through stdin:
printf '%s\n' "$VERIFICATION_VALUE" | \
./storefront-demo/start.sh set-verification \
--name "$VERIFICATION_NAME" \
--value-stdinCheck the local infrastructure before requesting one server-side DNS check:
./storefront-demo/start.sh doctor
printf '%s\n' "$VERIFICATION_TOKEN" | \
nucli --tenant <tenant> web domains verify-dns <tenant-domain-id> --token-stdin --json
unset VERIFICATION_TOKENThe raw token is returned only by start-verification. Passing it on stdin keeps it out of the process list and shell history. The TXT value is a public, hash-derived proof and does not reveal the raw token.
Do not repeat verification until CoreDNS serves the new TXT value.
Bind the domain to the site
nucli --tenant <tenant> web bind-domain <site-id> <tenant-domain-id> --json
nucli --tenant <tenant> web readiness <site-id> --jsonImport data/storefront-demo/ca.crt into the intended browser or operating system trust store. data/nucleus.crt trusts the admin host; it does not issue the Storefront certificate.
curl --cacert data/storefront-demo/ca.crt -sS -i \
https://shop.localhost.alvine.dev/HTTP 404 is expected before the first live release. At that stage, the response still confirms DNS, TLS, and proxy routing. Do not disable certificate verification.
Use a different Docker subnet
If init reports an occupied subnet, choose a free /24 and two addresses from it:
export STOREFRONT_DEMO_SUBNET=172.30.54.0/24
export STOREFRONT_DEMO_DNS_IP=172.30.54.53
export STOREFRONT_DEMO_PROXY_IP=172.30.54.80
./storefront-demo/start.sh initThe wrapper detects an identical subnet, and Docker Compose rejects overlaps. The selected values remain bound to the initialized runtime data.
Custom DNS and HTTPS ports must be between 1 and 65535. The DNS, Storefront HTTPS, and administration ports must be different. The wrapper accepts an existing Storefront network owned by the detected Compose project; a network owned by another project remains a conflict.
A custom .test host requires your own DNS resolver. On NixOS, declare extra hostnames through networking.extraHosts or networking.hosts instead of editing the generated /etc/hosts file permanently.
Verify the result
The local domain is prepared when the Storefront Doctor succeeds, the tenant domain is verified, the domain is bound to the intended site in the same tenant, and HTTPS responds with the local CA.
A Preview handoff link is a short-lived, single-use token. Open it exactly once in the intended browser, and keep it out of logs and test evidence.
Continue with Review and publish a CMS site. Only a published site release makes content visible on the live host.
Next steps
- Review the admin-host distinction in Understand system domains.
- Build and publish the site with Review and publish a CMS site.