Fix "no open ports detected" by making the HTTP server listen on host 0.0.0.0 and the port supplied in the PORT environment variable. Localhost and 127.0.0.1 accept traffic only from inside the same container. A hosting proxy cannot reach that loopback address.
The process can be healthy while the site is unreachable. This is a networking contract, not necessarily an application crash.
Two values must be right at the same time
| SETTING | LOCAL VALUE THAT OFTEN FAILS | DEPLOYMENT VALUE |
|---|---|---|
| Host interface | localhost or 127.0.0.1 | 0.0.0.0 |
| Port | A hardcoded 3000, 5000, or 8000 | The value in PORT |
Binding to 0.0.0.0 does not publish the container directly to the internet. It lets the platform proxy reach the process on the container network. The proxy normally accepts public HTTPS, terminates TLS, and forwards the request to your HTTP listener.
Working Node and Python examples
The fallback keeps local development convenient. In production, the host-provided PORT wins. Do not copy one provider's default port into the code and assume every environment uses it.
Read the first symptom, not the final error page
| SYMPTOM | LIKELY CAUSE | NEXT CHECK |
|---|---|---|
| No open ports detected | Nothing is listening where the scanner expects | Print the host and port at startup |
| 502 Bad Gateway with a running process | Proxy cannot reach the listener | Check 0.0.0.0, PORT, and startup completion |
| Connection refused | Process exited or never opened the socket | Read the first runtime error |
| EADDRINUSE or address already in use | Two servers chose the same port | Start one HTTP listener, not one per module |
| Health check times out | Route is slow, blocked, or never returns success | Create a small endpoint with no database dependency |
Reproduce the hosting contract locally
- 01Use the real start commandRun the same npm script, Uvicorn command, or entry file configured for the deployment.
- 02Set a temporary PORTStart with PORT=10000 or another unused local port so hardcoded values become visible.
- 03Print the listener addressThe startup line should name 0.0.0.0 and the value you supplied.
- 04Call a small routeUse curl against localhost on that port. A plain health response separates networking from database or frontend errors.
- 05Redeploy and read the earliest linesLater proxy errors are consequences. The startup log usually contains the cause.
Common fixes that create a second problem
- Do not bind directly to port 443. The platform proxy owns public HTTPS.
- Do not set PORT to a domain name or full URL. It is an integer.
- Do not open a second server only for health checks. Put the health route on the existing app.
- Do not use a development server in production when the framework provides a production start command.
- Do not treat 0.0.0.0 as a browser address. Visit the public host URL or localhost during local testing.
Spocket assigns PORT to HTTP apps and routes an HTTPS spocket.dev address to that listener. Use /documentation/domains-and-webhooks for the exact contract and /documentation/logs-and-status for startup output. Static exports do not need a listener, so /run/sites also helps confirm whether the project is a static site or a server app.