> For the complete documentation index, see [llms.txt](https://docs.zenml.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.zenml.io/kitaru/getting-started/deploy/docker.md).

# Docker

Run the Kitaru server with Docker, using Compose for one host or the server container against your own Postgres.

The server is one container plus Postgres. Compose runs both on a single host; for anything bigger, run the server container against a managed Postgres and keep the same environment variables.

## CLI-managed local deployment

For one local deployment per user, let the CLI own the lifecycle:

```bash
kitaru login --local
```

Requires [Docker](https://docs.docker.com/get-started/get-docker/) with the [Compose v2 plugin](https://docs.docker.com/compose/install/), or [Podman](https://podman.io/docs/installation) with Compose support. The CLI runs the version-matched `zenmldocker/kitaru-server` image with PostgreSQL kept private to the Compose network, stores generated runtime secrets in the Kitaru configuration directory, and opens the selected local URL once healthy (`http://localhost:8000` by default). Use `kitaru login --local --port 9000` or set `KITARU_LOCAL_PORT=9000` to expose it on another loopback port; the flag takes precedence and the selected port is persisted with the deployment. Existing images are reused without an automatic pull; `kitaru login --local --upgrade` is the explicit upgrade path, and `KITARU_LOCAL_IMAGE` points source builds at a locally built image. `kitaru local logs` inspects it; `kitaru logout` stops it (add `--volumes` to delete the database).

The rest of this page covers manually managed deployments, which are separate from the CLI-owned one.

## Docker Compose

The repository ships a Compose file that builds the server and starts Postgres beside it:

```bash
git clone https://github.com/zenml-io/kitaru.git
cd kitaru
docker compose up -d
curl http://localhost:8000/health
```

The shipped Compose file runs with `KITARU_SERVER_AUTH_SCHEME: none`, which is fine on your laptop but not for a shared server. For a team deployment, set the auth scheme to `local` and provide real keys (see below and [Authentication](/kitaru/running-in-production/authentication.md)).

## Configuration

The server is configured entirely through `KITARU_SERVER_*` environment variables. The ones every deployment should set:

| Variable                                                               | Meaning                                                                           |
| ---------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| `KITARU_SERVER_DB_HOST` / `DB_PORT` / `DB_USER` / `DB_PWD` / `DB_NAME` | Postgres connection, or one `KITARU_SERVER_DATABASE_URL` instead                  |
| `KITARU_SERVER_AUTH_SCHEME`                                            | `none` (open, dev only) or `local` (accounts + API keys)                          |
| `KITARU_SERVER_JWT_SIGNING_KEY`                                        | Secret for login tokens; set a long random value                                  |
| `KITARU_SERVER_SECRET_ENCRYPTION_KEY`                                  | Key encrypting stored [secrets](/kitaru/running-in-production/secrets.md) at rest |
| `KITARU_SERVER_DEFAULT_ACCOUNT_PASSWORD`                               | Bootstrap password for the `default` account                                      |
| `KITARU_SERVER_SERVER_URL`                                             | The externally reachable URL clients use                                          |

Operational knobs with sensible defaults; raise or lower them deliberately:

| Variable                                          | Default | Meaning                                                           |
| ------------------------------------------------- | ------- | ----------------------------------------------------------------- |
| `KITARU_SERVER_MAX_BLOB_SIZE_BYTES`               | 100 MiB | Upload cap for trace exports and plugin code                      |
| `KITARU_SERVER_PAYLOAD_OFFLOAD_THRESHOLD_BYTES`   | 20 KiB  | Session/node payload size above which it moves to blob storage    |
| `KITARU_SERVER_TASK_HEARTBEAT_TIMEOUT_SECONDS`    | 60      | How long a silent worker holds a task before it's requeued        |
| `KITARU_SERVER_TASK_RETRY_LIMIT`                  | 3       | Attempts before a stale task is abandoned                         |
| `KITARU_SERVER_JOB_PENDING_TIMEOUT_SECONDS`       | 3600    | How long a job waits unclaimed before it's canceled               |
| `KITARU_SERVER_EVALUATOR_TASK_TIMEOUT_SECONDS`    | 300     | Per-evaluator process timeout                                     |
| `KITARU_SERVER_IMPORTER_TASK_TIMEOUT_SECONDS`     | 600     | Per-import process timeout                                        |
| `KITARU_SERVER_EVALUATION_PAIR_LIMIT`             | 100     | Max (session × evaluator) pairs per batch request                 |
| `KITARU_SERVER_IDEMPOTENCY_KEY_RETENTION_SECONDS` | 900     | How long a stored response stays replayable for a retried request |
| `KITARU_SERVER_LOG_LEVEL`                         | `INFO`  | Server logging                                                    |

Database migrations run automatically at startup (`KITARU_SERVER_SKIP_DB_MIGRATION=true` disables that when you manage migrations yourself).

## The published image

For anything beyond a laptop, use the published server image instead of building from source:

```bash
docker run -d -p 8000:8000 \
  -e KITARU_SERVER_DB_HOST=your-postgres-host \
  -e KITARU_SERVER_DB_USER=... -e KITARU_SERVER_DB_PWD=... \
  -e KITARU_SERVER_AUTH_SCHEME=local \
  -e KITARU_SERVER_JWT_SIGNING_KEY=... \
  -e KITARU_SERVER_SECRET_ENCRYPTION_KEY=... \
  zenmldocker/kitaru-server:latest
```

Any container runtime works: the server listens on port 8000, runs as a non-root user, and all state lives in Postgres. Put TLS in front with your usual ingress or reverse proxy, and scale horizontally if needed, since the server is stateless between requests. On Kubernetes, use the [Helm chart](/kitaru/getting-started/deploy/helm.md), which wraps this same image with migrations, ingress, and secrets handled.

Workers are deployed separately, in the environments your agents live in. See [Workers in production](/kitaru/running-in-production/workers.md).

## First login

```bash
kitaru login https://kitaru.internal.example.com
kitaru status
```

Then create accounts and API keys for the team: [Authentication & API keys](/kitaru/running-in-production/authentication.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.zenml.io/kitaru/getting-started/deploy/docker.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
