# ───────────────────────────────────────────── # Stage 1: Build React frontend # ───────────────────────────────────────────── FROM node:20-alpine AS frontend-builder WORKDIR /app/frontend # Install dependencies first (layer cache) COPY frontend/package.json frontend/package-lock.json* ./ RUN npm ci # Copy source and build COPY frontend/ . RUN npm run build # ───────────────────────────────────────────── # Stage 2: Python backend (production image) # ───────────────────────────────────────────── FROM python:3.11-slim WORKDIR /app # Install Python dependencies COPY backend/requirements.txt ./requirements.txt RUN pip install --no-cache-dir -r requirements.txt # Copy backend and shared source COPY backend/ ./backend/ COPY models/ ./models/ # Copy compiled React app from Stage 1 COPY --from=frontend-builder /app/frontend/dist ./frontend/dist # HF Spaces requires non-root user with uid 1000 RUN useradd -m -u 1000 appuser USER appuser # HF Spaces requires port 7860 EXPOSE 7860 CMD ["uvicorn", "backend.main:app", "--host", "0.0.0.0", "--port", "7860"]