# syntax=docker/dockerfile:1.7

# ─── Builder ──────────────────────────────────────────────────────────────
FROM python:3.12-slim AS builder

ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1 \
    PIP_NO_CACHE_DIR=1 \
    PIP_DISABLE_PIP_VERSION_CHECK=1

WORKDIR /build

# Copy only the metadata first so dependency layer caches independently
# of source changes — rebuilds are seconds when only Python files change.
COPY pyproject.toml README.md ./
COPY src ./src

# Install into a dedicated prefix we'll copy verbatim into the runtime
# image. No virtualenv — Python's site-packages path handles isolation
# inside the slim image.
RUN pip install --prefix=/install .


# ─── Runtime ──────────────────────────────────────────────────────────────
FROM python:3.12-slim AS runtime

ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1 \
    NUDG3_MCP_LOG_LEVEL=INFO

# Non-root user — defence-in-depth even though the container exposes
# only an HTTP port and does no filesystem writes.
RUN groupadd --system --gid 1000 nudg3 && \
    useradd  --system --uid 1000 --gid nudg3 --no-create-home nudg3

COPY --from=builder /install /usr/local

USER nudg3

EXPOSE 8080

# Cloud Run reads this; --workers=1 because FastMCP keeps per-session
# state in-process. Horizontal scaling is via more Cloud Run instances.
# Uvicorn's default logging is used (Cloud Logging parses it fine); the
# JSON config in asgi.py applies to our own loggers above uvicorn's.
CMD ["uvicorn", "nudg3_mcp.asgi:app", \
     "--host", "0.0.0.0", \
     "--port", "8080", \
     "--workers", "1"]

# Cloud Run also probes /health independently; this HEALTHCHECK is for
# local docker run smoke and a belt-and-braces signal in any host that
# respects it. Failing fast is better than serving 5xx for minutes.
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
  CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8080/health', timeout=4).read()" || exit 1
