Skip to content

Run with Docker

Docker Compose runs Evarness as a set of services that stay up: the Evarness API (with the web console and the scheduled email jobs), the Governor, and Ollama. It builds the image from a clone of the repository.

git clone https://github.com/evarness-ai/evarness.git
cd evarness
echo "EVARNESS_AUTH_SECRET=$(openssl rand -hex 32)" >> .env   # once; .env is git-ignored
docker compose up        # or: make up

Put the secret in .env rather than exporting it. An export lasts for one shell, and Compose needs the variable for every docker compose command, not only up (see below).

On Windows, see Windows for the PowerShell version of the secret and for using Ollama for Windows.

Service Port Role
ollama 11434 The local model runtime.
ollama-init One shot: pulls the tier models, then exits.
governor 8080 The HTTP front of the governance kernel: policy, rate limits, audit.
evarness-api 8003 Chat, streaming chat, and the web console.

Every port binds to 127.0.0.1. evarness-api waits for the Governor to be healthy and for the models to finish pulling, so the first start is slow (about 6 GB of model weights) and later ones are fast.

If Ollama is already running on the host, it holds port 11434 and docker compose up stops with bind: address already in use. Quit the host Ollama, or use make up-host below, which runs Evarness in Docker against it.

Memory

The models run on the CPU inside the Docker VM, so they count against the memory Docker Desktop gives it. With 8 GB (Docker Desktop's default on many Macs; it showed 7.75 GiB), the stack started and a plain turn answered, but a turn that needed qwen2.5:7b-instruct (16K context) failed twice with LLM error: llama-server process has terminated: signal: killed, and docker inspect showed the Ollama container OOMKilled=true. The 3B router model loaded fine. Give Docker more memory (Docker Desktop, Settings, Resources), or use make up-host and let a native Ollama run the models. We have not measured how much memory the 7B tier needs, so treat anything above 8 GB as untested. The lite model set that evarness doctor picks for an 8 GB machine (one 4B model for tier 2 and the email judge) is a native-install path: ollama-init pulls the shipped tiers, not a set, and running the stack on lite has not been tried.

If you see signal: killed from Ollama, check docker inspect <ollama container> --format '{{.State.OOMKilled}}' first.

The one required variable

Compose refuses to load docker-compose.yml without EVARNESS_AUTH_SECRET. That applies to every docker compose subcommand, including ps, logs, exec and down, which start nothing. In a new terminal where the variable is not set they stop with:

error while interpolating services.governor.environment.EVARNESS_AUTH_SECRET: required variable EVARNESS_AUTH_SECRET is missing a value

The stack is not broken; Compose cannot read the file. Keep the secret in .env (Compose reads it from there for every command) or export the same value again. Use the same value as the one the running containers started with: the API authenticates calls against it, so a different one is a different login. make down and make logs set a placeholder themselves, since they never use the value. The requirement is deliberate: a shipped default would be a publicly known secret.

Every API call except the /healthz probe must carry it as a bearer token. A secret in .env is read by Compose, not exported to your shell, so load it for the call:

export EVARNESS_AUTH_SECRET="$(grep '^EVARNESS_AUTH_SECRET=' .env | cut -d= -f2-)"
curl -s localhost:8003/chat -H "authorization: Bearer $EVARNESS_AUTH_SECRET" \
  -H 'content-type: application/json' \
  -d '{"message": "what time is it?", "session_id": "demo"}'

Everything else defaults to local-only: the model endpoints point at the bundled Ollama. A .env beside docker-compose.yml (see .env.example) is where credentials and overrides go; it is loaded when present.

No trace UI runs in the stack. To see OpenTelemetry traces, run a backend of your own and set OTEL_EXPORTER_OTLP_ENDPOINT in .env (from a container, the host is host.docker.internal); see Send traces to your backend.

On a Mac: Metal-accelerated models

Ollama in a container runs on the CPU. For Metal speed, run Ollama natively (ollama serve, with the tier models pulled) and start Evarness against it:

make up-host

Lifecycle

make logs                # follow evarness-api and the Governor
make down                # stop and remove the stack; the volumes stay
docker compose down -v   # also drop the data and model volumes

The web console

Open http://127.0.0.1:8003/ in a browser. The page is served without a token, but only to a browser navigation (it sends Sec-Fetch-Mode: navigate); a bare curl of / gets a 401, as does any data call without the bearer token.

Models

ollama-init pulls the models config/llm_tiers.yaml routes to (the standard model set; evarness doctor's host sizing does not run in the stack). To change them, edit both that file and the ollama-init command in docker-compose.yml, or pull by hand:

docker compose exec ollama ollama pull <model>