Spaces:
Sleeping
Sleeping
File size: 3,053 Bytes
5299d9a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | # 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"]
|