Download Dockerfile from Shwy1001/BioPatch: direct link, hf CLI and curl.
- Browser
- Download file 4.96 kB
-
https://huggingface.co/spaces/Shwy1001/BioPatch/resolve/main/Dockerfile
- Command line
-
hf download hf://spaces/Shwy1001/BioPatch/Dockerfile
-
curl -L -o Dockerfile https://huggingface.co/spaces/Shwy1001/BioPatch/resolve/main/Dockerfile
4.96 kB
| # syntax=docker/dockerfile:1.7 | |
| # --------------------------------------------------------------------------- | |
| # BioPatch backend — Hugging Face Spaces + Fly.io compatible. | |
| # | |
| # IMPORTANT — LLM backend on this image: | |
| # Default: JARVIS_LLM_BACKEND=local → llama-cpp-python in-process | |
| # Default model: BioMistral-7B Q4_K_M (~4.4 GB weights, ~6 GB RAM with | |
| # 8K context). Tuned for the HF Spaces cpu-upgrade tier (8 vCPU / | |
| # 32 GB RAM). On the free tier this OOMs at load time — fall back to | |
| # a smaller model by overriding JARVIS_LLM_REPO / JARVIS_LLM_FILE / | |
| # JARVIS_LLM_CHAT_FORMAT in the Space Variables. | |
| # | |
| # Why local and not HF Inference on a Space: | |
| # HF Spaces sandbox blocks outbound DNS to api-inference.huggingface.co | |
| # (anti-loop policy), so the hosted Inference API is unreachable from | |
| # inside a Space. Local llama-cpp works. | |
| # | |
| # Set JARVIS_LLM_BACKEND=hf if you deploy this image OUTSIDE a Space | |
| # (e.g. Fly.io) and prefer the hosted API; you'll also need HF_TOKEN. | |
| # | |
| # Persistent storage: | |
| # When the Space has persistent storage enabled, /data is mounted as | |
| # a writable volume. The env vars below default to /data paths so the | |
| # SQLite DB, wound photos and the GGUF model cache survive restarts. | |
| # Without persistent storage, override these to /app paths via the | |
| # Space Variables. | |
| # | |
| # Thread safety: every BLAS / OpenMP / sklearn parallel pool is capped | |
| # at 1 thread + the RF model is forced to n_jobs=1 in code. This | |
| # eliminates the GGML_ASSERT / 'Failed joining thread' cascade that | |
| # crashed the container under simulator load (joblib pool corrupted | |
| # llama's GGML workspace). | |
| # --------------------------------------------------------------------------- | |
| ARG PYTHON_VERSION=3.12 | |
| FROM python:${PYTHON_VERSION}-slim AS base | |
| ENV PYTHONDONTWRITEBYTECODE=1 \ | |
| PYTHONUNBUFFERED=1 \ | |
| PIP_NO_CACHE_DIR=1 \ | |
| PIP_DISABLE_PIP_VERSION_CHECK=1 \ | |
| PIP_PREFER_BINARY=1 | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| build-essential \ | |
| libopenblas-dev \ | |
| ca-certificates \ | |
| curl \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # HF Spaces runs as UID 1000. | |
| RUN useradd -m -u 1000 user | |
| WORKDIR /app | |
| # Core deps first. | |
| COPY backend/requirements.txt /app/requirements.txt | |
| RUN pip install -r requirements.txt | |
| # LLM stack — pull pre-built CPU wheels from abetlen's dedicated index. | |
| # llama-cpp-python intentionally publishes only source dists to PyPI; | |
| # the binary wheels (built per Python version × platform) live at | |
| # https://abetlen.github.io/llama-cpp-python/whl/cpu. With --only-binary | |
| # pip refuses to compile from source, so if the wheel is genuinely | |
| # missing for our Python it errors out in seconds with a clear message | |
| # instead of OOMing 8 minutes into a C++ compile on the HF free tier. | |
| COPY backend/requirements-llm.txt /app/requirements-llm.txt | |
| RUN pip install --only-binary=:all: \ | |
| --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cpu \ | |
| -r requirements-llm.txt | |
| COPY backend /app | |
| RUN python -m scripts.seed_clinical_data || true | |
| # Thread caps — keep sklearn / OpenBLAS / OpenMP / MKL single-threaded. | |
| # Combined with the n_jobs=1 forced on the loaded RandomForest model, | |
| # this guarantees the joblib threadpool never spawns and never collides | |
| # with llama-cpp's GGML workspace. | |
| ENV OMP_NUM_THREADS=1 \ | |
| OPENBLAS_NUM_THREADS=1 \ | |
| MKL_NUM_THREADS=1 \ | |
| BLIS_NUM_THREADS=1 \ | |
| NUMEXPR_MAX_THREADS=1 \ | |
| JARVIS_LLM_BACKEND=local \ | |
| JARVIS_LLM_REPO=MaziyarPanahi/BioMistral-7B-GGUF \ | |
| JARVIS_LLM_FILE=BioMistral-7B.Q4_K_M.gguf \ | |
| JARVIS_LLM_CHAT_FORMAT=mistral-instruct \ | |
| JARVIS_LLM_CACHE=/data/models \ | |
| JARVIS_LLM_CTX=4096 \ | |
| JARVIS_LLM_THREADS=8 \ | |
| JARVIS_HF_MODEL=meta-llama/Llama-3.2-3B-Instruct \ | |
| DATABASE_URL=sqlite:////data/biopatch.db \ | |
| WOUND_PHOTO_DIR=/data/wound_photos \ | |
| HF_HOME=/data/.cache/huggingface \ | |
| PORT=7860 \ | |
| ENABLE_SIMULATOR=true \ | |
| SIMULATOR_INTERVAL_SECONDS=15.0 \ | |
| AUTO_SEED=true | |
| # Pre-create fallback dirs under /app for hosts WITHOUT persistent /data | |
| # (Fly.io, local docker run, etc.). On a HF Space with persistent storage | |
| # enabled, /data is mounted at runtime and the env vars above override | |
| # these paths. | |
| RUN mkdir -p /app/ai/artifacts/models /app/data/wound_photos /app/.cache/huggingface \ | |
| && chown -R user:user /app | |
| # Stay as root for the runtime. HF Spaces persistent /data is mounted | |
| # with FUSE-style perms that silently reject chown from inside the | |
| # container, so dropping to uid 1000 leaves the volume unwritable | |
| # (sqlite OperationalError: unable to open database file). Running | |
| # uvicorn as root sidesteps the perm check; the HF sandbox confines | |
| # the container regardless. The threading caps + RF n_jobs=1 already | |
| # neutralise the previous GGML / joblib collision, so non-root is no | |
| # longer required for stability. | |
| EXPOSE 8000 7860 | |
| CMD ["sh", "-c", "uvicorn main:app --host 0.0.0.0 --port ${PORT:-8000} --workers 1"] | |