diff --git a/.dockerignore b/.dockerignore index 6b80caeaf9f..f3a80fee3e4 100644 --- a/.dockerignore +++ b/.dockerignore @@ -49,6 +49,8 @@ build/ *.egg-info/ .DS_Store **/node_modules +ui/litellm-dashboard/.next +ui/litellm-dashboard/out litellm-rust/target/ litellm/rust_bridge/_native*.so *.log diff --git a/Dockerfile b/Dockerfile index 681681f28cc..b6fef1a21fc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,33 @@ +# syntax=docker/dockerfile:1.7 + # Base image for building ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:c61ac6919b811ea53c4782d69f1fe05218ba3c25d53f01b6ab7892e621bd4370 # Runtime image ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:c61ac6919b811ea53c4782d69f1fe05218ba3c25d53f01b6ab7892e621bd4370 ARG UV_IMAGE=ghcr.io/astral-sh/uv:0.11.7@sha256:240fb85ab0f263ef12f492d8476aa3a2e4e1e333f7d67fbdd923d00a506a516a +# Pinned by digest like the other base images; bump explicitly on Node upgrades. +ARG UI_BUILD_IMAGE=node:20.18-alpine3.20@sha256:3488b10bf958af7125a176419d2d8a9937d895bf124012aae811651988d2ffe6 FROM $UV_IMAGE AS uvbin +# Admin UI builder. Pinned to the build platform so the architecture-independent +# Next.js static export compiles once natively even in a multi-arch build, +# instead of once per target arch under QEMU. +FROM --platform=$BUILDPLATFORM $UI_BUILD_IMAGE AS ui-builder + +ENV NEXT_TELEMETRY_DISABLED=1 \ + npm_config_fund=false \ + npm_config_audit=false + +WORKDIR /ui + +COPY ui/litellm-dashboard/package.json ui/litellm-dashboard/package-lock.json ./ +RUN --mount=type=cache,target=/root/.npm npm ci --prefer-offline + +COPY ui/litellm-dashboard/ ./ +RUN npm run build + # Builder stage FROM $LITELLM_BUILD_IMAGE AS builder @@ -48,7 +69,13 @@ RUN uv sync --frozen --no-install-project --no-install-workspace --no-default-gr # Copy full source tree COPY . . -# Build Admin UI before final sync +# Replace the committed UI bundle with the one built from this exact source. +# Clearing first drops the committed bundle's content-hashed chunks that COPY +# would otherwise leave behind alongside the fresh ones. +RUN rm -rf litellm/proxy/_experimental/out +COPY --from=ui-builder /ui/out/. litellm/proxy/_experimental/out/ + +# Build Admin UI before final sync (applies the enterprise color override when present) RUN sed -i 's/\r$//' docker/build_admin_ui.sh && chmod +x docker/build_admin_ui.sh && ./docker/build_admin_ui.sh # Install project and workspace packages (fast - deps already cached) diff --git a/docker/Dockerfile.database b/docker/Dockerfile.database index 50ef55e3261..b3af953511d 100644 --- a/docker/Dockerfile.database +++ b/docker/Dockerfile.database @@ -1,12 +1,33 @@ +# syntax=docker/dockerfile:1.7 + # Base image for building ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:c61ac6919b811ea53c4782d69f1fe05218ba3c25d53f01b6ab7892e621bd4370 # Runtime image ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:c61ac6919b811ea53c4782d69f1fe05218ba3c25d53f01b6ab7892e621bd4370 ARG UV_IMAGE=ghcr.io/astral-sh/uv:0.11.7@sha256:240fb85ab0f263ef12f492d8476aa3a2e4e1e333f7d67fbdd923d00a506a516a +# Pinned by digest like the other base images; bump explicitly on Node upgrades. +ARG UI_BUILD_IMAGE=node:20.18-alpine3.20@sha256:3488b10bf958af7125a176419d2d8a9937d895bf124012aae811651988d2ffe6 FROM $UV_IMAGE AS uvbin +# Admin UI builder. Pinned to the build platform so the architecture-independent +# Next.js static export compiles once natively even in a multi-arch build, +# instead of once per target arch under QEMU. +FROM --platform=$BUILDPLATFORM $UI_BUILD_IMAGE AS ui-builder + +ENV NEXT_TELEMETRY_DISABLED=1 \ + npm_config_fund=false \ + npm_config_audit=false + +WORKDIR /ui + +COPY ui/litellm-dashboard/package.json ui/litellm-dashboard/package-lock.json ./ +RUN --mount=type=cache,target=/root/.npm npm ci --prefer-offline + +COPY ui/litellm-dashboard/ ./ +RUN npm run build + FROM $LITELLM_BUILD_IMAGE AS builder WORKDIR /app @@ -46,7 +67,13 @@ RUN uv sync --frozen --no-install-project --no-install-workspace --no-default-gr # Copy full source tree COPY . . -# Build Admin UI before final sync +# Replace the committed UI bundle with the one built from this exact source. +# Clearing first drops the committed bundle's content-hashed chunks that COPY +# would otherwise leave behind alongside the fresh ones. +RUN rm -rf litellm/proxy/_experimental/out +COPY --from=ui-builder /ui/out/. litellm/proxy/_experimental/out/ + +# Build Admin UI before final sync (applies the enterprise color override when present) RUN sed -i 's/\r$//' docker/build_admin_ui.sh && chmod +x docker/build_admin_ui.sh && ./docker/build_admin_ui.sh # Install project and workspace packages (fast - deps already cached) diff --git a/docker/Dockerfile.non_root b/docker/Dockerfile.non_root index 6bb925aa723..c24cb9008f0 100644 --- a/docker/Dockerfile.non_root +++ b/docker/Dockerfile.non_root @@ -1,11 +1,32 @@ +# syntax=docker/dockerfile:1.7 + # Base images ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:c61ac6919b811ea53c4782d69f1fe05218ba3c25d53f01b6ab7892e621bd4370 ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:c61ac6919b811ea53c4782d69f1fe05218ba3c25d53f01b6ab7892e621bd4370 ARG PROXY_EXTRAS_SOURCE=published ARG UV_IMAGE=ghcr.io/astral-sh/uv:0.11.7@sha256:240fb85ab0f263ef12f492d8476aa3a2e4e1e333f7d67fbdd923d00a506a516a +# Pinned by digest like the other base images; bump explicitly on Node upgrades. +ARG UI_BUILD_IMAGE=node:20.18-alpine3.20@sha256:3488b10bf958af7125a176419d2d8a9937d895bf124012aae811651988d2ffe6 FROM $UV_IMAGE AS uvbin +# Admin UI builder. Pinned to the build platform so the architecture-independent +# Next.js static export compiles once natively even in a multi-arch build, +# instead of once per target arch under QEMU. +FROM --platform=$BUILDPLATFORM $UI_BUILD_IMAGE AS ui-builder + +ENV NEXT_TELEMETRY_DISABLED=1 \ + npm_config_fund=false \ + npm_config_audit=false + +WORKDIR /ui + +COPY ui/litellm-dashboard/package.json ui/litellm-dashboard/package-lock.json ./ +RUN --mount=type=cache,target=/root/.npm npm ci --prefer-offline + +COPY ui/litellm-dashboard/ ./ +RUN npm run build + FROM $LITELLM_BUILD_IMAGE AS builder ARG PROXY_EXTRAS_SOURCE WORKDIR /app @@ -53,6 +74,12 @@ RUN --mount=type=cache,target=/app/.cache/uv,id=litellm-uv-cache \ # Copy full source tree COPY . . +# Replace the committed UI bundle with the one built from this exact source. +# Clearing first drops the committed bundle's content-hashed chunks that COPY +# would otherwise leave behind alongside the fresh ones. +RUN rm -rf litellm/proxy/_experimental/out +COPY --from=ui-builder /ui/out/. litellm/proxy/_experimental/out/ + # Set non-root flag for build time consistency ENV LITELLM_NON_ROOT=true