| # ββ Stage 1: Build the Next.js frontend ββββββββββββββββββββββββββ | |
| FROM node:20-slim AS frontend-build | |
| WORKDIR /app/frontend | |
| COPY src/frontend/package.json src/frontend/package-lock.json* ./ | |
| RUN npm ci 2>/dev/null || npm install | |
| COPY src/frontend/ ./ | |
| # Build-time env: WebSocket and API go through the same origin via nginx | |
| ENV NEXT_PUBLIC_WS_URL="" | |
| ENV NEXT_PUBLIC_API_URL="" | |
| ENV NEXT_TELEMETRY_DISABLED=1 | |
| # Limit Node memory for constrained HF Space build environment | |
| RUN NODE_OPTIONS=--max-old-space-size=1536 npm run build | |
| # ββ Stage 2: Production image ββββββββββββββββββββββββββββββββββββ | |
| FROM python:3.10-slim | |
| # System deps: nginx + node (for Next.js standalone server) | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| nginx \ | |
| curl \ | |
| && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ | |
| && apt-get install -y --no-install-recommends nodejs \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # ββ Python backend βββββββββββββββββββββββββββββββββββββββββββββββ | |
| WORKDIR /app/backend | |
| COPY src/backend/requirements.txt ./ | |
| # Install Python deps (skip torch/transformers β we use API mode only) | |
| RUN pip install --no-cache-dir \ | |
| fastapi==0.115.0 \ | |
| "uvicorn[standard]==0.30.6" \ | |
| websockets==12.0 \ | |
| pydantic-settings==2.5.2 \ | |
| python-dotenv==1.0.1 \ | |
| openai==1.51.0 \ | |
| httpx==0.27.2 \ | |
| chromadb==0.5.7 \ | |
| sentence-transformers==3.1.1 \ | |
| python-multipart==0.0.10 | |
| # Copy backend source (ChromaDB will auto-build from app/data/clinical_guidelines.json on first run) | |
| COPY src/backend/app/ ./app/ | |
| # ββ Frontend standalone build ββββββββββββββββββββββββββββββββββββ | |
| # Next.js standalone output: self-contained server, no node_modules needed | |
| WORKDIR /app/frontend | |
| COPY --from=frontend-build /app/frontend/.next/standalone ./ | |
| COPY --from=frontend-build /app/frontend/.next/static ./.next/static | |
| RUN mkdir -p ./public | |
| # ββ Nginx config βββββββββββββββββββββββββββββββββββββββββββββββββ | |
| COPY space/nginx.conf /etc/nginx/nginx.conf | |
| # ββ Startup script βββββββββββββββββββββββββββββββββββββββββββββββ | |
| COPY space/start.sh /app/start.sh | |
| RUN chmod +x /app/start.sh | |
| # HF Spaces expects port 7860 | |
| EXPOSE 7860 | |
| # Health check | |
| HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ | |
| CMD curl -f http://localhost:7860/api/health || exit 1 | |
| CMD ["/app/start.sh"] | |