| # legal-eye — Hugging Face Space Dockerfile | |
| # | |
| # Hardware target: HF Space "CPU basic" (free tier, 16 GB RAM). | |
| # Image stays slim — no compiler in final layer, runs as UID 1000 per | |
| # HF Space conventions (their internal user is named "user", uid 1000). | |
| # | |
| # Differences from `tau_rag/Dockerfile.prod`: | |
| # • UID 1000 instead of 10001 (HF Space requirement) | |
| # • Single-stage (HF Spaces build + cache the same way regardless) | |
| # • EXPOSE 8000 + bind 0.0.0.0 (HF Space app_port) | |
| # • TAU_RAG_AUTOLOAD_PARQUET=0 — parquet (2.6 GB) won't fit on free tier | |
| # • TAU_RAG_CLUSTER_AUGMENT=1 — needed for eval quality (lifts virtuals) | |
| FROM python:3.11-slim | |
| # Build deps — kept thin so the image stays under 1 GB | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| build-essential \ | |
| gfortran \ | |
| libopenblas-dev \ | |
| liblapack-dev \ | |
| curl \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # HF Space convention: non-root user named "user" with UID 1000 | |
| RUN useradd -m -u 1000 user | |
| WORKDIR /app | |
| # Install Python deps first — separate layer so code edits don't bust | |
| # the dependency cache on rebuilds. | |
| COPY --chown=user:user tau_rag/requirements.txt ./requirements.txt | |
| RUN pip install --no-cache-dir --upgrade pip \ | |
| && pip install --no-cache-dir -r requirements.txt | |
| # Copy the legal-eye package | |
| COPY --chown=user:user tau_rag ./tau_rag | |
| USER user | |
| EXPOSE 8000 | |
| # /app is read-only after build — runtime caches (retrievers, clusters) | |
| # go to /tmp/tau_rag_runtime so the writable layer is cleanly scoped. | |
| # HF Spaces free tier doesn't persist /data across restarts anyway, so | |
| # /tmp is fine; we just rebuild the index on each boot (~15-30 s). | |
| ENV PYTHONPATH=/app \ | |
| PYTHONUNBUFFERED=1 \ | |
| TAU_RAG_HOST=0.0.0.0 \ | |
| TAU_RAG_PORT=8000 \ | |
| TAU_RAG_PRESET=hebrew_legal_prod \ | |
| TAU_RAG_RUNTIME_DIR=/tmp/tau_rag_runtime \ | |
| TAU_RAG_AUTOLOAD_PARQUET=0 \ | |
| TAU_RAG_AUTOLOAD_CORPUS=1 \ | |
| TAU_RAG_AUTOLOAD_CORPUS_PATH=/app/tau_rag/runtime/uploads/corpus_paid.jsonl \ | |
| TAU_RAG_TIER=paid \ | |
| TAU_RAG_CLUSTER_AUGMENT=1 \ | |
| TAU_RAG_AUTH_REQUIRED=true \ | |
| TAU_RAG_RATE_LIMIT_QPS=3 \ | |
| TAU_RAG_LOG_LEVEL=INFO | |
| # Secrets injected via HF Space "Settings → Secrets" (NOT baked here): | |
| # TAU_RAG_SEED_ADMIN_KEY — 32-hex API key for /v1/* auth | |
| # TAU_RAG_HMAC_SECRET — 32-hex HMAC secret for signed URLs | |
| # TAU_RAG_CORS_ORIGINS — frontend origin (e.g. https://legal-eye.vercel.app) | |
| CMD ["uvicorn", "tau_rag.api.fastapi_app:app", \ | |
| "--host", "0.0.0.0", "--port", "8000", "--workers", "1"] | |