mirror of
https://github.com/mudler/LocalAI.git
synced 2026-09-13 22:57:36 -04:00
* test: make coverage failures observable Keep per-root logs, reject concurrent coverage runs, and avoid relying on /bin/sleep in the worker timeout test. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * test: parallelize coverage without remote fixtures Assisted-by: Codex:gpt-5 [apply_patch] [exec_command] Signed-off-by: Richard Palethorpe <io@richiejp.com> * test: add offline resource infrastructure Introduce versioned resource manifests, a checksum-verified CAS preparer, offline test wrappers, and a guarded network transport. Replace live Hugging Face, GitHub, and OCI cases with deterministic fixtures and inject fixture metadata into importer discovery. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * test: enforce offline resource replay Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * test: harden offline resource refresh Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * test: expose slow coverage waits Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * test: eliminate avoidable wall-clock waits Inject a clock into Hugging Face retry handling, reuse a process-scoped PostgreSQL container with per-spec schemas in the nodes suite, and poll local import jobs promptly. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * test: remove repeated fixture startup waits Share PostgreSQL fixtures across parallel endpoint and agent suite workers, and make the worker Free deadline injectable so the wedged-backend test does not spend five seconds on wall-clock time. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * test: fix offline resource CI portability Normalize Docker archive metadata before content addressing, derive archive checksums during explicit refreshes, make network lint portable to macOS, and prepare distributed images before running their offline suite. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * ci: cache Go modules before offline tests Warm the complete module graph before the Linux and macOS test jobs enter offline replay mode, so tool dependencies such as Ginkgo are not fetched through the guarded proxy. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * test: drop the static network lint in favour of real isolation The offline test suite already prevents tests from reaching the network twice over: run-test-linux-offline.sh puts the test process in a cgroup and REJECTs egress outside the private ranges, and HardenedTransport installs testnetwork.LocalGuard to refuse dials that resolve to a public address. Both fail the test with a precise error at the moment of the dial. test-network-lint.sh added neither. Its diff stage defaulted to a HEAD base, so on a clean checkout it compared the tree against itself and inspected nothing; the branch's own commits were never examined. It only produced output when an earlier job step dirtied the tree, and then it matched a bare https?:// against whatever changed. make react-ui runs npm install rather than npm ci, so CI rewrote core/http/react-ui/package-lock.json and the lint reported an npm registry URL as forbidden test network access: + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.25.tgz", Its fingerprint stage was self-defeating in a quieter way: hashing the whole tree's network-mechanism inventory meant every rebase onto a master that touched any _test.go needed a manual baseline bump, so the check mostly caught its own staleness. Remove the script, its make target and the two prerequisite edges, along with the test-network: fixture markers that existed only to suppress it. The isolation itself is untouched. Assisted-by: Claude:claude-opus-5 [go vet] Signed-off-by: Richard Palethorpe <io@richiejp.com> * ci: keep hidden files in the offline test bundle artifact Cherry-picked from15a37b0acon the remote branch. The offline bundle lives under .cache/, which actions/upload-artifact skips by default, so the Linux job packed an artifact missing the very file the next step restores. The other half of15a37b0acmoved test-network-lint out of the `test` and `test-coverage` prerequisite lists into a recipe line, so parallel make could not fingerprint the tree while generated fixtures were still changing. That is dropped: the preceding commit removes the lint entirely, and the race it worked around is one more reason a whole-tree fingerprint was the wrong mechanism. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * refactor: share bounded exponential backoff Use overflow-safe saturating arithmetic for retry delays across model import polling, downloads, registration, node operations, and model loading. Keep model import status checks responsive initially while capping their interval at 500ms. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * ci: mirror Jetson Python wheels Keep the CUDA aarch64 wheel subset in GHCR and serve it as a local PEP 503 index during L4T backend builds, preserving last-known-good packages through upstream outages. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * docs(agents): index the Jetson wheels mirror Mention the GHCR-hosted L4T wheel mirror in the CI caching guide summary so maintainers can find its outage and cache documentation. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * ci: add defensive build network proxy Record build destinations and byte counts, retry observable idempotent HTTP downloads, and isolate explorer database tests that race under coverage. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * fix(kokoros): implement updated backend trait Return unimplemented for image upscaling, matching the backend's other unsupported modalities after the protobuf API update. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * fix(ci): clear recovered proxy errors Do not mark a request failed when a later safe retry succeeds. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * ci: require HTTPS build interception Inject a short-lived proxy CA into BuildKit and Dockerfile RUN steps, reject plain HTTP and opaque tunnels, and retain method/status/byte telemetry for verified HTTPS traffic. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * fix(ci): preserve system trust in unproxied builds Mount the generated interception CA at a dedicated secret path and add it to the trust bundle only in proxy-aware dependency stages. This prevents optional secret mounts from masking the system CA bundle in ordinary backend test builds. Install the requested Go toolchain before starting the proxy and satisfy cleanup error checks found by CI lint. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * fix(ci): persist build proxy trust Install the generated proxy CA through the system-managed local certificate directory so ca-certificates upgrades retain it. Avoid turning canceled matrix jobs into proxy cleanup failures. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * fix(ci): trust proxy in nested build scripts Install the build proxy CA before nested source fetches, route the DS4 package setup through the HTTPS mirror helper, and avoid repeated OCI setup in gallery behavior tests. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * fix(ci): use HTTPS apt sources for Bonsai Rewrite ARM64 package sources before installing GCC and check gallery fixture cleanup errors so the optimized tests satisfy errcheck. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * fix(privacy-filter): trust build proxy CA Install the mounted build proxy certificate before privacy-filter's make target fetches its HTTPS sources, for both source and prebuilt builder paths.\n\nAssisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * test: fail on hidden offline egress Count cgroup-scoped firewall rejects and fail the offline test harness with bounded aggregate diagnostics. Inject the gen-audio GGUF probe so fixture-backed importer tests do not attempt real network access. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> * fix(ci): preserve system CA trust Build a combined runner certificate bundle instead of replacing public roots with the generated proxy CA. Centralize additive container installation in the shared proxy CA helper. Assisted-by: Codex:gpt-5 Signed-off-by: Richard Palethorpe <io@richiejp.com> --------- Signed-off-by: Richard Palethorpe <io@richiejp.com> Co-authored-by: localai-org-maint-bot <306269227+localai-org-maint-bot@users.noreply.github.com>
453 lines
21 KiB
Docker
453 lines
21 KiB
Docker
ARG BASE_IMAGE=ubuntu:24.04
|
|
ARG INTEL_BASE_IMAGE=${BASE_IMAGE}
|
|
ARG UBUNTU_CODENAME=noble
|
|
# Optional alternate Ubuntu apt mirror(s). Empty = use upstream.
|
|
# See .docker/apt-mirror.sh for accepted values.
|
|
ARG APT_MIRROR=""
|
|
ARG APT_PORTS_MIRROR=""
|
|
|
|
FROM alpine:3.22 AS ca-certificates
|
|
|
|
FROM ${BASE_IMAGE} AS requirements
|
|
COPY --from=ca-certificates /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
|
|
|
|
ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt \
|
|
CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt \
|
|
REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt \
|
|
PIP_CERT=/etc/ssl/certs/ca-certificates.crt
|
|
|
|
ARG APT_MIRROR
|
|
ARG APT_PORTS_MIRROR
|
|
ENV DEBIAN_FRONTEND=noninteractive
|
|
|
|
# hwdata ships /usr/share/hwdata/pci.ids. Without it, the ghw library we use
|
|
# for hardware detection cannot resolve PCI vendor IDs and fails to enumerate
|
|
# GPUs at all, so the image reports "No GPU detected" (see issue #10941).
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 --mount=type=bind,source=.docker/install-build-proxy-ca.sh,target=/usr/local/sbin/install-build-proxy-ca --mount=type=bind,source=.docker/apt-mirror.sh,target=/usr/local/sbin/apt-mirror \
|
|
APT_MIRROR="${APT_MIRROR}" APT_PORTS_MIRROR="${APT_PORTS_MIRROR}" sh /usr/local/sbin/apt-mirror && \
|
|
apt-get update && \
|
|
apt-get install -y --no-install-recommends \
|
|
ca-certificates curl wget espeak-ng libgomp1 \
|
|
ffmpeg libopenblas0 libopenblas-dev libopus0 sox \
|
|
hwdata && \
|
|
apt-get clean && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
# The requirements-drivers target is for BUILD_TYPE specific items. If you need to install something specific to CUDA, or specific to ROCM, it goes here.
|
|
FROM requirements AS requirements-drivers
|
|
|
|
ARG BUILD_TYPE
|
|
ARG CUDA_MAJOR_VERSION=12
|
|
ARG CUDA_MINOR_VERSION=0
|
|
ARG SKIP_DRIVERS=false
|
|
ARG TARGETARCH
|
|
ARG TARGETVARIANT
|
|
ENV BUILD_TYPE=${BUILD_TYPE}
|
|
ARG UBUNTU_VERSION=2404
|
|
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 mkdir -p /run/localai
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 echo "default" > /run/localai/capability
|
|
|
|
# Vulkan requirements
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 <<EOT bash
|
|
if [ "${BUILD_TYPE}" = "vulkan" ] && [ "${SKIP_DRIVERS}" = "false" ]; then
|
|
apt-get update && \
|
|
apt-get install -y --no-install-recommends \
|
|
software-properties-common pciutils wget gpg-agent && \
|
|
apt-get install -y libglm-dev cmake libxcb-dri3-0 libxcb-present0 libpciaccess0 \
|
|
libpng-dev libxcb-keysyms1-dev libxcb-dri3-dev libx11-dev g++ gcc \
|
|
libwayland-dev libxrandr-dev libxcb-randr0-dev libxcb-ewmh-dev \
|
|
git python-is-python3 bison libx11-xcb-dev liblz4-dev libzstd-dev \
|
|
ocaml-core ninja-build pkg-config libxml2-dev wayland-protocols python3-jsonschema \
|
|
clang-format qtbase5-dev qt6-base-dev libxcb-glx0-dev sudo xz-utils mesa-vulkan-drivers
|
|
if [ "amd64" = "$TARGETARCH" ]; then
|
|
wget "https://sdk.lunarg.com/sdk/download/1.4.335.0/linux/vulkansdk-linux-x86_64-1.4.335.0.tar.xz" && \
|
|
tar -xf vulkansdk-linux-x86_64-1.4.335.0.tar.xz && \
|
|
rm vulkansdk-linux-x86_64-1.4.335.0.tar.xz && \
|
|
mkdir -p /opt/vulkan-sdk && \
|
|
mv 1.4.335.0 /opt/vulkan-sdk/ && \
|
|
cd /opt/vulkan-sdk/1.4.335.0 && \
|
|
./vulkansdk --no-deps --maxjobs \
|
|
vulkan-loader \
|
|
vulkan-validationlayers \
|
|
vulkan-extensionlayer \
|
|
vulkan-tools \
|
|
shaderc && \
|
|
cp -rfv /opt/vulkan-sdk/1.4.335.0/x86_64/bin/* /usr/bin/ && \
|
|
cp -rfv /opt/vulkan-sdk/1.4.335.0/x86_64/lib/* /usr/lib/x86_64-linux-gnu/ && \
|
|
cp -rfv /opt/vulkan-sdk/1.4.335.0/x86_64/include/* /usr/include/ && \
|
|
cp -rfv /opt/vulkan-sdk/1.4.335.0/x86_64/share/* /usr/share/ && \
|
|
rm -rf /opt/vulkan-sdk
|
|
fi
|
|
if [ "arm64" = "$TARGETARCH" ]; then
|
|
mkdir vulkan && cd vulkan && \
|
|
curl -L -o vulkan-sdk.tar.xz https://github.com/mudler/vulkan-sdk-arm/releases/download/1.4.335.0/vulkansdk-ubuntu-24.04-arm-1.4.335.0.tar.xz && \
|
|
tar -xvf vulkan-sdk.tar.xz && \
|
|
rm vulkan-sdk.tar.xz && \
|
|
cd 1.4.335.0 && \
|
|
cp -rfv aarch64/bin/* /usr/bin/ && \
|
|
cp -rfv aarch64/lib/* /usr/lib/aarch64-linux-gnu/ && \
|
|
cp -rfv aarch64/include/* /usr/include/ && \
|
|
cp -rfv aarch64/share/* /usr/share/ && \
|
|
cd ../.. && \
|
|
rm -rf vulkan
|
|
fi
|
|
ldconfig && \
|
|
apt-get clean && \
|
|
rm -rf /var/lib/apt/lists/* && \
|
|
echo "vulkan" > /run/localai/capability
|
|
fi
|
|
EOT
|
|
|
|
# CuBLAS requirements
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 <<EOT bash
|
|
if ( [ "${BUILD_TYPE}" = "cublas" ] || [ "${BUILD_TYPE}" = "l4t" ] ) && [ "${SKIP_DRIVERS}" = "false" ]; then
|
|
apt-get update && \
|
|
apt-get install -y --no-install-recommends \
|
|
software-properties-common pciutils
|
|
if [ "amd64" = "$TARGETARCH" ]; then
|
|
curl -O https://developer.download.nvidia.com/compute/cuda/repos/ubuntu${UBUNTU_VERSION}/x86_64/cuda-keyring_1.1-1_all.deb
|
|
fi
|
|
if [ "arm64" = "$TARGETARCH" ]; then
|
|
if [ "${CUDA_MAJOR_VERSION}" = "13" ]; then
|
|
curl -O https://developer.download.nvidia.com/compute/cuda/repos/ubuntu${UBUNTU_VERSION}/sbsa/cuda-keyring_1.1-1_all.deb
|
|
else
|
|
curl -O https://developer.download.nvidia.com/compute/cuda/repos/ubuntu${UBUNTU_VERSION}/arm64/cuda-keyring_1.1-1_all.deb
|
|
fi
|
|
fi
|
|
dpkg -i cuda-keyring_1.1-1_all.deb && \
|
|
rm -f cuda-keyring_1.1-1_all.deb && \
|
|
apt-get update && \
|
|
apt-get install -y --no-install-recommends \
|
|
cuda-nvcc-${CUDA_MAJOR_VERSION}-${CUDA_MINOR_VERSION} \
|
|
cuda-nvrtc-dev-${CUDA_MAJOR_VERSION}-${CUDA_MINOR_VERSION} \
|
|
libcufft-dev-${CUDA_MAJOR_VERSION}-${CUDA_MINOR_VERSION} \
|
|
libcurand-dev-${CUDA_MAJOR_VERSION}-${CUDA_MINOR_VERSION} \
|
|
libcublas-dev-${CUDA_MAJOR_VERSION}-${CUDA_MINOR_VERSION} \
|
|
libcusparse-dev-${CUDA_MAJOR_VERSION}-${CUDA_MINOR_VERSION} \
|
|
libcusolver-dev-${CUDA_MAJOR_VERSION}-${CUDA_MINOR_VERSION}
|
|
if [ "${CUDA_MAJOR_VERSION}" = "13" ] && [ "arm64" = "$TARGETARCH" ]; then
|
|
apt-get install -y --no-install-recommends \
|
|
libcufile-${CUDA_MAJOR_VERSION}-${CUDA_MINOR_VERSION} libcudnn9-cuda-${CUDA_MAJOR_VERSION} cuda-cupti-${CUDA_MAJOR_VERSION}-${CUDA_MINOR_VERSION} libnvjitlink-${CUDA_MAJOR_VERSION}-${CUDA_MINOR_VERSION}
|
|
fi
|
|
apt-get clean && \
|
|
rm -rf /var/lib/apt/lists/* && \
|
|
echo "nvidia-cuda-${CUDA_MAJOR_VERSION}" > /run/localai/capability
|
|
fi
|
|
EOT
|
|
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 <<EOT bash
|
|
if [ "${BUILD_TYPE}" = "cublas" ] && [ "${TARGETARCH}" = "arm64" ]; then
|
|
echo "nvidia-l4t-cuda-${CUDA_MAJOR_VERSION}" > /run/localai/capability
|
|
fi
|
|
EOT
|
|
|
|
# https://github.com/NVIDIA/Isaac-GR00T/issues/343
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 <<EOT bash
|
|
if [ "${BUILD_TYPE}" = "cublas" ] && [ "${TARGETARCH}" = "arm64" ]; then
|
|
wget https://developer.download.nvidia.com/compute/cudss/0.6.0/local_installers/cudss-local-tegra-repo-ubuntu${UBUNTU_VERSION}-0.6.0_0.6.0-1_arm64.deb && \
|
|
dpkg -i cudss-local-tegra-repo-ubuntu${UBUNTU_VERSION}-0.6.0_0.6.0-1_arm64.deb && \
|
|
cp /var/cudss-local-tegra-repo-ubuntu${UBUNTU_VERSION}-0.6.0/cudss-*-keyring.gpg /usr/share/keyrings/ && \
|
|
apt-get update && apt-get -y install cudss cudss-cuda-${CUDA_MAJOR_VERSION} && \
|
|
wget https://developer.download.nvidia.com/compute/nvpl/25.5/local_installers/nvpl-local-repo-ubuntu${UBUNTU_VERSION}-25.5_1.0-1_arm64.deb && \
|
|
dpkg -i nvpl-local-repo-ubuntu${UBUNTU_VERSION}-25.5_1.0-1_arm64.deb && \
|
|
cp /var/nvpl-local-repo-ubuntu${UBUNTU_VERSION}-25.5/nvpl-*-keyring.gpg /usr/share/keyrings/ && \
|
|
apt-get update && apt-get install -y nvpl
|
|
fi
|
|
EOT
|
|
|
|
# If we are building with clblas support, we need the libraries for the builds
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 if [ "${BUILD_TYPE}" = "clblas" ] && [ "${SKIP_DRIVERS}" = "false" ]; then \
|
|
apt-get update && \
|
|
apt-get install -y --no-install-recommends \
|
|
libclblast-dev && \
|
|
apt-get clean && \
|
|
rm -rf /var/lib/apt/lists/* \
|
|
; fi
|
|
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 if [ "${BUILD_TYPE}" = "hipblas" ] && [ "${SKIP_DRIVERS}" = "false" ]; then \
|
|
apt-get update && \
|
|
apt-get install -y --no-install-recommends \
|
|
hipblas-dev \
|
|
hipblaslt-dev \
|
|
rocblas-dev && \
|
|
apt-get clean && \
|
|
rm -rf /var/lib/apt/lists/* && \
|
|
echo "amd" > /run/localai/capability && \
|
|
# I have no idea why, but the ROCM lib packages don't trigger ldconfig after they install, which results in local-ai and others not being able
|
|
# to locate the libraries. We run ldconfig ourselves to work around this packaging deficiency
|
|
ldconfig \
|
|
; fi
|
|
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 if [ "${BUILD_TYPE}" = "hipblas" ]; then \
|
|
ln -s /opt/rocm-**/lib/llvm/lib/libomp.so /usr/lib/libomp.so \
|
|
; fi
|
|
|
|
# ROCm's bundled libdrm_amdgpu is built with a hardcoded fallback lookup path
|
|
# for the ASIC ID table (/opt/amdgpu/share/libdrm/amdgpu.ids), which only exists
|
|
# if AMD's full amdgpu graphics/DKMS stack is installed. This compute-only image
|
|
# doesn't have it, so hipblas/rocBLAS log "No such file or directory" on every
|
|
# model load and can fail to identify the GPU. Point it at the equivalent file
|
|
# Ubuntu's libdrm-common package already ships.
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 if [ "${BUILD_TYPE}" = "hipblas" ] && [ -f /usr/share/libdrm/amdgpu.ids ] && [ ! -e /opt/amdgpu/share/libdrm/amdgpu.ids ]; then \
|
|
mkdir -p /opt/amdgpu/share/libdrm && \
|
|
ln -s /usr/share/libdrm/amdgpu.ids /opt/amdgpu/share/libdrm/amdgpu.ids \
|
|
; fi
|
|
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 expr "${BUILD_TYPE}" = intel && echo "intel" > /run/localai/capability || echo "not intel"
|
|
|
|
# Cuda
|
|
ENV PATH=/usr/local/cuda/bin:${PATH}
|
|
|
|
# HipBLAS requirements
|
|
ENV PATH=/opt/rocm/bin:${PATH}
|
|
|
|
###################################
|
|
###################################
|
|
|
|
# The requirements-core target is common to all images. It should not be placed in requirements-core unless every single build will use it.
|
|
FROM requirements-drivers AS build-requirements
|
|
|
|
ARG GO_VERSION=1.26.0
|
|
ARG CMAKE_VERSION=3.31.10
|
|
ARG CMAKE_FROM_SOURCE=false
|
|
ARG TARGETARCH
|
|
ARG TARGETVARIANT
|
|
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 apt-get update && \
|
|
apt-get install -y --no-install-recommends \
|
|
build-essential \
|
|
ccache \
|
|
ca-certificates espeak-ng \
|
|
curl libssl-dev \
|
|
git \
|
|
git-lfs \
|
|
libopus-dev pkg-config \
|
|
unzip upx-ucl python3 python-is-python3 && \
|
|
apt-get clean && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
# Install CMake (the version in 22.04 is too old)
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 <<EOT bash
|
|
if [ "${CMAKE_FROM_SOURCE}" = "true" ]; then
|
|
curl -L -s https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}.tar.gz -o cmake.tar.gz && tar xvf cmake.tar.gz && cd cmake-${CMAKE_VERSION} && ./configure && make && make install
|
|
else
|
|
apt-get update && \
|
|
apt-get install -y \
|
|
cmake && \
|
|
apt-get clean && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
fi
|
|
EOT
|
|
|
|
# Install Go
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 curl -L -s https://go.dev/dl/go${GO_VERSION}.linux-${TARGETARCH}.tar.gz | tar -C /usr/local -xz
|
|
ENV PATH=$PATH:/root/go/bin:/usr/local/go/bin
|
|
|
|
# Install grpc compilers
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.34.2 && \
|
|
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@1958fcbe2ca8bd93af633f11e97d44e567e945af
|
|
|
|
COPY --chmod=644 custom-ca-certs/* /usr/local/share/ca-certificates/
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 update-ca-certificates
|
|
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 test -n "$TARGETARCH" \
|
|
|| (echo 'warn: missing $TARGETARCH, either set this `ARG` manually, or run using `docker buildkit`')
|
|
|
|
# Use the variables in subsequent instructions
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 echo "Target Architecture: $TARGETARCH"
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 echo "Target Variant: $TARGETVARIANT"
|
|
|
|
|
|
|
|
|
|
WORKDIR /build
|
|
|
|
|
|
###################################
|
|
###################################
|
|
|
|
# Temporary workaround for Intel's repository to work correctly
|
|
# https://community.intel.com/t5/Intel-oneAPI-Math-Kernel-Library/APT-Repository-not-working-signatures-invalid/m-p/1599436/highlight/true#M36143
|
|
# This is a temporary workaround until Intel fixes their repository
|
|
FROM ${INTEL_BASE_IMAGE} AS intel
|
|
COPY --from=ca-certificates /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
|
|
ARG UBUNTU_CODENAME=noble
|
|
ARG APT_MIRROR
|
|
ARG APT_PORTS_MIRROR
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 wget -qO - https://repositories.intel.com/gpu/intel-graphics.key | \
|
|
gpg --yes --dearmor --output /usr/share/keyrings/intel-graphics.gpg
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 echo "deb [arch=amd64 signed-by=/usr/share/keyrings/intel-graphics.gpg] https://repositories.intel.com/gpu/ubuntu ${UBUNTU_CODENAME}/lts/2350 unified" > /etc/apt/sources.list.d/intel-graphics.list
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 --mount=type=bind,source=.docker/install-build-proxy-ca.sh,target=/usr/local/sbin/install-build-proxy-ca --mount=type=bind,source=.docker/apt-mirror.sh,target=/usr/local/sbin/apt-mirror \
|
|
APT_MIRROR="${APT_MIRROR}" APT_PORTS_MIRROR="${APT_PORTS_MIRROR}" sh /usr/local/sbin/apt-mirror && \
|
|
apt-get update && \
|
|
apt-get install -y --no-install-recommends \
|
|
intel-oneapi-runtime-libs && \
|
|
apt-get clean && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
###################################
|
|
###################################
|
|
|
|
# The builder-base target has the arguments, variables, and copies shared between full builder images and the uncompiled devcontainer
|
|
|
|
FROM build-requirements AS builder-base
|
|
|
|
ARG GO_TAGS="auth"
|
|
ARG GRPC_BACKENDS
|
|
ARG MAKEFLAGS
|
|
ARG LD_FLAGS="-s -w"
|
|
ARG TARGETARCH
|
|
ARG TARGETVARIANT
|
|
ENV GRPC_BACKENDS=${GRPC_BACKENDS}
|
|
ENV GO_TAGS=${GO_TAGS}
|
|
ENV MAKEFLAGS=${MAKEFLAGS}
|
|
ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility
|
|
ENV NVIDIA_REQUIRE_CUDA="cuda>=${CUDA_MAJOR_VERSION}.0"
|
|
ENV NVIDIA_VISIBLE_DEVICES=all
|
|
ENV LD_FLAGS=${LD_FLAGS}
|
|
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 echo "GO_TAGS: $GO_TAGS" && echo "TARGETARCH: $TARGETARCH"
|
|
|
|
WORKDIR /build
|
|
|
|
|
|
# We need protoc installed, and the version in 22.04 is too old.
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 <<EOT bash
|
|
if [ "amd64" = "$TARGETARCH" ]; then
|
|
curl -L -s https://github.com/protocolbuffers/protobuf/releases/download/v27.1/protoc-27.1-linux-x86_64.zip -o protoc.zip && \
|
|
unzip -j -d /usr/local/bin protoc.zip bin/protoc && \
|
|
rm protoc.zip
|
|
fi
|
|
if [ "arm64" = "$TARGETARCH" ]; then
|
|
curl -L -s https://github.com/protocolbuffers/protobuf/releases/download/v27.1/protoc-27.1-linux-aarch_64.zip -o protoc.zip && \
|
|
unzip -j -d /usr/local/bin protoc.zip bin/protoc && \
|
|
rm protoc.zip
|
|
fi
|
|
EOT
|
|
|
|
###################################
|
|
###################################
|
|
|
|
# Build React UI
|
|
FROM node:26-slim AS react-ui-builder
|
|
|
|
ENV NODE_EXTRA_CA_CERTS=/run/secrets/build_proxy_ca
|
|
WORKDIR /app
|
|
COPY core/http/react-ui/package*.json ./
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 npm install
|
|
COPY core/http/react-ui/ ./
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 npm run build
|
|
|
|
###################################
|
|
###################################
|
|
|
|
# Compile backends first in a separate stage
|
|
FROM builder-base AS builder-backends
|
|
ARG TARGETARCH
|
|
ARG TARGETVARIANT
|
|
|
|
WORKDIR /build
|
|
|
|
COPY ./Makefile .
|
|
COPY ./backend ./backend
|
|
COPY ./go.mod .
|
|
COPY ./go.sum .
|
|
COPY ./.git ./.git
|
|
|
|
# Some of the Go backends use libs from the main src, we could further optimize the caching by building the CPP backends before here
|
|
COPY ./pkg/grpc ./pkg/grpc
|
|
COPY ./pkg/utils ./pkg/utils
|
|
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 ls -l ./
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 make protogen-go
|
|
|
|
# The builder target compiles LocalAI. This target is not the target that will be uploaded to the registry.
|
|
# Adjustments to the build process should likely be made here.
|
|
FROM builder-backends AS builder
|
|
|
|
WORKDIR /build
|
|
|
|
COPY . .
|
|
|
|
# Copy pre-built React UI
|
|
COPY --from=react-ui-builder /app/dist ./core/http/react-ui/dist
|
|
|
|
## Build the binary
|
|
## If we're on arm64 AND using cublas/hipblas, skip some of the llama-compat backends to save space
|
|
## Otherwise just run the normal build
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 make build
|
|
|
|
###################################
|
|
###################################
|
|
|
|
# The devcontainer target is not used on CI. It is a target for developers to use locally -
|
|
# rather than copying files it mounts them locally and leaves building to the developer
|
|
|
|
FROM builder-base AS devcontainer
|
|
|
|
COPY .devcontainer-scripts /.devcontainer-scripts
|
|
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 apt-get update && \
|
|
apt-get install -y --no-install-recommends \
|
|
ssh less
|
|
# For the devcontainer, leave apt functional in case additional devtools are needed at runtime.
|
|
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 go install github.com/go-delve/delve/cmd/dlv@latest
|
|
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 go install github.com/mikefarah/yq/v4@latest
|
|
|
|
###################################
|
|
###################################
|
|
|
|
# This is the final target. The result of this target will be the image uploaded to the registry.
|
|
# If you cannot find a more suitable place for an addition, this layer is a suitable place for it.
|
|
FROM requirements-drivers
|
|
|
|
# Optional override for the HEALTHCHECK target. Left empty so healthcheck.sh
|
|
# derives the endpoint from the mode the container is actually running — the
|
|
# same image runs `local-ai run` (HTTP on 8080) and `local-ai worker` (HTTP on
|
|
# the gRPC base port minus one), and a hardcoded default marked every worker
|
|
# permanently unhealthy (#10987). Set it to pin an explicit URL.
|
|
ENV HEALTHCHECK_ENDPOINT=""
|
|
|
|
ARG CUDA_MAJOR_VERSION=12
|
|
ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility
|
|
ENV NVIDIA_REQUIRE_CUDA="cuda>=${CUDA_MAJOR_VERSION}.0"
|
|
ENV NVIDIA_VISIBLE_DEVICES=all
|
|
|
|
WORKDIR /
|
|
|
|
COPY ./entrypoint.sh .
|
|
COPY ./scripts/build/healthcheck.sh .
|
|
|
|
# Copy the binary
|
|
COPY --from=builder /build/local-ai ./
|
|
# Copy the opus shim if it was built
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 --mount=from=builder,src=/build/,dst=/mnt/build \
|
|
if [ -f /mnt/build/libopusshim.so ]; then cp /mnt/build/libopusshim.so ./; fi
|
|
|
|
# Make sure the models directory exists
|
|
RUN --mount=type=secret,id=build_proxy_ca,target=/run/secrets/build_proxy_ca,mode=0444 mkdir -p /models /backends /data
|
|
|
|
# Define the health check command.
|
|
#
|
|
# --start-period is the knob for slow starts, not --timeout/--retries. Since
|
|
# #10949 a frontend's startup preload materializes HuggingFace artifacts before
|
|
# the HTTP server binds (31 GB observed on a live cluster), so a healthy replica
|
|
# can legitimately fail probes for a long time. Failures inside the start period
|
|
# leave the container `starting` instead of burning retries, and the period ends
|
|
# early on the first success — so a generous value costs a fast-starting
|
|
# container nothing. A process that actually died is handled by the restart
|
|
# policy, not by health.
|
|
#
|
|
# --timeout is a per-probe deadline: 10m meant a wedged probe could hang for ten
|
|
# minutes and stretch detection without bound. A localhost curl that has not
|
|
# answered in 10s is itself the fault being detected.
|
|
HEALTHCHECK --start-period=60m --interval=1m --timeout=10s --retries=3 \
|
|
CMD /healthcheck.sh
|
|
|
|
VOLUME /models /backends /configuration /data
|
|
EXPOSE 8080
|
|
ENTRYPOINT [ "/entrypoint.sh" ]
|