RICS / docker-compose.yml
StormShadow308's picture
feat: async pipeline, job queue, generation hardening, and docs
732b14f
Raw
History Blame Contribute Delete
7.66 kB
version: "3.9"
# ── Report Genius AI — Production Stack ──────────────────────────────────────
#
# Services:
# api — FastAPI + Uvicorn (FAISS by default; optional Qdrant for async pipeline)
# qdrant — Optional vector DB when VECTORSTORE_BACKEND=qdrant
# temporal — Optional durable workflow server (ENABLE_TEMPORAL_WORKFLOW=true)
# temporal-worker — Runs worker.py when Temporal is enabled
#
# Quick start:
# cp .env.example .env # set OPENAI_API_KEY and TENANT_SECRET_KEY
# docker compose up --build -d
# open http://localhost:8000
#
# To use PostgreSQL instead of SQLite, set DATABASE_URL in .env:
# DATABASE_URL=postgresql+asyncpg://user:pass@postgres:5432/reportgenius
# ─────────────────────────────────────────────────────────────────────────────
services:
redis:
image: redis:7-alpine
container_name: report_genius_redis
restart: unless-stopped
ports:
- "6379:6379"
profiles:
- redis
jobs-worker:
build:
context: .
dockerfile: Dockerfile
target: production
image: report-genius-ai:latest
container_name: report_genius_jobs_worker
restart: unless-stopped
command: ["python", "jobs_worker.py"]
environment:
OPENAI_API_KEY: "${OPENAI_API_KEY}"
TENANT_SECRET_KEY: "${TENANT_SECRET_KEY:-change-me-in-production}"
DATABASE_URL: "${DATABASE_URL:-sqlite+aiosqlite:////data/dev.db}"
FAISS_INDEX_PATH: "/data/faiss_index"
UPLOAD_DIR: "/mnt/data/uploads"
CACHE_DIR: "/tmp/section_cache"
REDIS_URL: "${REDIS_URL:-redis://redis:6379/0}"
ENABLE_JOB_QUEUE: "true"
ENABLE_ASYNC_PIPELINE: "${ENABLE_ASYNC_PIPELINE:-false}"
VECTORSTORE_BACKEND: "${VECTORSTORE_BACKEND:-faiss}"
QDRANT_URL: "${QDRANT_URL:-http://qdrant:6333}"
GENERATION_STALE_SWEEP_SECONDS: "${GENERATION_STALE_SWEEP_SECONDS:-120}"
GENERATION_TIMEOUT_SECONDS: "${GENERATION_TIMEOUT_SECONDS:-3600}"
volumes:
- uploads:/mnt/data/uploads
- section_cache:/tmp/section_cache
- db_data:/data
- faiss_index:/data/faiss_index
depends_on:
redis:
condition: service_started
profiles:
- jobs
qdrant:
image: qdrant/qdrant:v1.12.5
container_name: report_genius_qdrant
restart: unless-stopped
ports:
- "6333:6333"
volumes:
- qdrant_data:/qdrant/storage
profiles:
- qdrant
api:
build:
context: .
dockerfile: Dockerfile
target: production
image: report-genius-ai:latest
container_name: report_genius_api
restart: unless-stopped
ports:
- "8000:8000"
environment:
# Pin PORT=8000 so the container's CMD listens on 8000 and the existing
# `localhost:8000` URL keeps working. The Dockerfile defaults to 7860
# (Hugging Face Spaces convention) when this env var is absent.
PORT: "8000"
OPENAI_API_KEY: "${OPENAI_API_KEY}"
TENANT_SECRET_KEY: "${TENANT_SECRET_KEY:-change-me-in-production}"
DATABASE_URL: "${DATABASE_URL:-sqlite+aiosqlite:////data/dev.db}"
FAISS_INDEX_PATH: "/data/faiss_index"
UPLOAD_DIR: "/mnt/data/uploads"
CACHE_DIR: "/tmp/section_cache"
MAX_CONTEXT_TOKENS: "${MAX_CONTEXT_TOKENS:-400}"
MAX_OUTPUT_TOKENS: "${MAX_OUTPUT_TOKENS:-300}"
RETRIEVAL_TOP_K: "${RETRIEVAL_TOP_K:-10}"
RERANK_TOP_N: "${RERANK_TOP_N:-3}"
MAX_CONCURRENT_INGESTS: "${MAX_CONCURRENT_INGESTS:-4}"
RATE_LIMIT_GENERATE_RPM: "${RATE_LIMIT_GENERATE_RPM:-20}"
RATE_LIMIT_READ_RPM: "${RATE_LIMIT_READ_RPM:-120}"
DEV_MODE: "false"
ENABLE_ASYNC_PIPELINE: "${ENABLE_ASYNC_PIPELINE:-false}"
ENABLE_SPECULATIVE_EXECUTOR: "${ENABLE_SPECULATIVE_EXECUTOR:-false}"
ENABLE_PROMPT_CACHING: "${ENABLE_PROMPT_CACHING:-false}"
ENABLE_TEMPORAL_WORKFLOW: "${ENABLE_TEMPORAL_WORKFLOW:-false}"
ENABLE_HYBRID_RETRIEVAL: "${ENABLE_HYBRID_RETRIEVAL:-true}"
SEMANTIC_CACHE_ENABLED: "${SEMANTIC_CACHE_ENABLED:-true}"
AGENTIC_INSPECTOR_WHEN_NOTES_ONLY: "${AGENTIC_INSPECTOR_WHEN_NOTES_ONLY:-false}"
NOTES_ONLY_GENERATION: "${NOTES_ONLY_GENERATION:-true}"
GENERATION_TIMEOUT_SECONDS: "${GENERATION_TIMEOUT_SECONDS:-3600}"
GENERATION_STALE_SWEEP_SECONDS: "${GENERATION_STALE_SWEEP_SECONDS:-120}"
TEMPORAL_HOST: "${TEMPORAL_HOST:-temporal:7233}"
TEMPORAL_NAMESPACE: "${TEMPORAL_NAMESPACE:-default}"
VECTORSTORE_BACKEND: "${VECTORSTORE_BACKEND:-faiss}"
QDRANT_URL: "${QDRANT_URL:-http://qdrant:6333}"
MAX_CONCURRENT_LLM_CALLS: "${MAX_CONCURRENT_LLM_CALLS:-10}"
REDIS_URL: "${REDIS_URL:-}"
ENABLE_JOB_QUEUE: "${ENABLE_JOB_QUEUE:-false}"
volumes:
- uploads:/mnt/data/uploads
- section_cache:/tmp/section_cache
- db_data:/data
- faiss_index:/data/faiss_index
depends_on:
qdrant:
condition: service_started
required: false
temporal:
condition: service_started
required: false
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20s
temporal:
image: temporalio/auto-setup:1.25.2
container_name: report_genius_temporal
restart: unless-stopped
ports:
- "7233:7233"
environment:
- DB=sqlite
profiles:
- temporal
temporal-worker:
build:
context: .
dockerfile: Dockerfile
target: production
image: report-genius-ai:latest
container_name: report_genius_temporal_worker
restart: unless-stopped
command: ["python", "worker.py"]
environment:
OPENAI_API_KEY: "${OPENAI_API_KEY}"
TENANT_SECRET_KEY: "${TENANT_SECRET_KEY:-change-me-in-production}"
DATABASE_URL: "${DATABASE_URL:-sqlite+aiosqlite:////data/dev.db}"
FAISS_INDEX_PATH: "/data/faiss_index"
UPLOAD_DIR: "/mnt/data/uploads"
CACHE_DIR: "/tmp/section_cache"
ENABLE_TEMPORAL_WORKFLOW: "true"
ENABLE_ASYNC_PIPELINE: "${ENABLE_ASYNC_PIPELINE:-false}"
ENABLE_SPECULATIVE_EXECUTOR: "${ENABLE_SPECULATIVE_EXECUTOR:-false}"
ENABLE_PROMPT_CACHING: "${ENABLE_PROMPT_CACHING:-false}"
VECTORSTORE_BACKEND: "${VECTORSTORE_BACKEND:-faiss}"
QDRANT_URL: "${QDRANT_URL:-http://qdrant:6333}"
ENABLE_HYBRID_RETRIEVAL: "${ENABLE_HYBRID_RETRIEVAL:-true}"
SEMANTIC_CACHE_ENABLED: "${SEMANTIC_CACHE_ENABLED:-true}"
AGENTIC_INSPECTOR_WHEN_NOTES_ONLY: "${AGENTIC_INSPECTOR_WHEN_NOTES_ONLY:-false}"
NOTES_ONLY_GENERATION: "${NOTES_ONLY_GENERATION:-true}"
GENERATION_TIMEOUT_SECONDS: "${GENERATION_TIMEOUT_SECONDS:-3600}"
GENERATION_STALE_SWEEP_SECONDS: "${GENERATION_STALE_SWEEP_SECONDS:-120}"
TEMPORAL_HOST: "${TEMPORAL_HOST:-temporal:7233}"
TEMPORAL_NAMESPACE: "${TEMPORAL_NAMESPACE:-default}"
TEMPORAL_TASK_QUEUE: "${TEMPORAL_TASK_QUEUE:-reports}"
MAX_CONCURRENT_LLM_CALLS: "${MAX_CONCURRENT_LLM_CALLS:-10}"
volumes:
- uploads:/mnt/data/uploads
- section_cache:/tmp/section_cache
- db_data:/data
- faiss_index:/data/faiss_index
depends_on:
temporal:
condition: service_started
profiles:
- temporal
volumes:
qdrant_data:
driver: local
uploads:
driver: local
section_cache:
driver: local
db_data:
driver: local
faiss_index:
driver: local