|
| 1 | +# syntax=docker/dockerfile:1 |
| 2 | + |
| 3 | +# llama.cpp embeddings sidecar — backs odek's memory.embedding (http provider). |
| 4 | +# |
| 5 | +# Builds llama-server from source pinned to the SAME llama.cpp release as the |
| 6 | +# main image (LLAMA_VERSION), and bundles a pinned nomic-embed-text-v1.5 GGUF |
| 7 | +# so the service is fully offline after build — no first-run model download. |
| 8 | +# This mirrors how the main image bundles whisper.cpp + MiniCPM-V. |
| 9 | +# |
| 10 | +# nomic-embed-text-v1.5 is a 768-dim text embedding model (~84 MB at Q4_K_M). |
| 11 | +# odek sends raw summary/query text for both corpus and query, so the embedding |
| 12 | +# space stays symmetric even without nomic's optional task-instruction prefixes. |
| 13 | +# |
| 14 | +# Override the model with build args, e.g. a higher-quality quant: |
| 15 | +# --build-arg EMBED_QUANT=Q8_0 |
| 16 | +# Available quants in this repo: Q4_K_M (default) | Q5_K_M | Q6_K | Q8_0 | f16 |
| 17 | + |
| 18 | +# ---- build stage: compile llama-server + fetch the model ---- |
| 19 | +# Same Debian Bookworm base as the runtime stage so the binary links against the |
| 20 | +# exact glibc/libstdc++ present at runtime (no ABI mismatch — see the main |
| 21 | +# Dockerfile's llama.cpp stage for the rationale). |
| 22 | +FROM debian:bookworm-slim AS build |
| 23 | +ARG LLAMA_VERSION=b9549 |
| 24 | +# Pin the embeddings model + git revision so the image is reproducible. |
| 25 | +ARG EMBED_HF_REPO=nomic-ai/nomic-embed-text-v1.5-GGUF |
| 26 | +ARG EMBED_HF_REVISION=0188c9bf409793f810680a5a431e7b899c46104c |
| 27 | +ARG EMBED_QUANT=Q4_K_M |
| 28 | +ARG EMBED_FILE=nomic-embed-text-v1.5.${EMBED_QUANT}.gguf |
| 29 | + |
| 30 | +RUN apt-get update && apt-get install -y --no-install-recommends \ |
| 31 | + git cmake make g++ curl ca-certificates \ |
| 32 | + && rm -rf /var/lib/apt/lists/* |
| 33 | + |
| 34 | +# BUILD_SHARED_LIBS=OFF statically links llama's internal libraries; GGML_OPENMP |
| 35 | +# OFF drops the libgomp dependency; LLAMA_CURL=OFF because the model is bundled |
| 36 | +# (no runtime download). Target llama-server (the OpenAI-compatible HTTP server) |
| 37 | +# instead of the main image's llama-mtmd-cli. |
| 38 | +RUN git clone --depth 1 --branch "${LLAMA_VERSION}" \ |
| 39 | + https://github.com/ggerganov/llama.cpp /llama \ |
| 40 | + && cmake -S /llama -B /llama/build \ |
| 41 | + -DCMAKE_BUILD_TYPE=Release \ |
| 42 | + -DBUILD_SHARED_LIBS=OFF \ |
| 43 | + -DGGML_NATIVE=OFF \ |
| 44 | + -DGGML_OPENMP=OFF \ |
| 45 | + -DLLAMA_CURL=OFF \ |
| 46 | + -DLLAMA_BUILD_TESTS=OFF \ |
| 47 | + && cmake --build /llama/build -j"$(nproc)" --target llama-server \ |
| 48 | + && install -m 755 /llama/build/bin/llama-server /usr/local/bin/llama-server \ |
| 49 | + && rm -rf /llama |
| 50 | + |
| 51 | +# Fetch the pinned GGUF into a fixed image path. |
| 52 | +RUN mkdir -p /models \ |
| 53 | + && curl -fSL --retry 5 --retry-delay 5 --retry-connrefused --retry-all-errors \ |
| 54 | + "https://huggingface.co/${EMBED_HF_REPO}/resolve/${EMBED_HF_REVISION}/${EMBED_FILE}" \ |
| 55 | + -o /models/embed.gguf |
| 56 | + |
| 57 | +# ---- runtime stage ---- |
| 58 | +FROM debian:bookworm-slim |
| 59 | +# libstdc++6 for the C++ binary; curl only for the compose healthcheck; |
| 60 | +# ca-certificates is harmless and tiny. No outbound network is needed at runtime. |
| 61 | +RUN apt-get update && apt-get install -y --no-install-recommends \ |
| 62 | + libstdc++6 ca-certificates curl \ |
| 63 | + && rm -rf /var/lib/apt/lists/* |
| 64 | +COPY --from=build /usr/local/bin/llama-server /usr/local/bin/llama-server |
| 65 | +COPY --from=build /models/embed.gguf /models/embed.gguf |
| 66 | + |
| 67 | +# Run non-root (uid 1000), matching the main image's posture. |
| 68 | +RUN useradd -u 1000 -m llama |
| 69 | +USER llama |
| 70 | +EXPOSE 8080 |
| 71 | + |
| 72 | +# --embeddings enables the /v1/embeddings endpoint; --pooling mean matches |
| 73 | +# nomic-embed-text; --ctx-size 2048 is the model's training context (episode |
| 74 | +# summaries are capped at ~1 KB, well within it). Bind all interfaces — only |
| 75 | +# the compose network can reach it (no host port is published). |
| 76 | +ENTRYPOINT ["llama-server", \ |
| 77 | + "--host", "0.0.0.0", "--port", "8080", \ |
| 78 | + "--model", "/models/embed.gguf", \ |
| 79 | + "--embeddings", "--pooling", "mean", "--ctx-size", "2048"] |
0 commit comments