Skip to main content
The repository ships a docker-compose.yml that starts the board, the driver, Postgres, an S3-compatible object store (RustFS) and a telemetry collector. The driver runs each task as a container on the same Docker daemon (EXECUTOR=docker, the default).
This is a single-machine stack for trying Bellows and for small private setups. Every published port is bound to 127.0.0.1, and the driver mounts /var/run/docker.sock, which is root on the host. Read Security first. For a team deployment use Kubernetes.
The dashboard and driver services run the repository’s working tree (npm run dev), bind-mounted into the container. The first start installs dependencies and builds, so it takes a few minutes. Edits to the checkout take effect without a rebuild.

Before you start

  • Docker with the Compose plugin, make, and Node.js 22 or newer.
  • A GitHub App and a GitHub OAuth App. Follow GitHub App. For local use, set the OAuth callback to <PUBLIC_URL>/api/auth/github/callback with PUBLIC_URL=http://127.0.0.1:5173.
  • A model credential for the agent, such as CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY.

Steps

1

Clone the repository

2

Create the secret-store keys

The board needs encryption keys on every boot. They live in secrets.env, never in .env.
It writes a gitignored secrets.env with fresh keys (SECRETS_BACKEND=database) and leaves an existing file unchanged. Back this file up: without the keys, stored secrets cannot be read.
3

Create .env

Set at least these in .env:Compose reads .env on its own. See Configuration for every variable.
4

Build the executor images

This builds claude-executor and opencode-executor on the local daemon. Rebuild after you change anything under docker/<executor>/, or the driver keeps using the old image.
5

Start the stack

Wait until the board answers:
6

Sign in and run a task

Open http://127.0.0.1:5173. This is the Vite dev server, which proxies /api to the board. Port 8080 serves the API only in this mode. Sign in with GitHub, add an executor profile, then follow Run tasks.
Compose names its network after the project directory, which defaults to the directory name. The driver joins runners to RUNNER_NETWORK, which defaults to factory-ai_default. If you cloned into a folder named bellows, set RUNNER_NETWORK=bellows_default in .env (or COMPOSE_PROJECT_NAME=factory-ai). Without the right network, the agent still works but its telemetry goes nowhere.

Services and ports

Authentication for a local trial

AUTH_MODE has two values: github and none. If you want none, run the board on the host with npm run dev and keep it on 127.0.0.1. A GitHub App is still required.

Where data lives

docker compose down keeps all volumes. docker compose down -v deletes them, including the database.

Logs

Task logs are on the task page in the web app.

Upgrade

1

Back up

2

Pull and rebuild

The containers run npm install on start, then the board applies new database migrations at boot.
Releases only add to the schema, so a rollback to the previous version runs against the newer schema.

Other Make targets