# syntax=docker/dockerfile:1.6 # ============================================================================= # brain_api — DidiBrain HTTP service that speaks Didi's web-module contract. # # Build context is the didibrain/ project root (one level up), so we can # COPY shared/ + extractor/ + brain_api/ in one shot: # # docker build -t didibrain-api -f brain_api/Dockerfile . # # Build via docker-compose at infra/docker-compose.yml (see `brain-api` # service) for the normal flow. # ============================================================================= FROM python:3.12-slim-bookworm AS runtime ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ PYTHONIOENCODING=utf-8 \ PIP_NO_CACHE_DIR=1 \ PIP_DISABLE_PIP_VERSION_CHECK=1 \ PIP_ROOT_USER_ACTION=ignore \ BRAIN_API_HOST=0.0.0.0 \ BRAIN_API_PORT=8090 WORKDIR /app # curl is used by the HEALTHCHECK directive below. RUN apt-get update \ && apt-get install -y --no-install-recommends curl \ && rm -rf /var/lib/apt/lists/* # Install Python dependencies first so the layer is cached when only app # code changes (which is the common case while iterating). COPY brain_api/requirements.txt /tmp/requirements.txt RUN pip install --upgrade pip \ && pip install -r /tmp/requirements.txt \ && rm /tmp/requirements.txt # App code. We intentionally COPY each top-level package separately so any # accidental extras (reports/, .venv/, etc.) don't sneak in even if # .dockerignore is missing. COPY shared /app/shared COPY extractor /app/extractor COPY brain_api /app/brain_api # Non-root runtime for safety. /app is owned by `brain` so the extractor # state file (extractor/_extracted.json) can be written if /v1/ingest fires # a background extraction run. RUN useradd --system --create-home --shell /bin/false brain \ && chown -R brain:brain /app USER brain EXPOSE 8090 # Liveness — the app exposes /health, which returns {status:"ok"} as soon # as the lifespan hook finishes (taxonomy refresh included). HEALTHCHECK --interval=10s --timeout=5s --start-period=20s --retries=5 \ CMD curl -fsS http://localhost:8090/health || exit 1 CMD ["python", "-m", "brain_api.run"]