# 2dph — docker composition # # docker compose up -d brain # API (Zig CGO serve) # docker compose --profile index run --rm index # Python rebuild # docker compose --profile picoclaw up brain-mcp # docker compose --profile reasoner up -d reasoner # CPU Ollama :11435 # docker compose --profile searxng up -d # # Secrets never baked in: search.env + db-profiles.yml from ~/.config/brain. name: 2dph services: brain: image: ghcr.io/eslider/2dph:api build: context: . dockerfile: Dockerfile target: api cache_from: - ghcr.io/eslider/2dph:cache command: ["serve"] environment: &env HF_HOME: /data/hf BRAIN_SEARCH_CACHE: /data/cache/web-search.sqlite BRAIN_DB_PROFILES: /secret/db-profiles.yml BRAIN_SEARCH_ENV: /secret/search.env KB_ROOT: /data KB_WORKERS: "4" KB_PORT: "8630" volumes: - kb-model:/data/hf - kb-var:/data - ~/.config/brain:/secret:ro ports: - "127.0.0.1:8630:8630" read_only: true tmpfs: - /tmp healthcheck: test: ["CMD", "wget", "-qO-", "http://127.0.0.1:8630/health"] interval: 30s timeout: 5s retries: 3 restart: unless-stopped stop_grace_period: 20s brain-watch: image: ghcr.io/eslider/2dph:api environment: *env volumes: - kb-model:/data/hf - kb-var:/data - ..:/corpus:ro - ~/.config/brain:/secret:ro command: ["watch", "/corpus"] read_only: true tmpfs: - /tmp restart: unless-stopped stop_grace_period: 20s # Python write path (Ladybug rebuild). Not in the API image. # docker compose --profile index run --rm index index: profiles: ["index"] image: ghcr.io/eslider/2dph:index build: context: . dockerfile: Dockerfile target: index environment: HF_HOME: /data/hf KB_PY: python3 volumes: - kb-model:/data/hf - kb-var:/app/var - ..:/corpus:ro - ~/.config/brain:/secret:ro command: ["index"] read_only: true tmpfs: - /tmp # Optional local SearXNG (D3). Skip if BRAIN_SEARCH_URL already points at a # live instance — do not run a second copy on that host. # SEARXNG_SECRET=$(openssl rand -hex 32) docker compose --profile searxng up -d searxng: profiles: ["searxng"] image: docker.io/searxng/searxng:2026.8.10-0a118066d ports: - "127.0.0.1:8888:8080" environment: SEARXNG_SECRET: ${SEARXNG_SECRET:-} volumes: - ./deploy/searxng/settings.yml:/etc/searxng/settings.yml:ro - ./deploy/searxng/limiter.toml:/etc/searxng/limiter.toml:ro restart: unless-stopped # MCP endpoint for an external agent (PicoClaw is not shipped here). # docker compose --profile picoclaw up brain-mcp brain-mcp: profiles: ["picoclaw"] image: ghcr.io/eslider/2dph:api environment: *env volumes: - kb-model:/data/hf - kb-var:/data - ~/.config/brain:/secret:ro command: ["serve"] ports: - "127.0.0.1:8630:8630" read_only: true tmpfs: - /tmp restart: unless-stopped # CPU OpenAI-compatible sidecar (D18). Weights are pulled at runtime, not # baked into the 2dph image. Does not touch host Ollama on :11434. # docker compose --profile reasoner up -d reasoner # docker compose --profile reasoner exec reasoner ollama pull qwen3.5:9b reasoner: profiles: ["reasoner"] image: docker.io/ollama/ollama:latest environment: OLLAMA_NUM_GPU: "0" OLLAMA_HOST: "0.0.0.0:11434" ports: - "127.0.0.1:11435:11434" volumes: - reasoner-ollama:/root/.ollama restart: unless-stopped volumes: kb-model: kb-var: reasoner-ollama: