services: redis: image: redis:7.2-alpine ports: - "6379:6379" volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 postgres_db: image: postgres:15-alpine ports: - "5433:5432" # Host port 5433 to avoid conflict if local Postgres runs on 5432 environment: POSTGRES_USER: ${POSTGRES_USER:-user} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-password} POSTGRES_DB: ${POSTGRES_DB:-knowledge_assistant_db} volumes: - postgres_data:/var/lib/postgresql/data - ./init-db.sh:/docker-entrypoint-initdb.d/init-db.sh # Optional: script to init DB on first run healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-user} -d ${POSTGRES_DB:-knowledge_assistant_db}"] interval: 10s timeout: 5s retries: 5 vector_db: # ChromaDB as an example image: chromadb/chroma:0.5.0 # Use a specific version ports: - "8001:8000" # Host port 8001 to avoid conflict volumes: - chroma_data:/chroma/chroma # Persist Chroma data environment: - IS_PERSISTENT=TRUE - CHROMA_SERVER_HOST=0.0.0.0 # Listen on all interfaces inside container - CHROMA_SERVER_HTTP_PORT=8000 - ANONYMIZED_TELEMETRY=FALSE # command: uvicorn chromadb.app:app --workers 1 --host 0.0.0.0 --port 8000 --log-config chromadb/log_config.yml # Healthcheck for Chroma might be tricky, often check HTTP endpoint # healthcheck: # test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/heartbeat"] # interval: 30s # timeout: 10s # retries: 3 api: build: context: . dockerfile: Dockerfile.api ports: - "${API_PORT:-8080}:${API_PORT:-8080}" depends_on: redis: condition: service_healthy postgres_db: condition: service_healthy vector_db: # Worker needs vector_db, API might not directly but good to have it up condition: service_started # ChromaDB takes a bit to start, using service_started environment: - LOG_LEVEL=${LOG_LEVEL:-INFO} - CELERY_BROKER_URL=${CELERY_BROKER_URL:-redis://redis:6379/0} - DATABASE_URL=${DATABASE_URL:-postgresql://${POSTGRES_USER:-user}:${POSTGRES_PASSWORD:-password}@postgres_db:5432/${POSTGRES_DB:-knowledge_assistant_db}} - API_PORT=${API_PORT:-8080} # Pass other necessary env vars from .env file volumes: - ./app:/app/app env_file: - .env command: uvicorn app.api.main:app --host 0.0.0.0 --port ${API_PORT:-8080} --reload worker: build: context: . dockerfile: Dockerfile.worker depends_on: redis: condition: service_healthy postgres_db: condition: service_healthy vector_db: condition: service_started # Worker directly interacts with vector_db api: # Ensure API is at least started if worker needs to call back or for shared code condition: service_started environment: - LOG_LEVEL=${LOG_LEVEL:-INFO} - CELERY_BROKER_URL=${CELERY_BROKER_URL:-redis://redis:6379/0} - CELERY_RESULT_BACKEND=${CELERY_RESULT_BACKEND:-redis://redis:6379/0} - DATABASE_URL=${DATABASE_URL:-postgresql://${POSTGRES_USER:-user}:${POSTGRES_PASSWORD:-password}@postgres_db:5432/${POSTGRES_DB:-knowledge_assistant_db}} - VECTOR_DB_IMPL=${VECTOR_DB_IMPL:-chromadb} - CHROMA_HOST=${CHROMA_HOST:-vector_db} - CHROMA_PORT=${CHROMA_PORT:-8000} - CHROMA_COLLECTION_NAME=${CHROMA_COLLECTION_NAME:-simple_wikipedia_chunks} - LLM_MODEL_NAME=${LLM_MODEL_NAME:-mistralai/Mistral-7B-Instruct-v0.1} - EMBEDDING_MODEL_NAME=${EMBEDDING_MODEL_NAME:-sentence-transformers/all-MiniLM-L6-v2} - RETRIEVAL_TOP_K=${RETRIEVAL_TOP_K:-5} # Pass other necessary env vars from .env file # Mount local models directory if LLM_MODEL_PATH is used # - HUGGING_FACE_HUB_TOKEN=${HUGGING_FACE_HUB_TOKEN} volumes: - ./app:/app/app # Example for mounting local models (ensure path exists and matches .env) # - ./models_cache:/root/.cache/huggingface/hub # Mount Hugging Face cache # - /path/to/your/local/llm_models:/models # If LLM_MODEL_PATH is used env_file: - .env command: watchmedo auto-restart --directory=./app --pattern=*.py --recursive -- celery -A app.worker.celery_app.celery worker -l ${LOG_LEVEL:-INFO} -Q technical_qna --concurrency=1 # Data ingestion service (run manually or on a schedule) ingestion: build: context: . dockerfile: Dockerfile.ingestion # Separate Dockerfile for ingestion if dependencies differ significantly depends_on: vector_db: condition: service_started # Needs vector_db to be up postgres_db: # If storing chunks/metadata in postgres condition: service_healthy environment: - LOG_LEVEL=${LOG_LEVEL:-INFO} - DATABASE_URL=${DATABASE_URL:-postgresql://${POSTGRES_USER:-user}:${POSTGRES_PASSWORD:-password}@postgres_db:5432/${POSTGRES_DB:-knowledge_assistant_db}} - VECTOR_DB_IMPL=${VECTOR_DB_IMPL:-chromadb} - CHROMA_HOST=${CHROMA_HOST:-vector_db} - CHROMA_PORT=${CHROMA_PORT:-8000} - CHROMA_COLLECTION_NAME=${CHROMA_COLLECTION_NAME:-simple_wikipedia_chunks} - EMBEDDING_MODEL_NAME=${EMBEDDING_MODEL_NAME:-sentence-transformers/all-MiniLM-L6-v2} - DATASET_NAME=${DATASET_NAME:-rahular/simple-wikipedia} - CHUNK_SIZE=${CHUNK_SIZE:-512} - CHUNK_OVERLAP=${CHUNK_OVERLAP:-64} # - HUGGING_FACE_HUB_TOKEN=${HUGGING_FACE_HUB_TOKEN} volumes: - ./data_ingestion:/app/data_ingestion - ./app/core:/app/app/core # Share core config/logging if needed # - ./models_cache:/root/.cache/huggingface/hub # Mount Hugging Face cache env_file: - .env # Command to run ingestion, e.g., python data_ingestion/ingest.py # This service is intended to be run on demand: # docker-compose run --rm ingestion command: ["tail", "-f", "/dev/null"] # Keep container running if needed, or specify ingestion command prometheus: image: prom/prometheus:v2.51.0 ports: - "9090:9090" volumes: - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml - prometheus_data:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--web.console.libraries=/usr/share/prometheus/console_libraries' - '--web.console.templates=/usr/share/prometheus/consoles' - '--web.enable-lifecycle' # Allows reload of config via HTTP POST to /-/reload depends_on: - api grafana: image: grafana/grafana:10.4.2 ports: - "3000:3000" volumes: - grafana_data:/var/lib/grafana - ./monitoring/grafana_datasources.yml:/etc/grafana/provisioning/datasources/default.yml # - ./monitoring/grafana_dashboards.yml:/etc/grafana/provisioning/dashboards/default.yml # - ./monitoring/dashboards:/var/lib/grafana/dashboards # If you have pre-defined dashboards environment: GF_SECURITY_ADMIN_USER: ${GRAFANA_ADMIN_USER:-admin} GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD:-password} # Change in production GF_DATASOURCES_DEFAULT_VERSION: 1 # Ensures datasource provisioning is picked up depends_on: - prometheus env_file: - .env volumes: redis_data: postgres_data: chroma_data: prometheus_data: grafana_data: # models_cache: # If using a shared Hugging Face cache volume