mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-27 06:13:07 +00:00
* fix(security): bump grpcio and boto3 so their bundled CA files drop the compromised eMudhra roots grpc ignores SSL_CERT_FILE and verifies every channel against its own bundled roots.pem. In 1.78.0 that file still trusts emSign ECC Root CA - G3 and AAA Certificate Services, so Vertex AI, Google KMS, Chirp STT and OTLP gRPC exporters (Arize) accept all 14 advisory chains. 1.84.1 is the first release whose roots.pem drops both roots. botocore uses certifi when it is installed and falls back to its bundled cacert.pem otherwise. Through 1.43.116 that file still trusts AAA Certificate Services. Requiring boto3 1.43.117 pulls in botocore 1.43.117, the first release whose cacert.pem rejects all 14 advisory chains, so the fallback stays safe if certifi is ever absent * fix(docker): provide OpenSSL 3 when generating Prisma engines
168 lines
6.7 KiB
Text
168 lines
6.7 KiB
Text
# syntax=docker/dockerfile:1.7
|
|
|
|
# Base image for building
|
|
ARG LITELLM_BUILD_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:81211e15a86ea1d5357f284482af45730c51de45eaf10ad9ce205d6bfc2df323
|
|
|
|
# Runtime image
|
|
ARG LITELLM_RUNTIME_IMAGE=cgr.dev/chainguard/wolfi-base@sha256:81211e15a86ea1d5357f284482af45730c51de45eaf10ad9ce205d6bfc2df323
|
|
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:24.19-alpine3.24@sha256:d32cdf619f63fe0471182d08996dd516c6275bb5fd31ae06e55a570bd9e1ad43
|
|
# Checksum from https://www.pgbouncer.org/downloads/ (the Wolfi repo only carries 1.24.x)
|
|
ARG PGBOUNCER_VERSION=1.26.0
|
|
ARG PGBOUNCER_SHA256=afd25dd61ee6775d37b40629b87ce08736b3e6955f3057bb212e410fbf21c71d
|
|
|
|
FROM $UV_IMAGE AS uvbin
|
|
|
|
FROM $LITELLM_BUILD_IMAGE AS pgbouncer-builder
|
|
ARG PGBOUNCER_VERSION
|
|
ARG PGBOUNCER_SHA256
|
|
USER root
|
|
RUN apk add --no-cache build-base pkgconf libevent-dev openssl-dev curl
|
|
WORKDIR /build
|
|
RUN curl -fsSL -o pgbouncer.tar.gz "https://www.pgbouncer.org/downloads/files/${PGBOUNCER_VERSION}/pgbouncer-${PGBOUNCER_VERSION}.tar.gz" && \
|
|
echo "${PGBOUNCER_SHA256} pgbouncer.tar.gz" | sha256sum -c - && \
|
|
tar xzf pgbouncer.tar.gz --strip-components=1 && \
|
|
./configure --prefix=/usr/local --with-openssl=/usr && \
|
|
make -j"$(nproc)" pgbouncer && \
|
|
install -m 0755 pgbouncer /usr/local/bin/pgbouncer
|
|
|
|
# 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 ./
|
|
COPY ui/litellm-dashboard/vendor/ ./vendor/
|
|
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
|
|
USER root
|
|
|
|
COPY --from=uvbin /uv /usr/local/bin/uv
|
|
COPY --from=uvbin /uvx /usr/local/bin/uvx
|
|
|
|
RUN apk add --no-cache \
|
|
bash \
|
|
gcc \
|
|
python-3.13 \
|
|
python-3.13-dev \
|
|
openssl \
|
|
libssl3 \
|
|
openssl-dev \
|
|
nodejs \
|
|
npm \
|
|
libsndfile
|
|
|
|
ENV UV_PROJECT_ENVIRONMENT=/app/.venv \
|
|
UV_LINK_MODE=copy \
|
|
UV_PYTHON_DOWNLOADS=0 \
|
|
PATH="/app/.venv/bin:${PATH}"
|
|
|
|
# Copy dependency metadata first for layer caching
|
|
COPY pyproject.toml uv.lock ./
|
|
COPY enterprise/pyproject.toml enterprise/
|
|
COPY litellm-proxy-extras/pyproject.toml litellm-proxy-extras/
|
|
|
|
# Install third-party dependencies (cached unless pyproject.toml/uv.lock change)
|
|
RUN uv sync --frozen --no-install-project --no-install-workspace --no-default-groups --no-editable \
|
|
--extra proxy \
|
|
--extra proxy-runtime \
|
|
--group admin-mcp \
|
|
--extra extra_proxy \
|
|
--extra semantic-router \
|
|
--extra saml \
|
|
--extra bedrock-realtime \
|
|
--python python3.13
|
|
|
|
# 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/
|
|
|
|
# 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)
|
|
RUN uv sync --frozen --no-default-groups --no-editable \
|
|
--extra proxy \
|
|
--extra proxy-runtime \
|
|
--group admin-mcp \
|
|
--extra extra_proxy \
|
|
--extra semantic-router \
|
|
--extra saml \
|
|
--extra bedrock-realtime \
|
|
--python python3.13
|
|
|
|
RUN HOME=/opt/prisma XDG_CACHE_HOME=/opt/prisma/.cache PRISMA_BINARY_CACHE_DIR=/opt/prisma/binaries \
|
|
npm_config_cache=/root/.npm \
|
|
prisma generate --schema=./schema.prisma
|
|
|
|
RUN sed -i 's/\r$//' docker/entrypoint.sh && chmod +x docker/entrypoint.sh && \
|
|
sed -i 's/\r$//' docker/prod_entrypoint.sh && chmod +x docker/prod_entrypoint.sh
|
|
|
|
FROM $LITELLM_RUNTIME_IMAGE AS runtime
|
|
ARG LITELLM_RELEASE_TAG=""
|
|
ENV LITELLM_RELEASE_TAG=${LITELLM_RELEASE_TAG}
|
|
|
|
USER root
|
|
|
|
# node (without npm) is required by the prisma CLI at runtime
|
|
RUN apk add --no-cache bash openssl libssl3 tzdata nodejs python-3.13 libsndfile libevent
|
|
COPY --from=pgbouncer-builder /usr/local/bin/pgbouncer /usr/local/bin/pgbouncer
|
|
|
|
WORKDIR /app
|
|
ENV PATH="/app/.venv/bin:${PATH}" \
|
|
PRISMA_BINARY_CACHE_DIR=/opt/prisma/binaries \
|
|
PRISMA_CLI_PATH=/opt/prisma/binaries/node_modules/.bin/prisma \
|
|
PRISMA_CLI_QUERY_ENGINE_TYPE=binary \
|
|
PRISMA_OFFLINE_MODE=true
|
|
|
|
# Copy only what runtime needs. The application is installed inside the venv;
|
|
# the rest of the builder's /app is source and build metadata that must not
|
|
# ship (manifest-scanning tools attribute everything in it to this image).
|
|
# entrypoint.sh invokes litellm/proxy/prisma_migration.py by source path.
|
|
COPY --from=builder /app/.venv /app/.venv
|
|
COPY --from=builder /app/docker /app/docker
|
|
COPY --from=builder /app/schema.prisma /app/schema.prisma
|
|
COPY --from=builder /app/litellm/proxy/prisma_migration.py /app/litellm/proxy/prisma_migration.py
|
|
# enterprise/ is imported by source path at runtime (proxy_cli puts the
|
|
# working directory on sys.path; litellm/proxy/hooks resolves
|
|
# enterprise.enterprise_hooks from it)
|
|
COPY --from=builder /app/enterprise /app/enterprise
|
|
COPY --from=builder /app/litellm-proxy-extras /app/litellm-proxy-extras
|
|
# Prisma CLI + engines are baked under /opt/prisma, a fixed path every
|
|
# runtime uid can read and that no cache volume mount shadows (unlike
|
|
# /app/.cache or $HOME/.cache in readOnlyRootFilesystem + emptyDir setups).
|
|
# The paths are pinned via PRISMA_BINARY_CACHE_DIR / PRISMA_CLI_PATH and
|
|
# recorded into the generated client at build time, so `prisma migrate
|
|
# deploy` on a fresh database needs no npm and no network access
|
|
# (#33650, #24554).
|
|
COPY --from=builder /opt/prisma /opt/prisma
|
|
|
|
RUN find /app/.venv -type f -path "*/tornado/test/*" -delete && \
|
|
find /app/.venv -type d -path "*/tornado/test" -delete && \
|
|
chmod -R a+rX /opt/prisma && \
|
|
test -x /opt/prisma/binaries/node_modules/.bin/prisma && \
|
|
test -f /opt/prisma/binaries/node_modules/prisma/build/index.js && \
|
|
python -c "from prisma.client import BINARY_PATHS; paths = list(BINARY_PATHS.query_engine.values()); assert paths and all(p.startswith('/opt/prisma/') for p in paths), paths"
|
|
|
|
EXPOSE 4000/tcp
|
|
|
|
ENTRYPOINT ["docker/prod_entrypoint.sh"]
|
|
CMD ["--port", "4000"]
|