services: db: image: pgvector/pgvector:pg16 container_name: rag_postgres environment: POSTGRES_USER: ${POSTGRES_USER:-raguser} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-ragpassword} POSTGRES_DB: ${POSTGRES_DB:-ragdb} ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data - ./backend/init.sql:/docker-entrypoint-initdb.d/init.sql healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-raguser} -d ${POSTGRES_DB:-ragdb}"] interval: 5s timeout: 5s retries: 10 schema: image: pgvector/pgvector:pg16 environment: POSTGRES_USER: ${POSTGRES_USER:-raguser} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-ragpassword} POSTGRES_DB: ${POSTGRES_DB:-ragdb} PGPASSWORD: ${POSTGRES_PASSWORD:-ragpassword} volumes: - ./backend/init.sql:/schema/init.sql:ro command: - sh - -c - psql -h db -U "$$POSTGRES_USER" -d "$$POSTGRES_DB" -f /schema/init.sql depends_on: db: condition: service_healthy api: build: context: ./backend environment: # Keep this optional at Compose interpolation time so `docker compose up db` # works for local frontend/database development. The API requires a real key # before it can make OpenAI requests. OPENAI_API_KEY: ${OPENAI_API_KEY:-} DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-raguser}:${POSTGRES_PASSWORD:-ragpassword}@db:5432/${POSTGRES_DB:-ragdb} ports: - "8000:8000" depends_on: db: condition: service_healthy schema: condition: service_completed_successfully healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"] interval: 10s timeout: 5s retries: 5 frontend: build: context: ./frontend args: # Baked into the bundle at build time, not read at container start. VITE_API_BASE_URL: ${VITE_API_BASE_URL:-http://localhost:8000} ports: - "5173:80" depends_on: api: condition: service_healthy volumes: postgres_data: