FROM python:3.11-slim # ── System dependencies ─────────────────────────────────────── RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ r-base \ r-base-dev \ libcurl4-openssl-dev \ libssl-dev \ libxml2-dev \ libzmq3-dev \ git \ wget \ && rm -rf /var/lib/apt/lists/* # ── Python dependencies (includes jupyter for IRkernel::installspec) ── COPY requirements.txt /tmp/requirements.txt RUN pip install --no-cache-dir -r /tmp/requirements.txt # ── R packages (jupyter is now on PATH, installspec will work) ──────── RUN Rscript -e " \ install.packages('pbdZMQ', repos='https://cloud.r-project.org', quiet=FALSE); \ stopifnot(requireNamespace('pbdZMQ')); \ install.packages('IRdisplay', repos='https://cloud.r-project.org', quiet=FALSE); \ install.packages('IRkernel', repos='https://cloud.r-project.org', quiet=FALSE); \ stopifnot(requireNamespace('IRkernel')); \ IRkernel::installspec(user=FALSE); \ install.packages('dplyr', repos='https://cloud.r-project.org', quiet=FALSE); \ cat('R setup complete\n') \ " # ── App ─────────────────────────────────────────────────────── WORKDIR /app COPY . /app RUN mkdir -p artifacts/py/figures artifacts/py/tables \ artifacts/r/figures artifacts/r/tables \ runs # ── HuggingFace: non-root user ──────────────────────────────── RUN useradd -m -u 1000 appuser && chown -R appuser /app USER appuser EXPOSE 7860 ENV GRADIO_SERVER_NAME="0.0.0.0" ENV GRADIO_SERVER_PORT="7860" CMD ["python", "app.py"]