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| Service | Image | Purpose |
|---|---|---|
postgres | postgres:16-alpine | Tenancy, metadata, encrypted secrets, audit log |
redis | redis:7-alpine | Celery queues, quota counters |
qdrant | qdrant/qdrant:v1.18.0 | Vector store for hybrid retrieval |
minio | minio/minio:latest | S3-compatible object storage for uploaded documents |
tei | text-embeddings-inference:cpu-1.8 | Local embedding server (BAAI/bge-m3) — opt-in |
tei-rerank | text-embeddings-inference:cpu-1.8 | Local reranker (BAAI/bge-reranker-v2-m3) — opt-in |
litellm | litellm:main-stable | Unified LLM gateway/proxy in front of any provider |
dex | dexidp/dex:v2.41.1 | OIDC 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 -dFirst 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).
| Service | Host port | Container port |
|---|---|---|
| Postgres | 55432 | 5432 |
| Redis | 56379 | 6379 |
| Qdrant | 56333 | 6333 |
| MinIO API | 59000 | 9000 |
| MinIO Console | 59001 | 9001 |
| TEI (embeddings) | 58080 | 80 |
| TEI (rerank) | 58081 | 80 |
| LiteLLM | 54000 | 4000 |
| Dex | 55556 | 5556 |
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
| Volume | Holds |
|---|---|
pgdata | The Postgres data directory — orgs, workspaces, users, encrypted secrets, audit log, document/job metadata |
qdrantdata | Vector index (embeddings + payload for ACL filtering) |
miniodata | Uploaded document originals |
teidata | Downloaded embedding model weights |
teirerankdata | Downloaded 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 -vdown -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.