services: db: image: postgres:15-alpine environment: POSTGRES_USER: ${POSTGRES_USER:-airpg} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-airpg} POSTGRES_DB: ${POSTGRES_DB:-airpg} volumes: - pg_data:/var/lib/postgresql/data ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-airpg}"] interval: 5s timeout: 3s retries: 10 qdrant: image: qdrant/qdrant:v1.9.0 environment: QDRANT__LOG_LEVEL: INFO volumes: - qdrant_data:/qdrant/storage ports: - "6333:6333" - "6334:6334" healthcheck: test: ["CMD", "bash", "-c", "exec 3<>/dev/tcp/127.0.0.1/6333 && echo -e 'GET /collections HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n' >&3 && head -n 1 <&3 | grep -q 200"] interval: 10s timeout: 5s retries: 10 backend: build: context: . dockerfile: deploy/Dockerfile.backend env_file: - .env environment: # Override .env values with docker-compose service names DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-airpg}:${POSTGRES_PASSWORD:-airpg}@db:5432/${POSTGRES_DB:-airpg} QDRANT_URL: http://qdrant:6333 # Allow backend to reach host services (e.g. Ollama on host) via host.docker.internal # On Linux this requires the extra_hosts mapping below. extra_hosts: - "host.docker.internal:host-gateway" volumes: - ./data:/app/data - ./app:/app/app ports: - "8000:8000" depends_on: db: condition: service_healthy qdrant: condition: service_healthy frontend: # nginx-served production build of the React app. # Listens on container port 80, mapped to host port 8080. # Access the app at http://localhost:8080 build: context: . dockerfile: deploy/Dockerfile.frontend args: # Bake the API base URL into the bundle at build time. # Relative "/api" works because nginx proxies /api/* → backend:8000. VITE_API_BASE_URL: /api ports: - "8080:80" depends_on: - backend volumes: pg_data: qdrant_data: