Runs on your machine AGPL-3.0 GitHub

Install

A single Docker Compose stack, one config file, and a setup script executed twice—first to write, then to build.

Requirements

Docker Desktop, or Docker Engine with Compose v2. That is the whole list. Everything else - the web server, the worker, Postgres, Redis, Jupyter and the local model server - comes up as containers.

A GPU is optional. The base stack runs the models on CPU, which is fine for the small defaults; see GPU acceleration below to use a card you already have, or to point Tzara at an inference server running elsewhere.

Get the code

Download the zip from the repository, or clone it:

git clone https://github.com/joseph-coleman/tzara.git tzara
cd tzara

Run setup twice

The first run copies .env.template to .env, generates a strong random POSTGRES_PASSWORD, and then stops. That pause is deliberate: Postgres bakes the password in on first start and cannot change it afterward, so you get a chance to review your settings before anything is built.

./setup.sh          # macOS / Linux
.\setup.ps1         # Windows PowerShell

Now open .env and check the settings that are painful to change later - where your vaults live, which models to use, GPU versus external inference. The defaults just work if you only want to try it out, and your Docker configuration can always be changed later.

When you are happy, run the same command again. This time it builds and starts the stack:

./setup.sh          # (or .\setup.ps1) - second run builds and starts

On this first build it also pulls the two default local models (llama3.2:3b for chat, embeddinggemma:300m for embeddings) via the ollama-init service, which can take several minutes on a fresh machine. On Lemonade, Llama-3.2-3B-Instruct-GGUF:latest and embeddinggemma-300m-qat-q8_0-GGUF-Q8_0 are the equivalents - and if you have the RAM, go bigger on the chat model, which needs completion plus tools.

When it is up

  • Wiki: http://localhost:8000/
  • Readiness check: http://localhost:8000/health

/health returns a single JSON status for Postgres, Redis, Ollama, and whether your chat and embedding models are present. Check it first if anything looks broken.

Configuration

All configuration lives in .env, copied from .env.template. It is read at runtime by the containers - change a value and docker compose up again, with no image rebuild. .env is git-ignored and docker-ignored, so your secrets never end up committed or baked into an image layer.

The defaults are chosen to work with zero edits. These are the handful you are most likely to touch:

VariableWhat it doesDefault
VAULTS_LOCATION Parent directory of your vaults; each subdirectory is one isolated vault. Point it at your notes root. ./app/vaults
HISTORY_LOCATION Where per-vault git history is stored. Keep it off any Dropbox or OneDrive-synced path. ./app/vault-history
DEFAULT_VAULT Which vault the landing page opens. main
PORT Web server port. 8000
POSTGRES_PASSWORD Postgres auth. Setup writes a random one for you. Baked in on first start - it cannot be changed afterward. (generated)
OLLAMA_MODEL
OLLAMA_EMBED_MODEL
Chat and embedding model names. llama3.2:3b
embeddinggemma:300m

Storage for Postgres and Ollama models defaults to Docker-managed named volumes (pg_data, ollama_models), so there are no host paths to create. To keep that data at a specific host path instead - recommended once you are past trying it out - set POSTGRES_DATA_LOCATION and OLLAMA_MODELS to absolute paths in .env.

The ADVANCED block in .env.template documents everything else, including the LLM backend provider. The same configuration guide ships inside the wiki under help.

GPU and external inference

The base docker-compose.yml runs Ollama on CPU. To change that, layer an overlay by editing COMPOSE_FILE in .env:

# NVIDIA GPU
COMPOSE_FILE=docker-compose.yml;docker-compose.nvidia.yml
# AMD ROCm GPU
COMPOSE_FILE=docker-compose.yml;docker-compose.amd.yml
# An inference server you run elsewhere - stock Ollama, Lemonade,
# vLLM, LocalAI, etc. (set OLLAMA_URL + LLM_PROVIDER to point at it)
COMPOSE_FILE=docker-compose.yml;docker-compose.external-inference.yml

COMPOSE_PATH_SEPARATOR is ; on Windows and Docker Desktop, : on macOS and Linux.

With the external-inference overlay, no local Ollama container starts and the first-run model bootstrap is skipped - the models live on your server. The overlay is topology-only: it just removes the local container. Which server you talk to and how is set by OLLAMA_URL and LLM_PROVIDER in .env.

Setup catches the easy mistake. It refuses to build if OLLAMA_URL points at an external server but this overlay is not in COMPOSE_FILE - otherwise it would spin up a local Ollama container and download models you do not need. It tells you exactly what to add to .env; fix it and re-run.

By hand

setup is only a convenience wrapper. The equivalent manual steps are, basically:

cp .env.template .env
# edit .env - at minimum set a real POSTGRES_PASSWORD (setup generates
# one for you; by hand you must pick one BEFORE the first `up`, as it
# cannot change later)
docker compose up --build

Updating help pages

Help documentation is seeded into the system vault once, on first run, and is yours thereafter - upgrading Tzara never overwrites it. To pull in a newer version's help pages when you want them:

./refresh-docs.sh                             # dry run: report what would change
./refresh-docs.sh --apply                     # refresh pages you still have
./refresh-docs.sh --apply --restore-missing   # also re-add ones you deleted

On Windows, run refresh-docs.bat. The refresh touches only help/ and the root pages - example agents and editors are opt-in per file via --include - never deletes, and commits each page's previous version first, so the whole run is revertable from the vault's git history. Tzara needs to be running for it to work.