Putting a small service on the public internet creates a boundary that did not exist while it was reachable only from one machine or one network. DNS, TLS, redirects, firewalls, reverse proxies, application behavior, and recovery now have to agree. Most launch problems are not deep failures in any one component; they are mismatches between two of them.
A useful preflight is therefore a written contract for the outside of the system. It should be short enough to repeat after every meaningful change and specific enough that another person—or you, six months later—can tell whether the service is behaving correctly.
Define the public contract
Start with the behavior a visitor can observe, not the process list behind it. Record the names, ports, status codes, redirects, and certificate names that are meant to be public. If an item is intentionally absent, record that too.
- Public name
- The exact hostname a client should use
- Address records
- Expected IPv4 and IPv6 answers, including who owns them
- Open transports
- Protocol and port pairs that are deliberately reachable
- Success response
- Expected status, redirect chain, and a stable body marker
- TLS identity
- Certificate names, issuer, and the next renewal deadline
- Failure response
- What a visitor should receive when the application is unavailable
- Timeout budget
- How long a normal request may take before it is considered failed
- Rollback
- The last known-good version and the command or action that restores it
This record prevents vague tests such as “the page opens for me.” It also exposes accidental surface area: an address record that no longer has a purpose, an old port that still accepts connections, or a certificate containing a name that was meant to stay internal.
Test from the wrong side
Run the preflight from outside the service’s normal network. A request from the host itself can bypass public DNS, edge routing, address-family problems, and firewall rules—the exact layers most likely to be wrong during a first deployment.
- Resolve the name. Compare the returned IPv4 and IPv6 addresses with the written contract. A stale record can send only part of the audience somewhere else.
- Complete the TLS handshake. Check the hostname, certificate chain, expiry, and negotiated protocol. A valid certificate for the wrong name is still a failure.
- Follow the whole HTTP path. Record every redirect and the final status. Test both the canonical URL and the plain HTTP entry point if it is advertised.
- Ask for a missing page. A deliberate
404is better than a default server page, a directory listing, or an unrelated upstream response. - Try an unexpected host. The service should fail deliberately rather than reveal an administrative default or a different virtual host.
- Repeat on another network. A mobile connection is often enough to expose split DNS, local caching, or an address-family path that the office network hid.
The most useful launch test is a request that travels through the same public path as a stranger’s request.
Decide what failure should look like
A service will eventually lose an upstream, miss a renewal, fill a filesystem, or receive a configuration it cannot start. The preflight should include one controlled failure so the public result is known before it happens unexpectedly.
Stop or isolate the application while leaving the public edge in place. Confirm that the response is intentional, short, and free of internal addresses, filesystem paths, stack traces, or default administrative pages. Then restore the application and verify that the external check recovers without manual cache clearing.
- Application unavailable
- Known error page or closed response; no accidental upstream detail
- Bad configuration
- Previous version remains available or rollback is immediate
- Certificate near expiry
- Alert arrives while renewal still has time to be repaired
- Storage pressure
- Logs and temporary files cannot silently consume the recovery path
Monitor the contract, not the process
A running process is evidence that a program started. It does not prove that DNS points to the right place, the certificate matches, the public route reaches the application, or the response contains the intended content.
A small external check can cover the useful chain with five observations: DNS resolves to an expected address, a connection completes, TLS presents the expected name, the final status is accepted, and the body contains one stable marker. Keep certificate days remaining and end-to-end duration beside those results. Alert on the contract failing, not on every small fluctuation.
Run the check from a location that does not share the service’s host or private network. If there is only one monitor, independence is more valuable than a large dashboard.
Leave a five-minute recovery note
The first minutes of an incident should not be spent rediscovering how the service is assembled. Store a short recovery sequence beside the configuration and keep it limited to actions that are safe under pressure.
- Confirm the outside symptom. Save the failing status, time, resolved address, and certificate result before changing anything.
- Identify the last change. Check deployment, DNS, certificate, firewall, and dependency changes in time order.
- Choose repair or rollback. Prefer rollback when the cause is unclear and the previous state is known to satisfy the public contract.
- Verify from outside again. Recovery is complete only when the original public check succeeds.
- Record one durable fact. Add the cause, the signal that would have caught it earlier, or the step that made recovery slower.
The goal is not a launch ritual with dozens of boxes. It is a compact, repeatable description of what the service promises publicly, how that promise is observed, and how the previous good state is restored.