# Rubban — public Space shell. Contains no application code: at build time it downloads the private bundle # from the dataset zangir/rubban-bundle using the HF_TOKEN build secret, then serves it behind the sign-in gate. FROM python:3.12-slim ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 PIP_NO_CACHE_DIR=1 \ RUBBAN_DATA_ROOT=/data PORT=7860 BUNDLE_REPO=zangir/rubban-bundle BUNDLE_FILE=rubban-bundle.tar.gz RUN apt-get update && apt-get install -y --no-install-recommends libglib2.0-0 curl ca-certificates && rm -rf /var/lib/apt/lists/* \ && useradd -m -u 1000 rubban && mkdir -p /srv /data && chown -R rubban:rubban /srv /data WORKDIR /srv RUN pip install "huggingface_hub>=0.25" # cache-buster: changing BUNDLE_REV in the Space variables forces a fresh download ARG BUNDLE_REV=main RUN --mount=type=secret,id=HF_TOKEN,mode=0444,required=true \ python - <<'EOF' import os, tarfile, pathlib from huggingface_hub import hf_hub_download token = pathlib.Path("/run/secrets/HF_TOKEN").read_text().strip() p = hf_hub_download(repo_id=os.environ["BUNDLE_REPO"], filename=os.environ["BUNDLE_FILE"], repo_type="dataset", token=token, revision=os.environ.get("BUNDLE_REV", "main")) with tarfile.open(p) as t: t.extractall("/srv", filter="data") print("bundle extracted:", sorted(os.listdir("/srv"))) EOF RUN pip install -r /srv/rubban-app/requirements.txt && pip install -e /srv/rubban-core \ && cp -r /srv/data/. /data/ && chown -R rubban:rubban /srv /data USER rubban # Claude Code CLI (native build) so the AI layer runs on the Space with a long-lived token (`claude setup-token` → secret CLAUDE_CODE_OAUTH_TOKEN) RUN curl -fsSL https://claude.ai/install.sh | bash && ~/.local/bin/claude --version ENV PATH="/home/rubban/.local/bin:${PATH}" CLAUDE_BIN=/home/rubban/.local/bin/claude HOME=/home/rubban WORKDIR /srv/rubban-app EXPOSE 7860 CMD ["python", "server.py"]