Maverick6022/dataforge
0
1# ── Stage 1: install dependencies ─────────────────────────────────────────────2FROM python:3.11-slim AS builder3 4COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv5 6WORKDIR /build7 8# Copy requirements first so Docker caches this layer separately9COPY backend/requirements.txt ./requirements.txt10COPY backend/requirements-boosters.txt ./requirements-boosters.txt11 12# Create venv and install packages13RUN uv venv /opt/venv --python 3.1114 15ENV VIRTUAL_ENV=/opt/venv16ENV PATH="/opt/venv/bin:$PATH"17 18# Core dependencies (auth + DB + ML)19RUN uv pip install --no-cache -r requirements.txt20 21# Optional ML boosters (failures are non-fatal)22RUN uv pip install --no-cache "xgboost>=2.0.0" || echo "xgboost skipped"23RUN uv pip install --no-cache "lightgbm>=4.0.0" || echo "lightgbm skipped"24RUN uv pip install --no-cache "catboost>=1.2.0" || echo "catboost skipped"25 26 27# ── Stage 2: lean runtime image ───────────────────────────────────────────────28FROM python:3.11-slim AS runtime29 30LABEL maintainer="DataForge"31LABEL description="DataForge AutoML Platform"32 33# libgomp1 – required by LightGBM and XGBoost at runtime34# libpq5 – required by psycopg2-binary at runtime35RUN apt-get update \36 && apt-get install -y --no-install-recommends libgomp1 libpq5 \37 && rm -rf /var/lib/apt/lists/*38 39# Copy only the pre-built venv from stage 140COPY --from=builder /opt/venv /opt/venv41 42ENV VIRTUAL_ENV=/opt/venv43ENV PATH="/opt/venv/bin:$PATH"44 45# ── Required environment variables (set in HF Space secrets) ──────────────────46# DATABASE_URL – e.g. postgresql://user:pass@db.neon.tech/dataforge?sslmode=require47# JWT_SECRET_KEY – a long random string; generate with: python -c "import secrets; print(secrets.token_hex(32))"48#49# Optional overrides:50# JWT_EXPIRE_MINUTES (default 60)51# COOKIE_SECURE (default true; set false for local plain-HTTP dev)52# DB_SSLMODE (default require)53# CORS_ORIGINS (comma-separated list; default *)54 55# Run as non-root user (required for Hugging Face Spaces)56RUN useradd -m -u 1000 dataforge57USER dataforge58 59WORKDIR /app60 61COPY --chown=dataforge:dataforge backend/ ./backend/62COPY --chown=dataforge:dataforge frontend/ ./frontend/63 64WORKDIR /app/backend65 66# NOTE: /data is mounted at runtime by HF Spaces as a FUSE volume.67# We deliberately do NOT create /data here – it doesn't exist at build time.68# The app creates /data/uploads and /data/models on first boot via os.makedirs.69 70EXPOSE 786071 72HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \73 CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:7860/health')" || exit 174 75CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]76 