Docker
Deploy bigRAG with Docker Compose.
Quick Start
Pull the images
docker pull yoginth/bigrag-api:2026.4.30
docker pull yoginth/bigrag-ui:2026.4.30Start the stack
BIGRAG_API_IMAGE=yoginth/bigrag-api:2026.4.30 \
BIGRAG_UI_IMAGE=yoginth/bigrag-ui:2026.4.30 \
docker compose up -d --no-buildStarts the bigRAG API, worker, admin UI, Postgres, and Redis. Turbopuffer runs as the managed vector, keyword, and hybrid search backend.
Verify
curl http://localhost:4000/healthDocker Compose
The default docker-compose.yml runs the API, worker, admin UI, Postgres, and Redis. Turbopuffer is configured from the admin UI and stored in Postgres; it does not run as a local Compose service.
- When hacking from a checkout, plain
docker compose up -dbuilds local API and UI images. - When deploying published images, set the image variables shown above and use
--no-build.
services:
bigrag-api:
image: yoginth/bigrag-api:2026.4.30
ports:
- "4000:4000"
volumes:
- bigrag_data:/data
environment:
BIGRAG_ENV: "${BIGRAG_ENV:-dev}"
BIGRAG_DATABASE_URL: postgres://bigrag:bigrag@postgres:5432/bigrag?sslmode=disable
BIGRAG_REDIS_URL: "${BIGRAG_REDIS_URL:-redis://redis:6379/0}"
BIGRAG_MASTER_KEY: "${BIGRAG_MASTER_KEY:-}"
BIGRAG_MASTER_KEY_PREVIOUS: '${BIGRAG_MASTER_KEY_PREVIOUS:-[]}'
BIGRAG_ALLOW_PUBLIC_BIND_IN_PROD: "${BIGRAG_ALLOW_PUBLIC_BIND_IN_PROD:-false}"
BIGRAG_SESSION_COOKIE_SECURE: "${BIGRAG_SESSION_COOKIE_SECURE:-false}"
BIGRAG_SESSION_COOKIE_SAMESITE: "${BIGRAG_SESSION_COOKIE_SAMESITE:-lax}"
BIGRAG_SESSION_COOKIE_DOMAIN: "${BIGRAG_SESSION_COOKIE_DOMAIN:-}"
BIGRAG_CORS_ORIGINS: '${BIGRAG_CORS_ORIGINS:-["http://localhost:3000"]}'
BIGRAG_TRUSTED_PROXIES: '${BIGRAG_TRUSTED_PROXIES:-[]}'
BIGRAG_UPLOAD_DIR: /data/uploads
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:4000/health"]
interval: 30s
timeout: 10s
retries: 3
bigrag-worker:
image: yoginth/bigrag-api:2026.4.30
command: ["bigrag-worker", "--processes", "${BIGRAG_WORKER_PROCESSES:-5}", "--threads", "${BIGRAG_WORKER_THREADS:-8}"]
volumes:
- bigrag_data:/data
environment:
BIGRAG_ENV: "${BIGRAG_ENV:-dev}"
BIGRAG_DATABASE_URL: postgres://bigrag:bigrag@postgres:5432/bigrag?sslmode=disable
BIGRAG_REDIS_URL: "${BIGRAG_REDIS_URL:-redis://redis:6379/0}"
BIGRAG_UPLOAD_DIR: /data/uploads
BIGRAG_MASTER_KEY: "${BIGRAG_MASTER_KEY:-}"
BIGRAG_MASTER_KEY_PREVIOUS: '${BIGRAG_MASTER_KEY_PREVIOUS:-[]}'
BIGRAG_SESSION_COOKIE_SECURE: "${BIGRAG_SESSION_COOKIE_SECURE:-false}"
BIGRAG_SESSION_COOKIE_SAMESITE: "${BIGRAG_SESSION_COOKIE_SAMESITE:-lax}"
BIGRAG_SESSION_COOKIE_DOMAIN: "${BIGRAG_SESSION_COOKIE_DOMAIN:-}"
BIGRAG_CORS_ORIGINS: '${BIGRAG_CORS_ORIGINS:-["http://localhost:3000"]}'
BIGRAG_TRUSTED_PROXIES: '${BIGRAG_TRUSTED_PROXIES:-[]}'
BIGRAG_WORKER_HEALTHCHECK_KEY: "${BIGRAG_WORKER_HEALTHCHECK_KEY:-bigrag:dramatiq:worker:heartbeat}"
depends_on:
bigrag-api:
condition: service_healthy
postgres:
condition: service_healthy
redis:
condition: service_healthy
healthcheck:
test:
[
"CMD-SHELL",
"python -c 'import os, sys, redis; client = redis.Redis.from_url(os.environ.get(\"BIGRAG_REDIS_URL\", \"redis://redis:6379/0\")); key = os.environ.get(\"BIGRAG_WORKER_HEALTHCHECK_KEY\", \"bigrag:dramatiq:worker:heartbeat\"); sys.exit(0 if client.ttl(key) > 0 else 1)'",
]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
bigrag-ui:
image: yoginth/bigrag-ui:2026.4.30
ports:
- "3000:3000"
environment:
BIGRAG_URL: http://localhost:4000
depends_on:
bigrag-api:
condition: service_healthy
postgres:
image: postgres:17
environment:
POSTGRES_USER: bigrag
POSTGRES_PASSWORD: bigrag
POSTGRES_DB: bigrag
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U bigrag"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
environment:
REDIS_PASSWORD: "${REDIS_PASSWORD:-}"
command:
- sh
- -c
- |
if [ -n "$$REDIS_PASSWORD" ]; then
exec redis-server --appendonly yes --maxmemory 1gb --maxmemory-policy noeviction --requirepass "$$REDIS_PASSWORD"
fi
exec redis-server --appendonly yes --maxmemory 1gb --maxmemory-policy noeviction
volumes:
- redis_data:/data
healthcheck:
test: ["CMD-SHELL", "if [ -n \"$${REDIS_PASSWORD}\" ]; then redis-cli -a \"$${REDIS_PASSWORD}\" --no-auth-warning ping; else redis-cli ping; fi"]
interval: 10s
timeout: 5s
retries: 5
volumes:
bigrag_data:
postgres_data:
redis_data:Admin UI Image
The admin UI is a static Vite app served by Nginx. Build it from the repository root:
docker build -f app/Dockerfile -t bigrag-ui .Run it with the API URL and matching backend CORS origin:
docker run --rm -p 3000:3000 \
-e BIGRAG_URL=http://localhost:4000 \
bigrag-uiSet BIGRAG_CORS_ORIGINS='["http://localhost:3000"]' on the API when running the UI locally. In production, set the exact public admin UI origin and use secure cookies.
Image split
bigrag-api— backend API and thebigrag-workerentrypoint.bigrag-ui— static admin UI served by Nginx.
Scale the worker with more bigrag-worker containers from the bigrag-api image. A separate bigrag-worker image is only useful if you intentionally split backend dependencies later.
Service Ports
| Service | Default Port |
|---|---|
| bigRAG API | 4000 |
| PostgreSQL | 5432 |
| Redis | 6379 |
Health Checks
bigRAG exposes two health endpoints:
| Endpoint | Purpose | Notes |
|---|---|---|
/health | Liveness check | Always returns 200 if the server is running |
/health/ready | Readiness check | Returns 503 if Postgres, Redis, Turbopuffer, or the embedding provider is unreachable |
# Quick liveness check
curl http://localhost:4000/health
# Full readiness (checks all dependencies)
curl http://localhost:4000/health/ready
# Infrastructure services
docker exec bigrag-postgres pg_isready -U bigrag
docker exec bigrag-redis redis-cli pingThe worker container healthcheck reads the worker heartbeat from Redis rather than calling the API HTTP server. If you split workers by queue, set BIGRAG_WORKER_HEALTHCHECK_KEY to the matching queue heartbeat key, such as bigrag:dramatiq:worker:heartbeat:webhooks.
/health/ready also validates the embedding provider. If no collection has an embedding_api_key configured, it returns 503. Use /health if you just need to check the server is running.
Startup Troubleshooting
If the API exits with ImportError: Can't find Python file .../site-packages/alembic/env.py, rebuild or pull a current API image. The container must include the bundled Alembic environment so startup migrations can run before FastAPI begins serving traffic.