Spaces:
Sleeping
Sleeping
| # ============================================================================= | |
| # Fin-EvalOps backend — Docker image for Hugging Face Spaces (Docker SDK) | |
| # | |
| # Build context: repository root. | |
| # Runtime layout (matches config.py's parents[2] = project root): | |
| # /app/ | |
| # backend/ # FastAPI app | |
| # skills/ # 13 self-eval + 14 competitor + 14 e2e skill protocols | |
| # 自研评测测试集/ # 13 categories, 3627 test cases (one JSON file per category) | |
| # /.cache/huggingface/ # HF Hub cache (datasets, models) | |
| # /data/ # SQLite DB (ephemeral — synced to HF Dataset) | |
| # ============================================================================= | |
| FROM python:3.11-slim AS base | |
| # System deps: curl for healthcheck, tini for clean signal handling, git for | |
| # huggingface_hub's snapshot_download fallback. | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| curl \ | |
| ca-certificates \ | |
| tini \ | |
| git \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # HF Spaces exposes the app on port 7860 (or the value of $PORT). | |
| # Make the port explicit for clarity; uvicorn reads $PORT at runtime. | |
| ENV PORT=7860 \ | |
| PYTHONUNBUFFERED=1 \ | |
| PYTHONDONTWRITEBYTECODE=1 \ | |
| PIP_NO_CACHE_DIR=1 \ | |
| PIP_DISABLE_PIP_VERSION_CHECK=1 \ | |
| # Tell huggingface_hub where to put its cache (and where to look first | |
| # when downloading dataset files). Persistent across rebuilds in the | |
| # image layer; not persistent across Space restarts (intentional). | |
| HF_HOME=/.cache/huggingface \ | |
| TRANSFORMERS_CACHE=/.cache/huggingface/hub | |
| WORKDIR /app | |
| # ---- Python deps (cache layer) ---- | |
| COPY backend/requirements.txt /app/backend/requirements.txt | |
| RUN pip install --no-cache-dir -r /app/backend/requirements.txt | |
| # ---- App source ---- | |
| COPY backend/ /app/backend/ | |
| COPY skills/ /app/skills/ | |
| # NOTE: 数据测试集/ is NOT bundled in the image. Tests are uploaded at | |
| # runtime via the web UI's "导入 JSON" button (POST /api/testsets/import-file). | |
| # scan-disk is a graceful no-op when testsets_root does not exist. | |
| # HF Spaces persistent storage opt-in (free tier: 20GB on CPU). | |
| # This is where the SQLite DB lives between deploys. The app still pushes | |
| # snapshots to a HF Dataset repo for off-host backup, so disk loss is non-fatal. | |
| RUN mkdir -p /data /.cache/huggingface | |
| # Ensure the data dir is writable by the runtime user (HF Spaces runs as | |
| # user 1000 by default, not root). | |
| RUN chown -R 1000:1000 /app /data /.cache/huggingface 2>/dev/null || true | |
| USER 1000 | |
| WORKDIR /app/backend | |
| EXPOSE 7860 | |
| # tini → forwards SIGTERM properly to uvicorn so the lifespan `shutdown` | |
| # hook runs and we get a final HF push. | |
| ENTRYPOINT ["/usr/bin/tini", "--"] | |
| # Default command. $PORT is set by the Space runtime (defaults to 7860 above). | |
| CMD ["sh", "-c", "exec uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-7860} --workers 1 --proxy-headers"] | |
| # ---- Healthcheck (Space hardware uses this) ---- | |
| HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \ | |
| CMD curl -fsS http://localhost:${PORT:-7860}/api/health || exit 1 | |