services: # PostgreSQL Database db: image: postgres:16-alpine container_name: ggw-db restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER:-ggw} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-ggwpassword} POSTGRES_DB: ${POSTGRES_DB:-ggwdb} volumes: - postgres_data:/var/lib/postgresql/data ports: - "${POSTGRES_PORT:-5432}:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-ggw} -d ${POSTGRES_DB:-ggwdb}"] interval: 5s timeout: 5s retries: 5 # FastAPI Backend backend: build: context: ./backend dockerfile: Dockerfile # Use BuildKit for faster builds with caching args: BUILDKIT_INLINE_CACHE: 1 container_name: ggw-backend restart: unless-stopped # Load environment variables from root .env file env_file: - .env ports: - "8000:8000" # Ensures `host.docker.internal` works on Linux (needed for Ollama on host). extra_hosts: - "host.docker.internal:host-gateway" volumes: # Mount .env file for configuration - ./.env:/app/.env:ro # Mount source code for hot reload - ./backend/app:/app/app:cached # Mount Alembic migrations so schema fixes don't require rebuilding the image - ./backend/alembic:/app/alembic:cached - ./backend/alembic.ini:/app/alembic.ini:cached - ./backend/uploads:/app/uploads # Persist PaddleOCR models - paddle_models:/root/.paddleocr # Persist ChromaDB vector store - chroma_data:/app/chroma_db # Persist Hugging Face model/cache locally - hf_cache:/root/.cache/huggingface environment: - DATABASE_URL=postgresql+asyncpg://${POSTGRES_USER:-ggw}:${POSTGRES_PASSWORD:-ggwpassword}@db:5432/${POSTGRES_DB:-ggwdb} - JWT_SECRET=${JWT_SECRET:-dev-secret-change-in-production} - JWT_ALGORITHM=${JWT_ALGORITHM:-HS256} - ACCESS_TOKEN_EXPIRE_MINUTES=${ACCESS_TOKEN_EXPIRE_MINUTES:-10080} - FRONTEND_ORIGIN=http://localhost:5173 # ChromaDB Configuration - CHROMA_PERSIST_DIR=/app/chroma_db - RAG_TOP_K=5 # Hugging Face cache configuration (local MedGemma) - HF_HOME=/root/.cache/huggingface # LLM API Keys - GROQ_API_KEY=${GROQ_API_KEY:-} - GROK_API_KEY=${GROK_API_KEY:-} - OPENAI_API_KEY=${OPENAI_API_KEY:-} - GEMINI_API_KEY=${GEMINI_API_KEY:-} - GOOGLE_PLACES_API_KEY=${GOOGLE_PLACES_API_KEY:-} - TRANSFORMERS_CACHE=/root/.cache/huggingface # Hugging Face auth (required for gated models like MedGemma) - HF_TOKEN=${HF_TOKEN:-} # Ollama (local, not cloud) - OLLAMA_BASE_URL=${OLLAMA_BASE_URL:-http://host.docker.internal:11434} - OLLAMA_MODEL=${OLLAMA_MODEL:-hf.co/unsloth/medgemma-4b-it-GGUF:Q6_K_XL} - OLLAMA_PULL_ON_START=${OLLAMA_PULL_ON_START:-true} - OLLAMA_PULL_LOG_STEP_PCT=${OLLAMA_PULL_LOG_STEP_PCT:-5} # Gemini Fallback (optional, for other features) - USE_GEMINI_FALLBACK=${USE_GEMINI_FALLBACK:-true} # Neo4j Configuration (for Mem0 graph memory and Graphiti) - NEO4J_URI=${NEO4J_URI:-bolt://neo4j:7687} - NEO4J_USER=${NEO4J_USER:-neo4j} - NEO4J_PASSWORD=${NEO4J_PASSWORD:-changeme} - MEM0_COLLECTION=${MEM0_COLLECTION:-user_memories} - GRAPHITI_DATABASE=${GRAPHITI_DATABASE:-neo4j} # SMS Configuration (Twilio or mock mode) - SMS_MODE=${SMS_MODE:-mock} - SMS_TEST_TO_NUMBER=${SMS_TEST_TO_NUMBER:-} - TWILIO_ACCOUNT_SID=${TWILIO_ACCOUNT_SID:-} - TWILIO_AUTH_TOKEN=${TWILIO_AUTH_TOKEN:-} - TWILIO_FROM_NUMBER=${TWILIO_FROM_NUMBER:-} # Reminder Scheduler Configuration - REMINDER_SCHEDULER_ENABLED=${REMINDER_SCHEDULER_ENABLED:-true} - REMINDER_CHECK_INTERVAL_SECONDS=${REMINDER_CHECK_INTERVAL_SECONDS:-60} healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/"] interval: 30s timeout: 10s retries: 3 start_period: 40s depends_on: db: condition: service_healthy neo4j: condition: service_healthy # Neo4j Graph Database (for Mem0 graph memory and Graphiti knowledge graph) neo4j: image: neo4j:5.26-community container_name: ggw-neo4j restart: unless-stopped environment: NEO4J_AUTH: ${NEO4J_USER:-neo4j}/${NEO4J_PASSWORD:-changeme} NEO4J_PLUGINS: '["apoc"]' NEO4J_dbms_security_procedures_unrestricted: apoc.* ports: - "7474:7474" # Browser UI - "7687:7687" # Bolt protocol volumes: - neo4j_data:/data - neo4j_logs:/logs healthcheck: test: ["CMD", "cypher-shell", "-u", "${NEO4J_USER:-neo4j}", "-p", "${NEO4J_PASSWORD:-changeme}", "RETURN 1"] interval: 10s timeout: 5s retries: 5 # Vite React Frontend frontend: build: context: ./frontend dockerfile: Dockerfile container_name: ggw-frontend restart: unless-stopped ports: - "5173:5173" volumes: # Mount source for hot reload, exclude node_modules - ./frontend/src:/app/src:cached - ./frontend/index.html:/app/index.html:cached - ./frontend/vite.config.ts:/app/vite.config.ts:cached - ./frontend/tsconfig.json:/app/tsconfig.json:cached environment: - VITE_API_URL=http://localhost:8000 depends_on: - backend volumes: postgres_data: paddle_models: chroma_data: hf_cache: neo4j_data: neo4j_logs: