Obsidian / Dockerfile
Jolly6443's picture
Fix: remove hardcoded ENV MODEL_ID=qwen that was silently overriding SPACE_ROLE on every Space
fd8d54e verified
Raw
History Blame Contribute Delete
4.26 kB
# ── Base image ────────────────────────────────────────────────
# Alpine (musl libc), not Debian slim (glibc) β€” the abetlen prebuilt CPU
# wheel for llama-cpp-python is itself linked against musl (confirmed via
# readelf: NEEDED libc.musl-x86_64.so.1), even though its filename is
# tagged with the generic "linux_x86_64" platform tag rather than a
# proper musllinux tag. On a glibc image this crashes at import time with
# "OSError: libc.musl-x86_64.so.1: cannot open shared object file".
# All other compiled deps here (pydantic-core, uvloop, httptools) publish
# real musllinux wheels, so nothing needs to compile from source.
FROM python:3.11-alpine
# ── Environment ───────────────────────────────────────────────
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=1 \
PIP_DISABLE_PIP_VERSION_CHECK=1
# ── System dependencies ───────────────────────────────────────
# Runtime-only β€” libstdc++/libgomp satisfy the wheel's NEEDED entries
# (ggml-cpu uses OpenMP + C++). No compiler needed since nothing builds
# from source.
RUN apk add --no-cache curl libstdc++ libgomp
# ── Work directory ────────────────────────────────────────────
WORKDIR /app
# ── Python dependencies ───────────────────────────────────────
# Install llama-cpp-python from precompiled CPU wheels (no compile β€” fast!)
# Pinned version + --only-binary forces pip to fail fast if the abetlen wheel
# index ever stops publishing a matching wheel, instead of silently falling
# back to a from-source cmake build that blows past HF's build timeout.
# Plain llama-cpp-python (no [server] extra) β€” we load the model directly
# with the Llama class and implement the OpenAI-style routes ourselves,
# rather than running llama_cpp.server's own bundled FastAPI app (which had
# a bug in its generic error-handling path that returned empty 400s on every
# proxied request). Then install our own minimal FastAPI stack.
RUN pip install --upgrade pip && \
pip install \
--only-binary=llama-cpp-python \
"llama-cpp-python==0.3.19" \
--extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cpu && \
pip install \
fastapi \
"uvicorn[standard]" \
huggingface_hub \
pydantic
# ── Copy app ──────────────────────────────────────────────────
COPY app.py .
# ── Port ──────────────────────────────────────────────────────
EXPOSE 7860
# ── Default environment (override via Space Settings) ─────────
# SPACE_ROLE: "reasoning" | "uncensored" | "general" (default: general) β€”
# picks the curated model automatically. Deliberately NOT setting MODEL_ID
# here: a hardcoded ENV MODEL_ID would always exist in os.environ, so
# app.py's `os.environ.get("MODEL_ID", ROLE_TO_MODEL_ID[SPACE_ROLE])`
# fallback could never trigger β€” every Space would pin to that value
# regardless of SPACE_ROLE. (This bit us once: this line used to read
# `ENV MODEL_ID="qwen"` and silently overrode SPACE_ROLE on every Space.)
# MODEL_ID / MODEL_REPO / MODEL_FILE: optional raw overrides, set only as a
# Space Variable if you want to bypass role-based selection entirely.
# N_CTX: context window tokens (default: 8192)
# N_THREADS: CPU threads (default: 4)
# API_KEY: optional bearer token to protect the API
# CONFIG_URL: optional URL to a JSON config (for multi-Space clusters)
ENV N_CTX="8192" \
N_THREADS="4"
# ── Launch ────────────────────────────────────────────────────
CMD ["python", "app.py"]