Deploy

Common pitfalls

The handful of mistakes that account for most failed deploys, and what to do instead.

  • Assuming a start_command (or port) field exists. It doesn't — those parameters are silently ignored. How an app starts is the per-runtime entrypoint convention.
  • Python entrypoint not named app.py / app. The import is app:app. A file called main.py, or an object named application, won't be found. See Python.
  • Missing gunicorn in requirements.txt. It's what serves a Python app; without it the app can't start.
  • Node without a start script. npm start needs one; add it to package.json. See Node.
  • Binding to 127.0.0.1. A server listening only on localhost is unreachable from outside its container. Bind 0.0.0.0.
  • Trusting the first status. Builds are async — poll get_app and confirm with a real request before calling a deploy done. See Checking a deploy.
  • Shipping build output. Skip node_modules, vendor, and virtualenvs — dependencies are installed for you from your manifest.
  • Deploying a framework project's root as a static site. A package.json infers the Node runtime. Build first and deploy the output folder. See Static sites.
  • Expecting a partial deploy to merge. Each deploy replaces the app's content wholesale; a file you stop sending disappears. Send the whole project.
  • Asking your agent to set a secret. There is no env parameter on create_app, on purpose: a key typed into a chat stays in the transcript. Ask for a link instead (manage_env) and enter it at /secrets-manager yourself. An app that needs one will crash on its first deploy and start cleanly once you save it.
  • Calling create_app again to update an app. That makes a second app on a different address. Updating is deploy_app with the existing service id.
  • Treating a "simulated" result as a success. It means hosting isn't configured and nothing was deployed.

More detail, by symptom: Fix a broken deploy.