Spaces:
Sleeping
Sleeping
| # Multi-stage build: | |
| # Stage 1 β build the Next.js frontend to a static export | |
| # Stage 2 β Python runtime serving FastAPI + the built frontend on the same port | |
| # ---------------------------------------------------------------------------- | |
| # Stage 1 β Node builder | |
| # ---------------------------------------------------------------------------- | |
| FROM node:22-alpine AS frontend-builder | |
| WORKDIR /app/frontend | |
| # Install deps first for layer caching | |
| COPY frontend/package.json frontend/package-lock.json* ./ | |
| RUN npm ci --no-audit --no-fund | |
| # Copy the rest of the frontend and build | |
| COPY frontend/ ./ | |
| # In production, the frontend calls the same origin (no separate backend URL). | |
| ENV NEXT_PUBLIC_BACKEND_URL="" | |
| # Static-export the app β produces ./out | |
| RUN npm run build | |
| # ---------------------------------------------------------------------------- | |
| # Stage 2 β Python runtime (FastAPI + corpus + Chroma + DuckDB + frontend) | |
| # ---------------------------------------------------------------------------- | |
| FROM python:3.11-slim | |
| WORKDIR /app | |
| # System deps for pdfplumber + torch CPU + sentence-transformers | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| build-essential \ | |
| libpoppler-cpp-dev \ | |
| pkg-config \ | |
| poppler-utils \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # Install Python deps | |
| COPY requirements.txt ./ | |
| RUN pip install --no-cache-dir --upgrade pip && \ | |
| pip install --no-cache-dir -r requirements.txt | |
| # Pre-download the embedding model so the first request is fast (no cold load) | |
| RUN python -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('BAAI/bge-small-en-v1.5')" | |
| # Copy the backend source + RAG modules + data | |
| COPY backend ./backend | |
| COPY rag ./rag | |
| COPY eval ./eval | |
| COPY docs ./docs | |
| # Copy the built frontend from stage 1 | |
| COPY --from=frontend-builder /app/frontend/out ./frontend/out | |
| # HF Spaces sends traffic to $PORT (default 7860). uvicorn will bind to it. | |
| ENV PORT=7860 | |
| EXPOSE 7860 | |
| # Copy entrypoint and make it executable | |
| COPY entrypoint.sh ./entrypoint.sh | |
| RUN chmod +x ./entrypoint.sh | |
| # Use a non-root user (HF Spaces recommends this for Docker spaces) | |
| RUN useradd -m -u 1000 user && chown -R user:user /app | |
| USER user | |
| # Start: entrypoint validates Chroma + (re-)ingests if needed, then runs uvicorn | |
| CMD ["sh", "/app/entrypoint.sh"] | |