# ---- Build frontend ---- FROM node:20-slim AS frontend-build # VITE_API_URL: leave empty for same-origin (backend serves frontend), # or set to a full URL (e.g. https://api.example.com) for cross-origin. ARG VITE_API_URL="" ENV VITE_API_URL=$VITE_API_URL WORKDIR /app/frontend COPY frontend/package.json frontend/package-lock.json* ./ RUN npm install COPY frontend/ ./ RUN npm run build # ---- Runtime ---- FROM python:3.11-slim WORKDIR /app # Install uv RUN pip install uv # Copy backend COPY backend/pyproject.toml backend/ COPY backend/visual_notebook/ backend/visual_notebook/ # Install backend dependencies RUN cd backend && uv pip install --system -e . # Copy demo data COPY datasets/ /app/datasets/ # Copy built frontend COPY --from=frontend-build /app/frontend/dist /app/static # Environment defaults (override at runtime via -e or orchestrator) ENV DATA_DIR=/app/datasets ENV CHECKPOINT_DIR=/app/checkpoints ENV CORS_ORIGINS=* ENV HOST=0.0.0.0 ENV PORT=7860 ENV STATIC_DIR=/app/static # Create checkpoints dir RUN mkdir -p /app/checkpoints # Expose port (HF Spaces uses 7860, Render auto-detects) EXPOSE 7860 # Health check for container orchestrators HEALTHCHECK --interval=30s --timeout=10s --start-period=15s --retries=3 \ CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:7860/health')" || exit 1 # Start command CMD ["uvicorn", "visual_notebook.main:app", "--host", "0.0.0.0", "--port", "7860", "--workers", "1"]