
Start a failed deployment check at the application and work outward: confirm the build, then the running process, its network, the reverse proxy, DNS and HTTPS. A working DNS record cannot fix a stopped application, and opening more public ports is not a general solution to a gateway error.
Identify which layer failed
| Symptom | Check first | Next action |
|---|---|---|
| Build fails or is killed | Runtime version, lockfile, build logs and available memory/disk. | Reproduce the build; measure resources before changing server size. |
| 502 or 503 from a proxy | Process health, listening address, port and shared network. | Fix the upstream service or proxy target; keep the app port private. |
| Homepage works, nested route returns 404 | Static server route fallback and client router paths. | Configure the fallback for browser routes, without swallowing API errors. |
| JavaScript request returns HTML | Asset path, build base and an over-broad fallback. | Publish the full build and correct the base path; do not label HTML as JavaScript. |
| Domain reaches the wrong server | A/AAAA records, proxy settings and the intended hostname. | Correct the actual DNS configuration; inspect IPv4 and IPv6 separately. |
| HTTPS issuance fails | DNS, reachable required ports, hostname and certificate logs. | Correct prerequisites before retrying; do not disable certificate validation. |
| Login redirects fail | Exact callback origins, HTTPS URL, cookie and backend settings. | Update the identity provider and app configuration together. |
Inspect process state without exposing secrets
For an example deployed through Docker Compose, these commands summarize service state and recent application logs. Replace app with the actual service name in your Compose file:
docker compose ps
docker compose logs --tail=100 appReview logs locally and redact credentials, request bodies and customer data before sharing excerpts. Do not publish full environment dumps. Inspect exit codes and the configured health check; a running container can still contain an unhealthy application.
Check the upstream from the right network
In a containerized proxy, localhost refers to the proxy container itself. A Compose service name and its internal port normally identify another service on the same network. The application must listen on an address reachable inside that network. Expose only the intended public proxy ports; a private application listener need not be published to the internet.
The reviewed Node and Next.js examples use a private application service and a separate Caddy proxy. Their health checks exercise a defined endpoint. Adapt the service name, port and endpoint to your own application; copying a different project's health URL does not prove your app is healthy.
Separate missing configuration from wrong build output
A browser bundle uses the public values available when it was built. A Node process may read server configuration at startup. Identify which applies before changing environment values. Rebuild static assets when needed; restart a server deliberately when its startup configuration changes. Keep private keys server-side and rotate a key if it was exposed in a published bundle.
Recover the application and data deliberately
Keep the last known-good image or artifact and the configuration version used with it. Before a database migration, take and verify a recoverable backup. Reverting an application image does not reverse a database schema change. Avoid destructive cleanup commands while investigating; containers, volumes and uploaded files have different lifecycles.
After recovery, test a direct route, the health endpoint, sign-in, an authorized data operation and an unauthorized request. Confirm the new deployment is the one receiving traffic and record the cause and corrective change.
Know which team owns the problem
For account access, billing, provisioning or the purchased hosting product, use the knowledge base and the published product support route. Application code, deployment panels, containers, database design and application recovery remain your responsibility on a self-managed VPS. The production checklist and app hosting decision page help define those boundaries before launch.