# Deployment
URL: /docs/alineod/getting-started/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](/docs/alineod/guides/crash-recovery)).

## Configuration [#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 [#docker]

The image builds the whole monorepo (alineod depends on the SDK workspace packages), so build from the repo root:

```bash
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 \
  alineod
```

Or with Compose:

```bash
NVIDIA_API_KEY=nvapi-... docker compose -f apps/alineod/docker-compose.yml up --build
```

The 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 [#networking]

alineod talks to OpenSandbox over HTTP only. It does **not** need the Docker socket: OpenSandbox creates the
agent containers, not alineod.

<Callout type="warn" title="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).
</Callout>

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-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:

```bash
cd apps/alineod
bun run spec    # writes specs/alineod/openapi.json and specs/alineod/events.schema.json
```
