Install
Core runs on one machine from one Compose file: PostgreSQL, OpenSandbox, and the orchestrator, which serves the operator app. Nothing else is needed: no cloud account, no email or payment provider, no reverse proxy. Every guild and every agent sandbox runs on that machine.
Requirements
- Docker with the Compose plugin. Sandboxes are containers the stack starts beside itself, so the stack mounts the Docker socket.
- git and bash.
- Disk for the images and for agent workspaces. The runtime image downloads a browser and toolchains and takes several minutes to build the first time.
Node and pnpm are not needed to run the stack. They are for development.
Start
git clone <this repository> && cd <it>
./setup.sh
docker compose up --detach --waitThen open http://127.0.0.1:8080/.
./setup.sh:
- copies
.env.exampleto.env(mode 600) when there is none; - writes the four values the stack cannot start without and nobody should pick by hand:
STATE_ROOT, the absolute path the stack keeps its state under (.statein the checkout),SECRETS_MASTER_KEY,POSTGRES_PASSWORD, andOPENSANDBOX_API_KEY; - creates the state directories under
STATE_ROOT:notes/,workspaces/,attachments/,postgres/, andopensandbox/; - builds the three images no registry publishes (
scripts/images.sh): the OpenSandbox server, from its pinned commit, and the two images agents run in, fromruntime/:agent-runtime:0.3for a standard box (coding and a browser) andagent-runtime-lite:0.1for a lite box (scripts and a terminal, nothing else).
Running it again keeps every value .env already has. It refuses to generate a secret when STATE_ROOT/postgres already holds a database, since that database was created with values only its owner has: put those values into .env, or point STATE_ROOT at an empty directory. ./setup.sh --env-only writes .env and the directories and builds no image.
The standard runtime image installs Google Chrome on amd64 and Debian's Chromium on arm64. To use Chromium everywhere:
docker build --build-arg BROWSER=chromium --tag agent-runtime:0.3 runtime/Without .env the stack does not resolve: each missing value says run ./setup.sh first, which writes it into .env. The first docker compose up builds the orchestrator image (apps/orchestrator/Dockerfile) from the checkout, and --wait returns once every service is healthy.
What runs
| Service | Role | Published |
|---|---|---|
orchestrator | The control plane and the operator app | 127.0.0.1:8080 (ORCHESTRATOR_PORT) |
postgres | The database | No |
opensandbox | Starts and stops agent sandboxes through the Docker socket | No |
Only the orchestrator is published, on loopback. Sandboxes have Docker bridge egress, so agents reach the public internet.
STATE_ROOT is an absolute path on the Docker host because OpenSandbox mounts each agent's workspace into its sandbox by that same path. It holds postgres/ (the database), workspaces/ (one directory per agent, mounted at /home/agent in its sandbox), attachments/ (uploaded chat images), notes/, and opensandbox/ (the sandbox server's store).
The first operator
Boot applies the migrations and, on a database with no user, creates one user, operator, who owns the organisation Home. The stack does not authenticate: whoever reaches the port is that operator, and the app opens on them with no sign-in. Giving other people accounts, and reaching the box from another machine, is Remote access.
The first model key
A run needs one model key: the server's, in .env (OPENROUTER_API_KEY or DEEPINFRA_API_KEY, then docker compose up --detach --wait again), or the organisation's own under Settings, Model keys. Until one exists, a banner above every page says so and names both ways to give one, the model picker marks each model with No … key yet, and a run on that model fails at its first model call with the variable's name. Every other key in .env is optional (Configure).
Next: Your first guild.