apps.yml reference
apps.yml tells a sandbox how to run your product: the toolchain, the backing services, and each app’s setup, startup, routing, and health checks.
Where it lives
The project Configure page stores the shared baseline for each repository. Changes made by an agent inside a thread are saved as workspace-only overrides, so an app can be configured and tested alongside branch-only code without changing other threads. Promote the reviewed document in project settings when the code is available project-wide.
A complete example
tools:
- nodejs_22
- pnpm@10.32.1
env:
NODE_ENV: development
setup:
- pnpm install
- pnpm db:migrate
services:
postgres:
image: postgres:16
environment:
POSTGRES_PASSWORD: postgres
ports:
- "5432:5432"
connectionEnv:
DATABASE_URL: postgres://postgres:postgres@localhost:5432/app
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
retries: 5
apps:
web:
dir_path: apps/web
when:
exists: apps/web/package.json
port: 3000
hmr_port: 30003
routes:
- path: /
startup: pnpm dev --host 0.0.0.0
health:
- endpoint: /
api:
dir_path: apps/api
port: 4000
routes:
- path: /api
startup: pnpm start
health:
- endpoint: /healthzTop-level fields
toolsToolchain packages, as name or name@version — e.g. nodejs_22, pnpm@10.32.1, postgresql_16.
envRepo-level environment variables injected into all apps and services.
setupRepo-level shell commands run once when the workspace is built, before per-app setup — installs, migrations, seeds.
onepasswordBind a 1Password item as the source of repo-level secrets: source_type (note or fields) plus source_item_id.
servicesNamed backing services (Postgres, Redis, …) run as containers next to your apps.
appsNamed applications — the processes Gentlybot starts, routes, and health-checks.
App fields (apps.<name>)
startupCommand(s) that launch the app. The only required app field.
portHTTP port the app listens on. Required for endpoint health checks and URL routing.
hmr_portSeparate HMR/WebSocket port (e.g. Vite). Upgrade requests are routed here instead of port.
dir_pathSubdirectory of the repo the app lives in (monorepos). Defaults to the repo root.
when.existsOptional repo-relative sentinel. The app is skipped in workspaces where this path does not exist.
routesHow the app is exposed on the sandbox URL: each entry is exactly one of path (/api), prefix (a subdomain label), or subdomain.
envApp-level environment variables; override repo-level values.
setupApp-specific setup commands, run after repo-level setup.
healthReadiness checks — all must pass before the app counts as running. Each is one of endpoint: /path (2xx/3xx on port) or exists: relative/file.
onepasswordApp-level 1Password binding, same shape as the repo-level one.
Service fields (services.<name>)
imageContainer image, e.g. postgres:16 or redis:7.4.
environmentEnvironment variables for the service container.
portsPort mappings, e.g. "5432:5432".
connectionEnvConnection strings exported to your apps’ environment, e.g. DB_URL.
healthcheckContainer health probe: test (command array) plus optional interval, timeout, start_period, retries.
optionsRuntime tuning: memory, cpus, shmSize, ulimits, capAdd, privileged.
Secrets
Don’t put real secrets in apps.yml. Bind a 1Password item with the onepassword field (repo-level or per-app) and Gentlybot resolves it into the sandbox environment at run time — secrets never need to be committed or stored in Gentlybot.