Deploying apps
How deploys work
What happens between a push and an app serving traffic, and the one rule that decides whether it comes up.
On this page
The four stages
- 01
Detect. The repository is read to work out the stack, the build command and the port the app listens on. - 02
Build. A container image is built from the code. Build logs stream live, so the failing step is visible as it happens. - 03
Health check. The new container starts and is checked for a TCP connection on its port. - 04
Cut over. Once the new version is healthy, traffic moves to it and the old one is retired.
The port contract
A PORTenvironment variable is set in the container. Read it rather than hardcoding a number.Bind 0.0.0.0, notlocalhostor127.0.0.1. A process bound to localhost is reachable only from inside its own container, so neither the health check nor a visitor can see it.The port is detected from the source where possible. If detection gets it wrong, set the port explicitly in the app’s settings.
localhost instead of 0.0.0.0 is the single most common cause of a build that succeeds and an app that never comes up. If an app works locally but not here, check this first.
// Node, correctconst port = process.env.PORT || 3000;app.listen(port, '0.0.0.0');// Node, will fail its health checkapp.listen(3000, 'localhost');
How long an app has to start
/health endpoint and no particular path is required.What triggers a deploy
A push to the branch the app is connected to. Pressing Redeploy in the console. An environment variable change, applied on the next deploy or restart. An AI agent acting on the account’s behalf over MCP.