Zekra
القائمة · Zekra

Self-hosting

Run your own Zekra instance with Docker, including its dependencies, configuration, schema setup and first admin.

Zekra is open source (github.com/fadymondy/zekra). It ships as one Go binary that serves the REST API, the web console, GraphQL and an OpenAPI description on a single port (:8080).

Requirements

ComponentRequiredPurpose
PostgreSQL with the vchord, vchord_bm25, pg_tokenizer and pg_partman extensions (VectorChord)yesMemories, vector index, BM25 keyword index, entity graph, accounts
Embedding server, Text Embeddings Inference (TEI) with a 1024-dimension modelyes, for retain and recallEmbeddings. The reference setup uses Qwen/Qwen3-Embedding-0.6B. The schema's vector column is 1024-dimensional, so the model must match.
Reranker, TEI with a reranker modelrecommendedReranks recall results. The reference setup uses BAAI/bge-reranker-v2-m3.
RedisoptionalShared recall cache. An in-process cache is used otherwise.
Chat LLM: an Ollama-compatible endpoint, or an Anthropic API keyoptionalbrain_chat and POST /api/brain/chat
CogneeoptionalAn external engine for entity-graph extraction
Mail: a Resend API key or SMTPrecommendedVerification codes, sign-in codes and export links

Without an embedding server, retain and recall return 503 no_embedder. Everything else keeps working.

1. Build

The generated code (internal/**/gen) is not committed, so run code generation before you build. Code generation uses the togo CLI.

sh

The Dockerfile builds the web console and the API into a distroless image that listens on :8080.

2. Configure

Copy .env.example to .env and fill it in. These are the settings that matter most:

Core

VariableNotes
APP_ENVproduction fails closed on missing secrets
APP_URLPublic base URL, such as https://zekra.example.com
DATABASE_URLpostgres://user:password@host:5432/zekra?sslmode=require
DB_DRIVERpgx
AUTH_SECRETRequired. At least 32 bytes (openssl rand -hex 32). Signs sessions. If it is unset, sessions end on every restart.
ZEKRA_SECRETS_KEY64 hex characters. Encrypts the secrets vault. If unset, it is derived from AUTH_SECRET. Keep it stable, or stored secrets become unreadable.
VAULT_KEY32 bytes (hex or base64). Encrypts two-factor secrets. Falls back to ZEKRA_SECRETS_KEY, then AUTH_SECRET. Set it in production.
ZEKRA_PUBLIC_URLURL placed in the MCP configs that the session launcher generates. Defaults to APP_URL.

Access control

VariableNotes
ZEKRA_REQUIRE_AUTH1 requires a session or token on every brain endpoint. Set it on any public instance.
ZEKRA_REQUIRE_TOKEN1 stops treating tokenless requests as trusted admin requests
ADMIN_EMAILSComma-separated emails that get the console admin role
ALLOW_REGISTRATIONfalse closes sign-up

See Security for what each switch does.

Retrieval

VariableNotes
TEI_EMBEDDINGS_URLEmbedding server, such as http://tei-embed:80
TEI_EMBEDDINGS_DIM1024
TEI_RERANKER_URLReranker server (optional)
BRAIN_BM25_TOKENIZERBM25 tokenizer name. Leave it at the default unless you install a custom multilingual tokenizer.
BRAIN_HNSW_EF_SEARCHVector search breadth (optional tuning)
CACHE_DRIVER, REDIS_URL, BRAIN_RECALL_CACHE_TTLmemory (default) or redis. The TTL is in seconds; 0 turns off recall caching.

Chat

VariableNotes
BRAIN_CHAT_LLM_URL, BRAIN_CHAT_LLM_MODEL, BRAIN_CHAT_LLM_KEYOllama-compatible endpoint. Fall back to EXTRACTION_LLM_URL, EXTRACTION_LLM_MODEL and EXTRACTION_LLM_API_KEY.
ANTHROPIC_API_KEY (or BRAIN_CHAT_ANTHROPIC_KEY), BRAIN_CHAT_ANTHROPIC_MODELUse Claude for chat instead
BRAIN_CHAT_LLM_TOOLS0 turns off the tool-calling agent and uses single-shot answers

Graph engine (optional)

COGNEE_API_URL, COGNEE_API_TOKEN, COGNEE_ADMIN_EMAIL. If COGNEE_API_URL is unset, the engine is off, and the graph is built from memory metadata instead.

Accounts and mail

VariableNotes
AUTH_PUBLIC_URLPublic origin for OAuth callbacks and email links. Falls back to APP_URL.
RESEND_API_KEY, MAIL_FROMEmail delivery. Without a key, production cannot deliver codes, and development only logs them.
OAUTH_GOOGLE_CLIENT_ID, OAUTH_GOOGLE_CLIENT_SECRETGoogle sign-in. Callback: <AUTH_PUBLIC_URL>/api/auth/google/callback
OAUTH_GITHUB_CLIENT_ID, OAUTH_GITHUB_CLIENT_SECRETGitHub sign-in. Callback: <AUTH_PUBLIC_URL>/api/auth/github/callback
APPLE_SERVICES_ID, APPLE_TEAM_ID, APPLE_KEY_ID, APPLE_PRIVATE_KEY_PATH (or APPLE_PRIVATE_KEY)Apple sign-in, HTTPS only. Callback: <AUTH_PUBLIC_URL>/api/auth/apple/callback
SESSION_DRIVERcookie (default) or database. With database, admins can list and revoke individual sessions.

A sign-in provider is enabled only when its credentials are set. Otherwise its routes return 404.

Never commit .env or bake secrets into the image.

3. Apply the schema

Zekra's schema is applied by the zekractl ops tool, not on startup:

sh

This applies the account schema, the brain schema and the BM25 layer. It is idempotent. If the database role cannot use the BM25 extension's catalogs, the BM25 step is skipped and recall falls back to vector-only search. To fix that, have a superuser run infra/grant-bm25.sql, then run zekractl bm25.

Other zekractl commands:

CommandWhat it does
zekractl inspectShow extensions, tables, tokenizer, BM25 index and row counts
zekractl bm25Apply only the BM25 layer
zekractl bm25-testSeed a few multilingual rows and run a BM25 query
zekractl admin <email>Give an existing account the admin role
zekractl mirror <namespace>Copy a brain's Cognee graph into Zekra's entity tables

4. Run

sh

Put a TLS-terminating reverse proxy in front of it for public use. The console, API and SSE stream are all served from the same origin.

5. Verify

sh

Then register at /register with an address listed in ADMIN_EMAILS (or run zekractl admin <email>), open Admin → Tokens, mint a token, and point the CLI at your instance:

sh

Local development

sh

Legacy CABRAIN_* environment variable names are still read. A ZEKRA_* value always wins.