services: # ── API ── brain-api: build: context: . dockerfile: Dockerfile.api container_name: brain-api restart: unless-stopped volumes: - ./storage:/app/storage environment: - DATABASE_URL=postgresql+asyncpg://brain:brain@brain-db:5432/brain - REDIS_URL=redis://brain-redis:6379/0 - MEILI_URL=http://brain-meili:7700 - MEILI_MASTER_KEY=${MEILI_MASTER_KEY:-brain-meili-secure-key-2026} - CRAWLER_URL=http://brain-crawler:3100 - OPENAI_API_KEY=${OPENAI_API_KEY} - OPENAI_MODEL=${OPENAI_MODEL:-gpt-4o-mini} - PORT=8200 - DEBUG=${DEBUG:-0} - TZ=${TZ:-America/Chicago} depends_on: brain-db: condition: service_healthy brain-redis: condition: service_started brain-meili: condition: service_started networks: - default - pangolin # ── Worker ── brain-worker: build: context: . dockerfile: Dockerfile.worker container_name: brain-worker restart: unless-stopped volumes: - ./storage:/app/storage environment: - DATABASE_URL=postgresql+asyncpg://brain:brain@brain-db:5432/brain - REDIS_URL=redis://brain-redis:6379/0 - MEILI_URL=http://brain-meili:7700 - MEILI_MASTER_KEY=${MEILI_MASTER_KEY:-brain-meili-secure-key-2026} - CRAWLER_URL=http://brain-crawler:3100 - OPENAI_API_KEY=${OPENAI_API_KEY} - OPENAI_MODEL=${OPENAI_MODEL:-gpt-4o-mini} - TZ=${TZ:-America/Chicago} depends_on: brain-db: condition: service_healthy brain-redis: condition: service_started # ── PostgreSQL + pgvector ── brain-db: image: pgvector/pgvector:pg16 container_name: brain-db restart: unless-stopped environment: - POSTGRES_USER=brain - POSTGRES_PASSWORD=brain - POSTGRES_DB=brain volumes: - ./data/postgres:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U brain"] interval: 5s timeout: 3s retries: 10 # ── Redis ── brain-redis: image: redis:7-alpine container_name: brain-redis restart: unless-stopped volumes: - ./data/redis:/data # ── Meilisearch ── brain-meili: image: getmeili/meilisearch:v1.12 container_name: brain-meili restart: unless-stopped environment: - MEILI_MASTER_KEY=${MEILI_MASTER_KEY:-brain-meili-secure-key-2026} - MEILI_ENV=production volumes: - ./data/meili:/meili_data # ── Crawler (Playwright + stealth for JS rendering + screenshots) ── brain-crawler: build: context: ./crawler dockerfile: Dockerfile container_name: brain-crawler restart: unless-stopped environment: - PORT=3100 - TZ=${TZ:-America/Chicago} shm_size: '1gb' networks: pangolin: external: true