https://your-domain serves it”, in order. Each step shows a status, what it found in plain words, the evidence, and one button: a fix the control plane applies itself, a “Check again”, or a link to the one thing you must do elsewhere. It refreshes on its own while you work through it and stops when the domain is live.
Open it from the success banner after a deploy, from the Go live tab of an app, from a domain’s row on the Domains page, or from the doctor link in a domain diagnosis.
The steps
A step that waits on something outside your control (DNS spreading, a certificate request) shows when it will look again. The summary badge on lists has five states: Not live, Waiting for DNS, Waiting for certificate, Live, Needs attention.
2. Reachable on its port
Every app has the automatic address (ansslip.io hostname served by the ingress). When the app exposure feature is allowed for the app, the step also shows the direct host:port URL with a copy button. The direct port is plain HTTP and bypasses the domain’s TLS, basic auth and sign-in gates: use it to check that the app runs, never as its public address. See App ports and exposure.
3. Server firewall
The checklist reads the host firewall (ufw, firewalld, nftables, iptables, in that order) and reports whether ports 80 and 443 accept traffic from anywhere. The fix opens exactly those two TCP ports and nothing else, with these rules:- It shows the exact commands and the undo commands before it runs, and the result lists what was added. The fix needs the root ability, is recorded in the audit log (
host_firewall.web_ports_opened) and in the fix attempt history, and is rate limited like other fixes. - It only runs when the control plane runs as root directly on the host. Inside a container, or without root, the step becomes guided: you get the commands to run yourself.
- It never enables a disabled firewall. A firewall that is off or allows everything is reported as not blocking and left alone.
- It never edits or deletes an existing rule. An explicit deny rule for 80 or 443 is reported and left for you to remove.
- It fails closed: if the firewall cannot be read, is ambiguous (several nftables input chains that drop), or any command fails, nothing stays half applied. Commands already run are undone.
- iptables and nftables rules apply immediately but are lost on reboot unless you save your ruleset. The fix says so.
::/0 if the domain has an AAAA record). It is guidance only: nothing in the product changes a provider firewall today. If the host firewall is fine but port 80 does not answer on this server’s address, the step turns red and puts the provider steps first.
4. DNS
The step lists the record to create, how far it has propagated, and when it will look again. A proxied Cloudflare record is flagged, because a proxy in front changes who answers the certificate challenge. See DNS zones and records.5. Certificate
This is the same flow as Get a real certificate: a preflight (DNS, port 80, CAA, contact email, rate limits), then the request. The checklist only ever asks for a real certificate. The staging authority is for rehearsal and is refused while a working certificate exists, so it is not offered here. While waiting, the plain-language reason for a CA failure is shown, and when Let’s Encrypt asks you to wait, the time you can try again.6. Live
An end-to-end check: this server connects to the domain’s address, verifies the certificate chain for the domain against the system roots, requests the app’s readiness path, and compares the answer with what the app returns directly (the status, then the body, then the content type and server header). A mismatch means another server or a default page is answering. When the app is on another node, or its port cannot be read, the check can only say that a valid certificate and a response exist, and says so. The check runs from the control plane host. It cannot prove the wider internet can reach your server, and no third-party probing service is used. The proof of outside reachability is the certificate itself: Let’s Encrypt only issues one after it reached the domain over port 80 from the internet.Timeline
Below the steps is a timeline for the domain: DNS detected, ports open, certificate requested, certificate issued, renewal scheduled, and every failure with its reason. Issue, request and failure times come from the certificate store and the CA’s recorded errors. “DNS detected”, “ports open” and “live” are the first time this process observed them, so they reset when the control plane restarts.From the terminal
--wait it polls and exits 7 until the domain is live or --timeout passes (default 5m); without it the exit code is 0 whatever the state. Apply the firewall fix with levelrail-cli fixes apply host.firewall.open_web_ports.
API
Fixes use the existing routes:
POST /api/v1/fixes/{id}/apply (root), POST /api/v1/domains/{domain}/cert (root) and the DNS record routes. The stream refreshes every APP_GOLIVE_POLL_INTERVAL (default 10s) for at most APP_GOLIVE_STREAM_ROUNDS rounds (default 60), and ends after two live snapshots in a row. APP_GOLIVE_FIREWALL_TIMEOUT (default 5s) bounds the firewall read.