Docker Compose

deploy/compose.yaml is the reference way to run Ragz's infrastructure services. It does not run the Ragz API or frontend themselves — those run natively against these services (see Linux, macOS, or Windows) during development, or behind a reverse proxy in Production.

Why services aren't in Compose

Keeping the API/worker/frontend outside Compose keeps the dev loop fast — no image rebuild to see a code change — while still giving you real Postgres, Redis, and Qdrant instead of mocks.

What it brings up

docker compose -f deploy/compose.yaml up -d
ServiceImagePurpose
postgrespostgres:16-alpineTenancy, metadata, encrypted secrets, audit log
redisredis:7-alpineCelery queues, quota counters
qdrantqdrant/qdrant:v1.18.0Vector store for hybrid retrieval
miniominio/minio:latestS3-compatible object storage for uploaded documents
teitext-embeddings-inference:cpu-1.8Local embedding server (BAAI/bge-m3) — opt-in
tei-reranktext-embeddings-inference:cpu-1.8Local reranker (BAAI/bge-reranker-v2-m3) — opt-in
litellmlitellm:main-stableUnified LLM gateway/proxy in front of any provider
dexdexidp/dex:v2.41.1OIDC provider for manual SSO testing — opt-in

postgres, redis, qdrant, minio, and litellm start by default. tei, tei-rerank, and dex are behind Compose profiles and only start when you ask for them:

# Hosted embeddings + hosted rerank (default; no local model servers)
docker compose -f deploy/compose.yaml up -d
 
# Hybrid: also run a local reranker
docker compose -f deploy/compose.yaml --profile ml up -d
 
# Fully local / air-gapped: local embedder + local reranker
docker compose -f deploy/compose.yaml --profile ml --profile local-embeddings up -d
 
# Add the Dex OIDC provider for SSO testing
docker compose -f deploy/compose.yaml --profile sso up -d

First start downloads model weights

tei and tei-rerank each download roughly 2.3 GB of model weights into their own named volume the first time they start. start_period in their health checks allows up to 180s for this — don't be alarmed if docker compose ps shows them as unhealthy for a while on first run.

Ports

Every service binds to 127.0.0.1 only — nothing here is reachable from outside the host, by design. A reverse proxy is the only thing that should ever be exposed publicly (see Production).

ServiceHost portContainer port
Postgres554325432
Redis563796379
Qdrant563336333
MinIO API590009000
MinIO Console590019001
TEI (embeddings)5808080
TEI (rerank)5808180
LiteLLM540004000
Dex555565556

The non-default host ports (55432 instead of 5432, and so on) mean this stack won't collide with services you already have running locally.

Volumes and where data lives

VolumeHolds
pgdataThe Postgres data directory — orgs, workspaces, users, encrypted secrets, audit log, document/job metadata
qdrantdataVector index (embeddings + payload for ACL filtering)
miniodataUploaded document originals
teidataDownloaded embedding model weights
teirerankdataDownloaded reranker model weights

The Key Encryption Key (KEK) used to envelope-encrypt provider secrets in Postgres is not a Docker volume — it's a file on the backend host, backend/data/ragz_kek by default (override with RAGZ_KEK_FILE). It's the one secret that lives outside the database.

Back up pgdata and the KEK together

Losing the KEK file makes every provider key stored in pgdata permanently unrecoverable, even though the encrypted bytes are still in Postgres. Back up both, and keep them together. See Backups for a full backup/restore procedure.

Starting and stopping

# Start (detached)
docker compose -f deploy/compose.yaml up -d
 
# View status / health
docker compose -f deploy/compose.yaml ps
 
# Tail logs for one service
docker compose -f deploy/compose.yaml logs -f qdrant
 
# Stop, keep data
docker compose -f deploy/compose.yaml stop
 
# Stop and remove containers, keep volumes (data survives)
docker compose -f deploy/compose.yaml down
 
# Stop and remove containers AND volumes (destroys all data — dev only)
docker compose -f deploy/compose.yaml down -v

down -v deletes everything

down -v removes the named volumes, including pgdata and qdrantdata. There is no confirmation prompt. Never run it against a deployment you care about.

Changing default credentials

The Compose file ships with fixed dev credentials — POSTGRES_PASSWORD, MINIO_ROOT_PASSWORD, LITELLM_MASTER_KEY, LITELLM_SALT_KEY — meant only for local development. Override them (via environment variables or by editing deploy/compose.yaml) before running anywhere reachable beyond your own machine. See Configuration and Production for the full checklist.

Next steps

  • Configuration — environment variables and app settings that sit on top of this infrastructure.
  • Production — reverse proxy, TLS, scaling, and the full credential-hardening checklist.