Web Apps

A web app task runs a long-lived process that serves traffic on a publicly accessible URL under rwx.run. Web apps spin up on demand and spin down when idle, making them well-suited for previewing branch changes before merge — whether the reviewer is a human or an agent.

A web app task looks like this:

tasks:
  - key: my-app
    use: [build]
    app:
      endpoint: my-app-pr-${{ init.pull-request-number }}
      port: 3000
    run: pnpm start
  • The endpoint will be part of the app's subdomain, and must be alphanumeric or hyphens (no underscores).
  • The port is what will bind to your server process, and must be between 1024 and 49151.

Startup Timeout

By default, a web app is given 1 minute to start up. After this, the app's task is marked as a failure. You can override this by configuring timeout:

tasks:
  - key: my-app
    use: [build]
    app:
      endpoint: my-app-pr-${{ init.pull-request-number }}
      port: 3000
      timeout: 2m
    run: pnpm start

Idle Timeout

A web app spins down after 10 minutes of inactivity. If a user hits the URL after that, the app restarts on demand.

To print the preview link or send it somewhere (e.g. as a PR comment, a Slack message, etc), you can set up a follow-up task like this:

- key: share-link
  run: echo "$MY_APP_URL"
  env:
    MY_APP_URL: ${{ tasks.my-app.app.url }}

The above prints the canonical URL, which is pinned to the cache key of the task. Use it when you want the URL to keep pointing at the same build — for example, in integration tests that should hit a stable target. The canonical URL is shaped like:

https://{task-cache-key}--{org-slug}.{region}.rwx.run

If you'd rather the URL track the latest build for a given endpoint (so a shared PR link automatically picks up new commits), use tasks.my-app.app.url.friendly instead. The friendly URL is shaped like:

https://{endpoint}--{org-slug}.{region}.rwx.run

Backing Services

Most apps need a database, cache, or other supporting services running alongside them. Use background-processes to start them up before your app boots:

tasks:
  - key: my-app
    use: [build]
    docker: true
    background-processes:
      - key: services
        run: docker compose up
    app:
      endpoint: pr-${{ init.pull-request-number }}
      port: 3000
    run: pnpm start

For apps that talk to backing services on startup, add a ready-check to avoid race conditions.

Web app tasks support most of the same configuration as command tasks, including env and filter.