Deploying
Port and health checks for zero-downtime deploys
How DployHub uses your port and health check path to release new versions with zero downtime, what the failure messages mean and how to fix them.
Updated 3 min read
Every release on DployHub is zero-downtime. We start the new version next to the old one, check that it answers, and only then switch traffic. Two settings drive this: the port your app listens on and the health check path. Getting them right is the most common fix for a failed release.
How a release works
- The new container starts with your environment variables and the
PORTvariable set. - For up to 90 seconds we request the health check path on the configured port.
- As soon as it answers with any HTTP status below 500, traffic switches to the new version.
- The old container is removed.
If the check never passes, the running version keeps serving visitors and the deploy is marked failed with the last 50 log lines from the new container. Your users see nothing.
Listening on the right port
We always set the PORT environment variable to the configured port, unless you set PORT yourself. Read it, and bind to 0.0.0.0 so connections from outside the container reach you:
const port = process.env.PORT || 3000;
server.listen(port, '0.0.0.0');import os
port = int(os.environ.get("PORT", 8000))
app.run(host="0.0.0.0", port=port)Detected defaults are 3000 for Node.js, 8000 for Python, 80 for static sites and the first EXPOSE line for Dockerfiles. Change the port in the app Settings if yours differs.
Choosing a health check path
The default is /. Any status below 500 passes, so a redirect or a 404 is fine, but a 500 is not. If your home page needs a database or slow external calls, add a light endpoint and set the path to it:
app.get('/health', (req, res) => res.status(200).send('ok'));The path must start with /, for example /health or /api/status.
Failure messages and fixes
Your app didn't answer on port P within 90 seconds
Nothing answered on that port. Check that the app listens on 0.0.0.0 rather than localhost, that it uses the PORT variable, and that the port in Settings matches. Also check whether startup work such as migrations takes longer than 90 seconds.
Your app kept answering with HTTP 5xx
The app is up but the health check path errors. Usual causes are a missing environment variable, an unreachable database, or a framework rejecting the hostname, such as Django without the address in ALLOWED_HOSTS. Read the log lines in the failed deployment.
Your app stopped right after starting (exit code N)
The process exited. Exit code 137 means it ran out of memory; raise memory in Settings. Other codes usually mean a crash on startup, shown in the logs.
If the logs do not explain the failure, raise a ticket and attach the deployment; we include the app status, error summary and recent logs automatically.
Frequently asked questions
Which HTTP statuses pass the health check?
Any status below 500. Redirects and 404s pass; 5xx responses do not.
How long do you wait for a new version?
Up to 90 seconds. If it has not answered by then, the deploy fails and the old version keeps serving.
Do I need to set the PORT variable?
No. We set PORT automatically to the configured port unless you set it yourself.
Related articles
- App not answering on its port: fix health check failsSeeing "didn't answer on port within 90 seconds"? Learn why the health check fails and how to listen on PORT and 0.0.0.0 in Express, Flask and FastAPI.
- Build settings: build, start, root folder and moreEvery DployHub build setting explained: build type, build and start commands, port, root folder, Dockerfile path and health check path, with examples.
- App crashed out of memory (exit code 137)Exit code 137 means your app ran out of memory. Learn how to confirm it in metrics, add more RAM, and tune Node.js heap size or gunicorn workers to fit.
- Roll back to a previous version in secondsUndo a bad release by rolling back to an earlier successful version from the Deployments tab. No rebuild, it takes seconds, and the last 5 images are kept.