| # ββ stage 1: build the React frontend ββββββββββββββββββββββββ | |
| FROM node:20-slim AS frontend | |
| WORKDIR /fe | |
| COPY frontend/package.json frontend/package-lock.json ./ | |
| RUN npm ci --no-audit --no-fund | |
| COPY frontend/ ./ | |
| # empty API base = same-origin requests (the FastAPI container serves both) | |
| ENV VITE_API_BASE= | |
| RUN npm run build | |
| # ββ stage 2: backend + seeded demo index βββββββββββββββββββββ | |
| # 3.13 matches the version the pinned requirements were resolved under | |
| FROM python:3.13-slim | |
| WORKDIR /app | |
| # model caches live inside /app so the runtime user can read them and | |
| # nothing re-downloads on container restart | |
| ENV HF_HOME=/app/.cache \ | |
| PYTHONUNBUFFERED=1 | |
| COPY requirements.txt . | |
| RUN pip install --no-cache-dir -r requirements.txt \ | |
| && python -m spacy download en_core_web_sm | |
| COPY backend/ backend/ | |
| COPY data/uploads/ data/uploads/ | |
| # parse the committed public filing into the graph + vector store now, | |
| # at build time β the container boots demo-ready | |
| RUN python -m backend.seed | |
| COPY --from=frontend /fe/dist frontend/dist | |
| # HF Spaces runs containers as uid 1000; own everything we write to | |
| RUN useradd -m -u 1000 appuser && chown -R appuser /app | |
| USER appuser | |
| # hosted demo talks to Groq (set GROQ_API_KEY as a Space secret); | |
| # local/private mode is: clone the repo, run with Ollama instead | |
| ENV LLM_BACKEND=groq | |
| EXPOSE 7860 | |
| CMD ["uvicorn", "backend.main:app", "--host", "0.0.0.0", "--port", "7860"] | |