Local setup & troubleshooting
Docker, Postgres, and the Ollama path to a genuinely $0 stack.
Picking a provider
EVESTACK_PROVIDER selects the branch in agent/agent.ts. It is the only variable that does,
and EVESTACK_MODEL on its own never changes providers — it just hands a different model name
to whichever provider is already selected.
EVESTACK_PROVIDER | Key it reads | Default EVESTACK_MODEL |
|---|---|---|
unset, or openai | OPENAI_API_KEY | gpt-5-mini |
anthropic | ANTHROPIC_API_KEY | claude-sonnet-5 |
ollama | none | qwen3 |
create-evestack asks which one you want and writes both lines. Anything other than those three
values is rejected at boot with the list above rather than silently treated as OpenAI — a
misspelled provider is a mistake, not a preference.
One thing that table does not cover, and it decides whether long-term memory works: embeddings.
openai has an embeddings endpoint on the same key. ollama has one, but it is a second pull
(ollama pull nomic-embed-text). anthropic has none at all, so remember and recall on that
path need either an OPENAI_API_KEY as well or EVESTACK_EMBED_PROVIDER=ollama to run embeddings
locally. Nothing else about the Anthropic path is affected. The three EVESTACK_EMBED_* variables
are in long-term memory.
Ollama
For zero cost, total:
ollama pull qwen3 # the chat model
ollama pull nomic-embed-text # embeddings — a separate model, and `remember` needs itThen set both of these in .env.local:
EVESTACK_PROVIDER=ollama
EVESTACK_MODEL=qwen3EVESTACK_PROVIDER is the one that selects the local path. The model name on its own is handed
to the OpenAI provider, and the agent then refuses to boot:
Cannot compile agent compaction because the primary compaction trigger model
"openai/qwen3" does not have known AI Gateway context window metadata.create-evestack offers this as an option at scaffold time and writes both lines for you.
Two more, both optional:
OLLAMA_BASE_URL=http://127.0.0.1:11434 # bare host — no /api suffix
EVESTACK_CONTEXT_WINDOW=32768 # qwen3's native windowai-sdk-ollama appends the API path itself, so a OLLAMA_BASE_URL ending in /api gives
OllamaError: 404 page not found. EVESTACK_CONTEXT_WINDOW is what the template passes to
eve's modelContextWindowTokens — the escape hatch that skips the catalog lookup entirely.
Raise it for a model with a bigger window; set it too high and compaction fires too late to
save the turn. Both are ignored on the hosted providers, whose models the catalog does know.
Check your free RAM first. qwen3 is 5.2 GB, and it loads on top of Docker, Postgres, the dashboard and the agent — plus the 274 MB embedding model once memory is used. On a machine without roughly both model sizes + 4 GB to spare, this does not degrade gracefully — it can take minutes to answer a one-word prompt and can take the host down. On a laptop already running the rest of the stack, a hosted key is the practical choice.
Local models generally have weaker tool-calling than gpt-5-mini or Claude. That's the honest tradeoff for $0 total cost — try it, and switch to a cloud key if tool use feels unreliable.
What it costs on disk
The RAM warning above is the one that bites first, but disk is the one nobody budgets for. Measured on macOS with Colima, one project, clean Docker:
| With an API key | On the $0 Ollama path | |
|---|---|---|
| Docker images | ~2.0 GB | ~2.0 GB |
| Postgres volume | ~70 MB | ~70 MB |
| Project directory | ~300 MB | ~300 MB |
qwen3 + nomic-embed-text | not pulled | 5.5 GB |
| Total | ≈ 2.4 GB | ≈ 7.9 GB |
Budget 10 GB free on the local-model path, 4 GB with an API key. That leaves room to grow; the flat totals do not.
The image figure is pgvector/pgvector:pg17 at 646 MB, the dashboard at 1.05 GB unpacked from a
228 MB pull, and a 665 MB sandbox template image eve builds on first run, less the node:24-slim
layers two of them share. The project directory is almost entirely node_modules (262 MB
measured); .eve/ accounts for the rest and grows while eve dev is running.
Each additional project on the same machine costs about 0.5 GB. The big images are shared —
its own sandbox template image (+157 MB), its own Postgres volume (~70 MB) and its own
node_modules are not.
What grows, and the one thing nothing cleans up
Spans are about 1.55 KB each and self-prune on a 30-day window (EVESTACK_TRACE_RETENTION_DAYS).
The workflow schema never prunes itself; npm run db:prune is the manual answer to both,
and Operations covers it — including why space is not returned to the
filesystem without a VACUUM FULL.
The exception is the per-project eve-sandbox-template:* image. eve builds one per project,
tagged with a hash of the project id, and at 665 MB it is the third-largest single item on disk.
Nothing removes it: no evestack command, no docker compose down -v, and not deleting the
project directory either. It outlives the project that created it, and a cleanup on the
development machine reclaimed several GB from seven stale ones that had accumulated this way.
# what is actually there
docker images --filter reference='eve-sandbox-template:*'
# remove them — `docker image prune` rejects a reference filter, so list and pipe
docker images --filter reference='eve-sandbox-template:*' -q | xargs docker rmiDo that after you delete a project, not while one is running: the tag carries no hint of which project it belongs to, and a live project rebuilds its own on the next turn.
Docker sandbox
The default backend, docker(), keeps one long-lived container per durable session and
persists /workspace across turns with no idle timeout — genuinely free to run 24/7 on
your own machine, since it's just a container.
Swaps, one line in agent/sandbox/sandbox.ts:
microsandbox()— real VM isolation, domain-level network policies, credential brokering. macOS on Apple Silicon or Linux with KVM only.justbash()— no daemon at all, but no real binaries either.
Common issues
eve dev seems to not be listening on port 2000.
It is listening on EVESTACK_AGENT_PORT from .env.local, which the scaffolder set to the
first free port at or above 2000 at the time you scaffolded — so on a machine that already
had something on 2000, it is 2001 or higher. npm run dev passes that number to eve dev as
--port, and eve only scans for a free port when it is given none, so nothing auto-increments
at boot: if that port is busy now, you get EADDRINUSE and no server. Read .env.local for
the number, and free the port rather than waiting for eve to move.
A follow-up request 404s or the agent seems to have forgotten everything.
Check that WORKFLOW_POSTGRES_URL is actually set and Postgres is reachable — without it,
eve silently falls back to its local on-disk world under .eve/.workflow-data, which does
not survive a container rebuild the way Postgres does.
@workflow/world-postgres fails at boot with a protocol or spec version error.
It is not pinned to an exact version somewhere. eve needs the 5.0.0-beta line, so npm's
latest (the 4.x line) is wrong — and so is the beta dist-tag, which now resolves past the
release eve 0.30.8 can talk to. Pin 5.0.0-beta.32 exactly; see
Troubleshooting for the spec-version message.
The dashboard can't reach the database.
It reads WORKFLOW_POSTGRES_URL directly — same variable, same database, as the agent. If the
agent works but the dashboard doesn't, the two processes likely have different .env.local
files with different values.
Reverse-proxying either the agent or the dashboard.
Forward /eve/ and /.well-known/workflow/, unrewritten. Forwarding only /eve/ lets a
session start, then stalls it forever — the workflow callback can't get back in.