SebAustin's picture
deploy: routing-agent demo dashboard
5299d9a verified
Raw
History Blame Contribute Delete
3.05 kB
# syntax=docker/dockerfile:1
#
# ============================================================================
# HUGGING FACE SPACE VARIANT β€” not the default build target.
#
# The harness/scoring image is `Dockerfile` at the repo root (ENTRYPOINT =
# adapter.py, harness-facing /input -> /output contract) and stays the
# default for `docker build .` / the scoring pipeline. This file only
# exists so the orchestrator can assemble a separate Hugging Face Docker
# Space repo that runs the judge-facing demo dashboard
# (`routing_agent.webapp`) on the port Spaces expects (7860).
#
# This file is NOT deployed by this repo directly β€” see
# `spaces/README.md` ("How the orchestrator assembles this Space repo")
# and the main repo's `DEPLOYMENT.md` for the exact assembly + gated
# deploy steps. When copied into the Space repo it must be renamed to
# `Dockerfile` (HF Docker Spaces require that exact filename at the repo
# root).
# ============================================================================
#
# Build steps below mirror the main Dockerfile (same base image, same uv
# install method, same layer-caching order, same non-root user) so the
# Space image has the same size/security posture as the harness image β€”
# the only differences are the final PORT/EXPOSE/CMD, which run the demo
# webapp instead of the adapter.
FROM python:3.12-slim AS base
# Copy the uv/uvx binaries from the official distroless uv image instead of
# installing via pip or curl|sh β€” smaller, pinned, and avoids a build-time
# network fetch script.
COPY --from=ghcr.io/astral-sh/uv:0.11.18 /uv /uvx /usr/local/bin/
ENV UV_COMPILE_BYTECODE=1 \
UV_LINK_MODE=copy \
UV_PROJECT_ENVIRONMENT=/opt/venv \
PATH="/opt/venv/bin:$PATH" \
PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1
WORKDIR /app
# Install dependencies first (layer caching): only the `main` (default)
# dependency group, never `dev` β€” no pytest/ruff/respx in the shipped image.
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-install-project --no-dev
# Now copy source and install the project itself. README.md is required by
# hatchling (pyproject `readme` field) to build the project wheel.
COPY README.md ./
COPY src/ ./src/
COPY evals/ ./evals/
RUN uv sync --frozen --no-dev
# Non-root user β€” same posture as the harness image. Spaces containers do
# not use the /input,/output volumes (those are the scoring harness's
# contract), but keep the directories for parity / in case a judge runs
# this image with `docker run -p ... <img> python -m routing_agent.adapter`
# to sanity-check the harness path too.
RUN groupadd --system app && useradd --system --gid app --home /app app \
&& mkdir -p /input /output \
&& chown -R app:app /app /input /output
USER app
# Hugging Face Docker Spaces always route traffic to port 7860 inside the
# container (see spaces/README.md front-matter `app_port: 7860`).
ENV PORT=7860
EXPOSE 7860
# Space-facing default: run the demo dashboard, not the harness adapter.
CMD ["python", "-m", "routing_agent.webapp"]