Spaces:
Running
Running
Download Dockerfile from Mungert/NetMonLLMLive: direct link, hf CLI and curl.
- Browser
- Download file 13.2 kB
-
https://huggingface.co/spaces/Mungert/NetMonLLMLive/resolve/main/Dockerfile
- Command line
-
hf download hf://spaces/Mungert/NetMonLLMLive/Dockerfile
-
curl -L -o Dockerfile https://huggingface.co/spaces/Mungert/NetMonLLMLive/resolve/main/Dockerfile
13.2 kB
| # syntax=docker/dockerfile:1.4 | |
| # ============================================================ | |
| # Stage 1: Build CPU-optimized OpenBLAS + llama.cpp | |
| # ============================================================ | |
| FROM debian:13 AS native-build | |
| ENV DEBIAN_FRONTEND=noninteractive | |
| # ============================================================ | |
| # Native build dependencies | |
| # | |
| # Original packages retained: | |
| # build-essential | |
| # curl | |
| # ca-certificates | |
| # git | |
| # cmake | |
| # clang | |
| # pkg-config | |
| # ccache | |
| # wget | |
| # | |
| # gfortran is required for the source OpenBLAS build. | |
| # ============================================================ | |
| RUN apt-get update && \ | |
| apt-get install -y --no-install-recommends \ | |
| build-essential \ | |
| curl \ | |
| ca-certificates \ | |
| git \ | |
| cmake \ | |
| clang \ | |
| pkg-config \ | |
| ccache \ | |
| wget \ | |
| gfortran && \ | |
| update-ca-certificates && \ | |
| rm -rf /var/lib/apt/lists/* | |
| # ============================================================ | |
| # Build OpenBLAS from source | |
| # | |
| # No TARGET is specified. | |
| # OpenBLAS detects the build CPU and optimizes for it. | |
| # ============================================================ | |
| WORKDIR /build | |
| RUN git clone --depth 1 \ | |
| https://github.com/OpenMathLib/OpenBLAS.git \ | |
| /build/OpenBLAS | |
| WORKDIR /build/OpenBLAS | |
| # Suppress the enormous normal compiler log. | |
| # If compilation fails, print the final 100 lines. | |
| RUN make -j2 > /tmp/openblas-build.log 2>&1 || \ | |
| (echo "OpenBLAS build failed:" && \ | |
| tail -100 /tmp/openblas-build.log && \ | |
| false) && \ | |
| make PREFIX=/opt/OpenBLAS install \ | |
| > /tmp/openblas-install.log 2>&1 || \ | |
| (echo "OpenBLAS install failed:" && \ | |
| tail -100 /tmp/openblas-install.log && \ | |
| false) && \ | |
| rm -f \ | |
| /tmp/openblas-build.log \ | |
| /tmp/openblas-install.log | |
| # ============================================================ | |
| # Build llama.cpp against our source-built OpenBLAS | |
| # ============================================================ | |
| WORKDIR /build | |
| RUN git clone --depth 1 \ | |
| https://github.com/ggml-org/llama.cpp.git \ | |
| /build/llama.cpp | |
| WORKDIR /build/llama.cpp | |
| ENV PKG_CONFIG_PATH=/opt/OpenBLAS/lib/pkgconfig | |
| ENV LD_LIBRARY_PATH=/opt/OpenBLAS/lib | |
| RUN cmake -S . -B build \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCMAKE_PREFIX_PATH=/opt/OpenBLAS \ | |
| -DGGML_NATIVE=ON \ | |
| -DGGML_BLAS=ON \ | |
| -DGGML_BLAS_VENDOR=OpenBLAS \ | |
| -DLLAMA_CURL=OFF && \ | |
| cmake --build build \ | |
| --config Release \ | |
| -j2 | |
| # ============================================================ | |
| # Extract runtime files | |
| # | |
| # IMPORTANT: | |
| # Use libopenblas* as in your ORIGINAL Dockerfile. | |
| # | |
| # This copies: | |
| # libopenblas.so | |
| # libopenblas.so.0 | |
| # CPU-specific target library such as: | |
| # libopenblas_skylakexp-r0.3.34.dev.so | |
| # | |
| # This avoids creating broken OpenBLAS symlinks. | |
| # ============================================================ | |
| RUN mkdir -p \ | |
| /out/llama \ | |
| /out/openblas && \ | |
| cp -a build/bin/. /out/llama/ && \ | |
| cp -a /opt/OpenBLAS/lib/libopenblas* /out/openblas/ | |
| # ============================================================ | |
| # Stage 2: Build .NET application | |
| # ============================================================ | |
| FROM debian:13 AS dotnet-build | |
| ENV DEBIAN_FRONTEND=noninteractive | |
| ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 | |
| ENV DOTNET_NOLOGO=1 | |
| RUN apt-get update && \ | |
| apt-get install -y --no-install-recommends \ | |
| ca-certificates \ | |
| wget \ | |
| git \ | |
| libicu76 \ | |
| libssl3t64 && \ | |
| update-ca-certificates && \ | |
| rm -rf /var/lib/apt/lists/* | |
| # ============================================================ | |
| # Create non-root build user | |
| # ============================================================ | |
| RUN useradd -m user && \ | |
| mkdir -p \ | |
| /home/user/code \ | |
| /home/user/out/app && \ | |
| chown -R user:user /home/user | |
| USER user | |
| WORKDIR /home/user | |
| # ============================================================ | |
| # Install .NET 10 SDK | |
| # ============================================================ | |
| RUN wget -q \ | |
| https://dot.net/v1/dotnet-install.sh \ | |
| -O dotnet-install.sh && \ | |
| chmod +x dotnet-install.sh && \ | |
| ./dotnet-install.sh \ | |
| --channel 10.0 && \ | |
| rm dotnet-install.sh | |
| ENV DOTNET_ROOT=/home/user/.dotnet | |
| ENV PATH="${PATH}:${DOTNET_ROOT}:${DOTNET_ROOT}/tools" | |
| # ============================================================ | |
| # Clone application repositories | |
| # ============================================================ | |
| WORKDIR /home/user/code | |
| RUN --mount=type=secret,id=GITHUB_TOKEN,mode=0444,required=true \ | |
| git clone --depth 1 \ | |
| https://x-access-token:$(cat /run/secrets/GITHUB_TOKEN)@github.com/Mungert69/NetworkMonitorLib.git \ | |
| /home/user/code/NetworkMonitorLib && \ | |
| git clone --depth 1 \ | |
| https://x-access-token:$(cat /run/secrets/GITHUB_TOKEN)@github.com/Mungert69/NetworkMonitorLLM.git \ | |
| /home/user/code/NetworkMonitorLLM | |
| # ============================================================ | |
| # Restore and publish .NET application | |
| # ============================================================ | |
| WORKDIR /home/user/code/NetworkMonitorLLM | |
| RUN dotnet restore NetworkMonitorLLM.csproj | |
| RUN dotnet publish NetworkMonitorLLM.csproj \ | |
| -c Release \ | |
| --no-restore \ | |
| --no-self-contained \ | |
| -o /home/user/out/app | |
| # ============================================================ | |
| # Stage 3: Runtime image | |
| # ============================================================ | |
| FROM debian:13 AS runtime | |
| ENV DEBIAN_FRONTEND=noninteractive | |
| ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 | |
| ENV DOTNET_NOLOGO=1 | |
| # ============================================================ | |
| # Runtime dependencies | |
| # | |
| # Original runtime utilities retained: | |
| # curl | |
| # ca-certificates | |
| # wget | |
| # vim | |
| # libicu76 | |
| # expect | |
| # | |
| # Explicit compiler/runtime libraries added because the build | |
| # toolchain no longer exists in this multi-stage image: | |
| # | |
| # libstdc++6 | |
| # libgcc-s1 | |
| # libgfortran5 | |
| # libgomp1 | |
| # libquadmath0 | |
| # libatomic1 | |
| # ============================================================ | |
| RUN apt-get update && \ | |
| apt-get install -y --no-install-recommends \ | |
| ca-certificates \ | |
| wget \ | |
| curl \ | |
| vim \ | |
| libicu76 \ | |
| libssl3t64 \ | |
| libgssapi-krb5-2 \ | |
| libstdc++6 \ | |
| libgcc-s1 \ | |
| libgfortran5 \ | |
| libgomp1 \ | |
| libquadmath0 \ | |
| libatomic1 \ | |
| zlib1g \ | |
| expect \ | |
| tzdata && \ | |
| update-ca-certificates && \ | |
| rm -rf /var/lib/apt/lists/* | |
| # ============================================================ | |
| # Install CPU-optimized OpenBLAS | |
| # ============================================================ | |
| COPY --from=native-build \ | |
| /out/openblas/ \ | |
| /usr/local/lib/ | |
| RUN ldconfig | |
| # ============================================================ | |
| # Verify OpenBLAS itself was copied correctly | |
| # | |
| # `test -e` follows the libopenblas.so symlink, so this fails | |
| # if the CPU-specific target library was not copied. | |
| # ============================================================ | |
| RUN test -e /usr/local/lib/libopenblas.so && \ | |
| echo "OpenBLAS library verified:" && \ | |
| ls -lh /usr/local/lib/libopenblas* | |
| # ============================================================ | |
| # Create runtime user/directories | |
| # ============================================================ | |
| RUN useradd -m user && \ | |
| mkdir -p \ | |
| /home/user/code/app/wwwroot \ | |
| /home/user/code/models/llama.cpp \ | |
| /home/user/code/models && \ | |
| chown -R user:user /home/user | |
| USER user | |
| WORKDIR /home/user | |
| # ============================================================ | |
| # Install ONLY ASP.NET Core runtime | |
| # ============================================================ | |
| RUN wget -q \ | |
| https://dot.net/v1/dotnet-install.sh \ | |
| -O dotnet-install.sh && \ | |
| chmod +x dotnet-install.sh && \ | |
| ./dotnet-install.sh \ | |
| --channel 10.0 \ | |
| --runtime aspnetcore && \ | |
| rm dotnet-install.sh | |
| ENV DOTNET_ROOT=/home/user/.dotnet | |
| ENV PATH="${PATH}:${DOTNET_ROOT}:${DOTNET_ROOT}/tools" | |
| # ============================================================ | |
| # Runtime dynamic library locations | |
| # | |
| # llama.cpp puts its shared libraries beside its executables. | |
| # Source-built OpenBLAS is in /usr/local/lib. | |
| # ============================================================ | |
| ENV LD_LIBRARY_PATH="/home/user/code/models/llama.cpp:/usr/local/lib" | |
| # ============================================================ | |
| # Copy compiled llama.cpp binaries/libraries | |
| # ============================================================ | |
| COPY --from=native-build --chown=user:user \ | |
| /out/llama/ \ | |
| /home/user/code/models/llama.cpp/ | |
| # ============================================================ | |
| # Verify EVERY llama/OpenBLAS dynamic dependency | |
| # | |
| # This catches missing shared libraries DURING THE DOCKER BUILD | |
| # rather than discovering them after the Space starts. | |
| # ============================================================ | |
| RUN set -eu; \ | |
| echo "Checking llama.cpp runtime dependencies..."; \ | |
| missing=0; \ | |
| for f in /home/user/code/models/llama.cpp/*; do \ | |
| [ -f "$f" ] || continue; \ | |
| deps="$(ldd "$f" 2>/dev/null || true)"; \ | |
| if printf '%s\n' "$deps" | grep -q "not found"; then \ | |
| echo "========================================"; \ | |
| echo "MISSING DEPENDENCY IN: $f"; \ | |
| printf '%s\n' "$deps"; \ | |
| echo "========================================"; \ | |
| missing=1; \ | |
| fi; \ | |
| done; \ | |
| for f in /usr/local/lib/libopenblas*; do \ | |
| [ -f "$f" ] || continue; \ | |
| deps="$(ldd "$f" 2>/dev/null || true)"; \ | |
| if printf '%s\n' "$deps" | grep -q "not found"; then \ | |
| echo "========================================"; \ | |
| echo "MISSING DEPENDENCY IN: $f"; \ | |
| printf '%s\n' "$deps"; \ | |
| echo "========================================"; \ | |
| missing=1; \ | |
| fi; \ | |
| done; \ | |
| if [ "$missing" -ne 0 ]; then \ | |
| echo "One or more runtime libraries are missing."; \ | |
| exit 1; \ | |
| fi; \ | |
| echo "All llama.cpp/OpenBLAS dynamic dependencies resolved." | |
| # ============================================================ | |
| # Copy published .NET application | |
| # ============================================================ | |
| COPY --from=dotnet-build --chown=user:user \ | |
| /home/user/out/app/ \ | |
| /home/user/code/app/ | |
| # ============================================================ | |
| # Application configuration | |
| # ============================================================ | |
| COPY --chown=user:user \ | |
| appsettings.json \ | |
| /home/user/code/app/appsettings.json | |
| COPY --chown=user:user \ | |
| index.html \ | |
| /home/user/code/app/wwwroot/index.html | |
| # ============================================================ | |
| # Model configuration | |
| # | |
| # Model is deliberately NOT put into the Docker image. | |
| # It is downloaded after the Space starts so the 6.5GB GGUF | |
| # does not have to be exported/compressed/pushed as an image | |
| # layer. | |
| # ============================================================ | |
| ENV MODEL_DIR=/home/user/code/models | |
| ENV MODEL_FILE=Mellum2-12B-A2.5B-Instruct-mxfp4_moe.gguf | |
| ENV MODEL_URL=https://huggingface.co/Mungert/Mellum2-12B-A2.5B-Instruct-GGUF/resolve/main/Mellum2-12B-A2.5B-Instruct-mxfp4_moe.gguf | |
| # ============================================================ | |
| # Create startup script | |
| # ============================================================ | |
| RUN cat > /home/user/start.sh <<'EOF' | |
| #!/bin/sh | |
| set -e | |
| MODEL_PATH="${MODEL_DIR}/${MODEL_FILE}" | |
| TEMP_PATH="${MODEL_PATH}.download" | |
| echo "==========================================" | |
| echo "NetworkMonitorLLM startup" | |
| echo "==========================================" | |
| echo "Model:" | |
| echo "${MODEL_PATH}" | |
| echo | |
| echo "OpenBLAS:" | |
| ls -lh /usr/local/lib/libopenblas* || true | |
| echo | |
| echo "llama.cpp:" | |
| ls -lh /home/user/code/models/llama.cpp/ | head -20 || true | |
| # ============================================================ | |
| # Download model at runtime | |
| # | |
| # Quiet mode prevents the 6.5GB download from exhausting the | |
| # Hugging Face web log display. | |
| # ============================================================ | |
| if [ ! -s "${MODEL_PATH}" ]; then | |
| echo | |
| echo "Model not present." | |
| echo "Downloading model..." | |
| rm -f "${TEMP_PATH}" | |
| wget -q \ | |
| --tries=5 \ | |
| --timeout=60 \ | |
| -O "${TEMP_PATH}" \ | |
| "${MODEL_URL}" | |
| echo "Download completed." | |
| mv "${TEMP_PATH}" "${MODEL_PATH}" | |
| else | |
| echo | |
| echo "Model already exists." | |
| fi | |
| echo | |
| echo "Model size:" | |
| ls -lh "${MODEL_PATH}" | |
| # ============================================================ | |
| # Start .NET application | |
| # ============================================================ | |
| echo | |
| echo "Starting NetworkMonitorLLM..." | |
| cd /home/user/code/app | |
| exec dotnet NetworkMonitorLLM.dll \ | |
| --urls http://0.0.0.0:7860 | |
| EOF | |
| RUN chmod +x /home/user/start.sh | |
| # ============================================================ | |
| # Hugging Face Space | |
| # ============================================================ | |
| WORKDIR /home/user/code/app | |
| EXPOSE 7860 | |
| CMD ["/home/user/start.sh"] |