Put an app online
Something that runs code — Node, Python or PHP. What your agent sends, what we build, and how to confirm it actually serves.
An app is anything that needs code running to answer a request: an API, a form that does something, a dashboard, a webhook receiver, a small tool.
Ask for it
put this app online
Your agent picks the runtime from your files and sends them. About a minute later you have a link with HTTPS on it.
If your app needs an API key or any other secret, say so in the same breath. Environment variables are set when the app is created and can't be changed afterwards, so it saves a rebuild to get them in the first time:
put it online, and set OPENAI_API_KEY to the one in my .env
What each runtime expects
Your agent handles this. It's here so you can check its work when a build won't come up.
| Runtime | Your project must have | How it starts |
|---|---|---|
| Node | package.json with a start script | npm start |
| Python | app.py exposing a WSGI callable named app, and gunicorn in requirements.txt | gunicorn app:app |
| PHP | index.php at the project root | Apache serves the root; index.php is the front controller |
These are conventions, not settings
There is no start-command field and no port field. If a build starts and then dies, it is almost always because the entrypoint isn't where the runtime looks for it. That is the single most common failure here — see Common pitfalls.
A minimal example of each
{
"name": "my-app",
"scripts": {
"start": "node server.js"
}
}from flask import Flask
app = Flask(__name__) # the name `app`, in the file `app.py`
@app.route("/health")
def health():
return {"ok": True}flask
gunicorn<?php
echo "hello";Confirm it actually serves
Ask your agent to open the link, not just to report success:
open the URL and tell me what it returns
A build can be queued, report as running, and still be crash-looping. A real HTTP response is the pass condition. If it isn't serving, Fix a broken deploy walks through it.
Adding a /health route that returns something trivial makes this check unambiguous, and costs you
three lines.
Secrets and configuration
API keys, passwords and anything else your app needs at run time go in as environment variables. They're stored apart from your code and never written into your source.
You set them yourself, in a browser — your agent has no way to. Ask it to manage your environment
variables and it hands back a link to /secrets-manager; sign in there with an emailed code and type them in.
Change or rotate them whenever you like: saving restarts the app with the new values. Your agent only
ever sees the names. See Environment variables.
Under the hood
We generate a Dockerfile for your runtime and build it:
- Node — a multi-stage build on
node:<version>-slim.npm ci(falling back tonpm install), thennpm run build --if-present, thennpm startin a slim production image withNODE_ENV=production. - Python —
python:<version>-slim,pip install -r requirements.txt, thengunicorn app:appbound to the container port. - PHP —
php:<version>-apacheserving the project root. If acomposer.jsonis present, Composer installs your dependencies with--no-dev --optimize-autoloader.
Build output you ship is ignored: node_modules, vendor, .venv, __pycache__, .git and .env
files are excluded from the build context. Send your source, not your dependencies.
Bring your own Dockerfile
If your project contains a Dockerfile at its root, we use yours and generate nothing. That is the
escape hatch for anything the four runtimes don't cover — a Go binary, an ASGI server, a worker
with system dependencies. Two rules: you still pick a runtime, and your container must listen on
that runtime's port, because that's what traffic is routed to — 3000 for node, 8000 for
python, 80 for php and static.