Gentlybot docs

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.

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.

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
    secrets:
      MAPS_API_KEY: "Maps console > Credentials > Server key"
    health:
      - endpoint: /

  api:
    dir_path: apps/api
    port: 4000
    routes:
      - path: /api
    startup: pnpm start
    health:
      - endpoint: /healthz
tools
list of strings

Toolchain packages, as name or name@version — e.g. nodejs_22, pnpm@10.32.1, postgresql_16.

env
map

Repo-level environment variables injected into all apps and services.

setup
string or list

Repo-level shell commands run once when the workspace is built, before per-app setup — installs, migrations, seeds.

secrets
map

Secret variable names shared by every app in this repository, each with an optional where-to-get hint. Names only; add values in Gentlybot.

onepassword
object

Bind a 1Password item as the source of repo-level secrets: source_type (note or fields) plus source_item_id.

services
map

Named backing services (Postgres, Redis, …) run as containers next to your apps.

apps
map

Named applications — the processes Gentlybot starts, routes, and health-checks.

startup
string or listrequired

Command(s) that launch the app. The only required app field.

port
integer

HTTP port the app listens on. Required for endpoint health checks and URL routing.

hmr_port
integer

Separate HMR/WebSocket port (e.g. Vite). Upgrade requests are routed here instead of port.

rewrite_host
boolean

Send Host: localhost:<port> to the app, with the public preview host in X-Forwarded-Host. Only for apps that reject unknown hostnames. Requires port.

dir_path
string

Subdirectory of the repo the app lives in (monorepos). Defaults to the repo root.

when.exists
string

Optional repo-relative sentinel. The app is skipped in workspaces where this path does not exist.

routes
list

How the app is exposed on the sandbox URL: each entry is exactly one of path (/api), prefix (a subdomain label), or subdomain.

env
map

App-level environment variables; override repo-level values.

setup
string or list

App-specific setup commands, run after repo-level setup.

health
list

Readiness checks — all must pass before the app counts as running. Each is one of endpoint: /path (2xx/3xx on port) or exists: relative/file.

secrets
map

Secret variable names only this app needs, each with an optional where-to-get hint. Names only; add values in Gentlybot.

onepassword
object

App-level 1Password binding, same shape as the repo-level one.

image
stringrequired

Container image, e.g. postgres:16 or redis:7.4.

environment
map

Environment variables for the service container.

ports
string or list

Port mappings, e.g. "5432:5432".

connectionEnv
map

Connection strings exported to your apps’ environment, e.g. DB_URL.

healthcheck
object

Container health probe: test (command array) plus optional interval, timeout, start_period, retries.

options
object

Runtime tuning: memory and shmSize (up to 8g), cpus (up to 4), ulimits, and capAdd (allowlisted — IPC_LOCK, SYS_NICE, SYS_RESOURCE plus Docker defaults). Privileged containers are not available.

API keys, tokens and signing secrets never go in gently.apps.yml or your repository. The config declares which names each app needs; the values are stored encrypted in Gentlybot, can't be read back, and reach every new sandbox for the project.

Declare the names

Put a name under top-level secrets: when every app in the repository shares one value, such as a server and a background worker from the same codebase. Put it under apps.<name>.secrets when apps need different values, such as apps in separate folders of a monorepo. Names are uppercase server-side variables: names exposed to the browser (VITE_…, NEXT_PUBLIC_… and similar) and names the sandbox sets (PORT, GENTLY_…) are refused.

secrets:                 # shared by every app in this repository
  SIGNING_SECRET: "Generate with: openssl rand -hex 32"

apps:
  api:
    startup: bin/rails server
    secrets:             # this app only
      PAYMENTS_API_KEY: "Payments dashboard > API keys (test mode)"
  worker:
    startup: bundle exec sidekiq

Add the values

  • On the Configure page: each repository has its own Secrets section, above Tools and Services, with one group per app. A repository with missing secrets opens by default. Use Add value or Replace on a row, Add secret for a new name, or the ⋯ menu to remove a value. Project admins can change values; other members see names and whether each is saved.
  • Paste .env: paste NAME=value lines to add or replace several secrets at once. Nothing is removed, and browser-exposed or reserved names are skipped with a note.
  • Edit all: saved values show as NAME=***. Leave *** to keep a value, type over it to replace it, delete a line to remove it, or add lines. You confirm removals before anything is saved, and every change lands together or not at all.
  • In a thread: when setup needs a value, Gentlybot asks whether you want to enter it now. If you do, a secure form opens; in a project with several repositories you choose the repository it belongs to. Project admins see Use in every new thread for this project, on by default; unchecked, the value reaches that thread only. A thread-only value can be moved to the project later from the thread's Environment tab.

Each value belongs to one app, or to all apps, in one repository. Two repositories can use the same variable name with different values, so app names must be unique across a project's repositories. Values reach the app's environment and its .env file, not repository-level setup: commands. New sandboxes receive them automatically; a running sandbox picks up a change after you rerun setup or restart the app.

If your team already keeps development secrets in 1Password, Gentlybot can load them instead of values added above. Keep secret values in 1Password, not in gently.apps.yml or your repository. Gentlybot loads the selected items into the sandbox environment for your apps.

  1. Create a 1Password service account with read access to the vault containing your development secrets, and copy its service account token.
  2. On the project’s Configure page, expand 1Password. Paste the token and select Save; then choose the vault and select its Save button. This vault is shared by the project’s item bindings.
  3. Create an item in that vault using one of the formats below. Copy its item ID (the item’s unique identifier), then expand the repository on Configure and add a onepassword block in its gently.apps.yml editor. Save the config and start or refresh the sandbox.

Option 1 · Note body

Put KEY=value lines in the item’s free-text note body, like a .env file. Choose source_type: note. Custom fields on the same item are not read in this mode.

API_TOKEN=your-value
PRIVATE_KEY="your-multiline-value"

Option 2 · Item fields

Add a separate Text or Concealed field for each variable. The field label is the variable name (for example API_TOKEN) and the field value is the secret. Choose source_type: fields. The note body is not read in this mode.

Add the block at the top level to share values across the repository’s apps, or under apps.<name> for one app. You can use both with different items. Replace the example IDs with IDs from the selected vault; item titles also work if unique, but IDs avoid ambiguity.

onepassword:
  source_type: note
  source_item_id: your-repo-item-id

apps:
  web:
    startup: pnpm dev
    onepassword:
      source_type: fields
      source_item_id: your-web-item-id