Deployment
Configure alineod, run it as a Docker container, and connect it to OpenSandbox.
alineod is a single Bun process with two SQLite files and a working directory. It holds no in-memory state that can't be rebuilt, so the process — or its container — can be restarted or recreated freely (see Crash recovery).
Configuration
| Variable | Default | Description |
|---|---|---|
ALINEOD_PORT | 4600 | HTTP + SSE listen port. |
ALINEOD_DB_PATH | ./data/alineod.db | alineod's own state: the append-only swarm ledger and the agents/handles tables derived from it. |
ALINEOD_SDK_LEDGER_PATH | ./data/alineod-sdk-ledger.db | The SDK's sandbox ledger (sandbox, exec, and checkpoint events), shared by every agent alineod drives. |
ALINEOD_WORK_DIR | ./data/alineod-work | Spec files handed to spawn(), and stored agent results. |
ALINEOD_PROMPT_INACTIVITY_MS | 180000 | If a turn's stream produces nothing for this long, alineod follows the turn by polling instead. |
ALINEOD_TURN_MAX_MS | 1800000 | How long a polled turn may keep running (paused time excluded) before it's ended with partial output. |
ALINEOD_CATCH_UP_POLL_MS | 2000 | Interval between state polls while following a turn. |
ALINEOD_STATE_PROBE_TIMEOUT_MS | 5000 | Bound on one state poll, so an unresponsive agent can't stall alineod. |
ALINEOD_RESUME_BRIDGE_TIMEOUT_MS | 10000 | After a resume, how long to wait for the agent's harness to answer before restarting it. |
OpenSandbox connection settings come from alineo.config.json in the working directory, exactly as for the SDK
and CLI. Model-provider keys (NVIDIA_API_KEY, ANTHROPIC_API_KEY, …) are read from alineod's own environment
wherever a spec's env references them as ${VAR}.
Fixed limits, set in apps/alineod/config.ts:
- Socket idle timeout: 255 s (Bun's maximum — its ~10 s default would kill SSE and long-polls).
- SSE heartbeat: every 10 s.
GET /agents/:id/result?wait=is capped at 240 s.
Docker
The image builds the whole monorepo (alineod depends on the SDK workspace packages), so build from the repo root:
docker build -f apps/alineod/Dockerfile -t alineod .
docker run --rm -p 4600:4600 \
--add-host host.docker.internal:host-gateway \
-e ALINEO_SERVER_URL=http://host.docker.internal:8080 \
-e NVIDIA_API_KEY=nvapi-... \
-v alineod-data:/data \
alineodOr with Compose:
NVIDIA_API_KEY=nvapi-... docker compose -f apps/alineod/docker-compose.yml up --buildThe entrypoint writes /data/alineo.config.json from these variables before starting the server:
| Variable | Description |
|---|---|
ALINEO_SERVER_URL | OpenSandbox server URL. |
ALINEO_USE_SERVER_PROXY | Route sandbox traffic through the OpenSandbox server (true). |
ALINEO_API_KEY | OpenSandbox API key, if the server requires one. |
All state lives under /data — keep it on a volume.
Networking
alineod talks to OpenSandbox over HTTP only. It does not need the Docker socket: OpenSandbox creates the agent containers, not alineod.
Server proxy URLs and the eip
In server-proxy mode, OpenSandbox hands back sandbox URLs built from its own configured eip. If
that is http://localhost:8080, those URLs won't resolve from inside the alineod container.
Either put alineod on the same Docker network as OpenSandbox with a routable eip, or run the
container with --network host (the same as running alineod bare on the host).
alineod has also been run against an OpenSandbox server using gVisor (runsc) as its secure container runtime;
nothing in alineod depends on the runtime.
The protocol spec
The wire contract is defined once, as Zod schemas in apps/alineod/src/schema.ts. The running daemon serves an
interactive OpenAPI document at /openapi, and the schemas can be emitted to files for client generation:
cd apps/alineod
bun run spec # writes specs/alineod/openapi.json and specs/alineod/events.schema.json