services: db: image: pgvector/pgvector:pg17 volumes: - postgres_data_dev:/var/lib/postgresql/data/ environment: - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - POSTGRES_DB=${POSTGRES_DB} ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] interval: 5s timeout: 5s retries: 5 networks: - app-network redis: image: redis:7-alpine ports: - "6379:6379" volumes: - redis_data_dev:/data command: redis-server --appendonly yes healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 5s retries: 5 networks: - app-network # ========================================================================== # MCP Servers - Model Context Protocol servers for AI agent capabilities # ========================================================================== mcp-llm-gateway: build: context: ./mcp-servers/llm-gateway dockerfile: Dockerfile ports: - "8001:8001" env_file: - .env environment: - LLM_GATEWAY_HOST=0.0.0.0 - LLM_GATEWAY_PORT=8001 - REDIS_URL=redis://redis:6379/1 - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} - OPENAI_API_KEY=${OPENAI_API_KEY} - ENVIRONMENT=development depends_on: redis: condition: service_healthy healthcheck: test: ["CMD", "python", "-c", "import httpx; httpx.get('http://localhost:8001/health').raise_for_status()"] interval: 30s timeout: 10s retries: 3 start_period: 10s networks: - app-network restart: unless-stopped mcp-knowledge-base: build: context: ./mcp-servers/knowledge-base dockerfile: Dockerfile ports: - "8002:8002" env_file: - .env environment: # KB_ prefix required by pydantic-settings config - KB_HOST=0.0.0.0 - KB_PORT=8002 - KB_DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB} - KB_REDIS_URL=redis://redis:6379/2 - KB_LLM_GATEWAY_URL=http://mcp-llm-gateway:8001 - OPENAI_API_KEY=${OPENAI_API_KEY} - ENVIRONMENT=development depends_on: db: condition: service_healthy redis: condition: service_healthy healthcheck: test: ["CMD", "python", "-c", "import httpx; httpx.get('http://localhost:8002/health').raise_for_status()"] interval: 30s timeout: 10s retries: 3 start_period: 10s networks: - app-network restart: unless-stopped backend: build: context: ./backend dockerfile: Dockerfile target: development volumes: - ./backend:/app - ./uploads:/app/uploads # Note: venv is at /opt/venv (not /app/.venv) so bind mount doesn't affect it ports: - "8000:8000" env_file: - .env environment: - DATABASE_URL=${DATABASE_URL} - SECRET_KEY=${SECRET_KEY} - ENVIRONMENT=development - DEBUG=true - BACKEND_CORS_ORIGINS=${BACKEND_CORS_ORIGINS} - REDIS_URL=redis://redis:6379/0 # MCP Server URLs - LLM_GATEWAY_URL=http://mcp-llm-gateway:8001 - KNOWLEDGE_BASE_URL=http://mcp-knowledge-base:8002 depends_on: db: condition: service_healthy redis: condition: service_healthy mcp-llm-gateway: condition: service_healthy mcp-knowledge-base: condition: service_healthy healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 10s timeout: 5s retries: 5 start_period: 40s networks: - app-network command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] # Celery workers for background task processing (per ADR-003) celery-agent: build: context: ./backend dockerfile: Dockerfile target: development volumes: - ./backend:/app env_file: - .env environment: - DATABASE_URL=${DATABASE_URL} - REDIS_URL=redis://redis:6379/0 - CELERY_QUEUE=agent # MCP Server URLs (agents need access to MCP) - LLM_GATEWAY_URL=http://mcp-llm-gateway:8001 - KNOWLEDGE_BASE_URL=http://mcp-knowledge-base:8002 depends_on: db: condition: service_healthy redis: condition: service_healthy mcp-llm-gateway: condition: service_healthy mcp-knowledge-base: condition: service_healthy networks: - app-network command: ["celery", "-A", "app.celery_app", "worker", "-Q", "agent", "-l", "info", "-c", "4"] celery-git: build: context: ./backend dockerfile: Dockerfile target: development volumes: - ./backend:/app env_file: - .env environment: - DATABASE_URL=${DATABASE_URL} - REDIS_URL=redis://redis:6379/0 - CELERY_QUEUE=git depends_on: db: condition: service_healthy redis: condition: service_healthy networks: - app-network command: ["celery", "-A", "app.celery_app", "worker", "-Q", "git", "-l", "info", "-c", "2"] celery-sync: build: context: ./backend dockerfile: Dockerfile target: development volumes: - ./backend:/app env_file: - .env environment: - DATABASE_URL=${DATABASE_URL} - REDIS_URL=redis://redis:6379/0 - CELERY_QUEUE=sync depends_on: db: condition: service_healthy redis: condition: service_healthy networks: - app-network command: ["celery", "-A", "app.celery_app", "worker", "-Q", "sync", "-l", "info", "-c", "2"] celery-beat: build: context: ./backend dockerfile: Dockerfile target: development volumes: - ./backend:/app env_file: - .env environment: - DATABASE_URL=${DATABASE_URL} - REDIS_URL=redis://redis:6379/0 depends_on: db: condition: service_healthy redis: condition: service_healthy networks: - app-network command: ["celery", "-A", "app.celery_app", "beat", "-l", "info"] frontend: build: context: ./frontend dockerfile: Dockerfile target: deps args: - NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} volumes: - ./frontend:/app - frontend_dev_modules:/app/node_modules - frontend_dev_next:/app/.next ports: - "3000:3000" environment: - NODE_ENV=development - NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} - NEXT_PUBLIC_API_BASE_URL=http://backend:8000 depends_on: backend: condition: service_healthy command: npm run dev networks: - app-network volumes: postgres_data_dev: redis_data_dev: frontend_dev_modules: frontend_dev_next: networks: app-network: driver: bridge