mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-30 06:43:27 +00:00
Dockerfile.fips builds on chainguard-base-fips with FIPS-provider-linked python/node/openssl from the org apk repo (CMVP #5132). A fips-check stage runs openssl-fips-test and an ELF allowlist gate: every native binary must be in the reviewed fips_elf_inventory.txt or carry an explicit bundled-crypto waiver, so new native deps fail the build until reviewed. Known offenders are waived pending the dependency-fix workstream and the report ships at /fips-scan-report.txt
169 lines
6.6 KiB
Text
169 lines
6.6 KiB
Text
# syntax=docker/dockerfile:1.7
|
|
|
|
# FIPS 140-3 variant (workstream A of the FIPS roadmap). Builds on
|
|
# chainguard-base-fips so python/node/openssl resolve to Chainguard's
|
|
# FIPS-provider-linked packages from the image's pinned virtualapk repo.
|
|
# Build requires a Chainguard token:
|
|
# CGR_TOKEN=$(chainctl auth token --audience apk.cgr.dev) \
|
|
# docker build --secret id=cgr-token,env=CGR_TOKEN -f docker/Dockerfile.fips .
|
|
ARG LITELLM_BUILD_IMAGE=cgr.dev/berri.ai/chainguard-base-fips@sha256:4f23c1a31be6a0778c4851c54474c7630b2feda7d113c7b1b5e7b1def8c89b04
|
|
|
|
ARG LITELLM_RUNTIME_IMAGE=cgr.dev/berri.ai/chainguard-base-fips@sha256:4f23c1a31be6a0778c4851c54474c7630b2feda7d113c7b1b5e7b1def8c89b04
|
|
ARG UV_IMAGE=ghcr.io/astral-sh/uv:0.11.7@sha256:240fb85ab0f263ef12f492d8476aa3a2e4e1e333f7d67fbdd923d00a506a516a
|
|
# UI builder only emits static JS assets; no binary from it reaches the final
|
|
# image, so it does not need a FIPS base.
|
|
ARG UI_BUILD_IMAGE=node:24.19-alpine3.24@sha256:d32cdf619f63fe0471182d08996dd516c6275bb5fd31ae06e55a570bd9e1ad43
|
|
# Checksum from https://www.pgbouncer.org/downloads/
|
|
ARG PGBOUNCER_VERSION=1.25.2
|
|
ARG PGBOUNCER_SHA256=924ad35113fd0a71c8e2dbe85b5d03445532e2b7b37a9f8a48983beea238b332
|
|
|
|
FROM $UV_IMAGE AS uvbin
|
|
|
|
FROM $LITELLM_BUILD_IMAGE AS pgbouncer-builder
|
|
ARG PGBOUNCER_VERSION
|
|
ARG PGBOUNCER_SHA256
|
|
USER root
|
|
# openssl-dev here is the FIPS-configured system OpenSSL, so pgbouncer links
|
|
# libcrypto.so.3 and inherits the FIPS provider at runtime.
|
|
RUN --mount=type=secret,id=cgr-token \
|
|
HTTP_AUTH="basic:virtualapk.cgr.dev:user:$(cat /run/secrets/cgr-token)" \
|
|
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
|
|
|
|
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
|
|
USER root
|
|
|
|
COPY --from=uvbin /uv /usr/local/bin/uv
|
|
COPY --from=uvbin /uvx /usr/local/bin/uvx
|
|
|
|
RUN --mount=type=secret,id=cgr-token \
|
|
HTTP_AUTH="basic:virtualapk.cgr.dev:user:$(cat /run/secrets/cgr-token)" \
|
|
apk add --no-cache \
|
|
bash \
|
|
gcc \
|
|
python-3.13 \
|
|
python-3.13-dev \
|
|
openssl \
|
|
openssl-dev \
|
|
nodejs \
|
|
npm \
|
|
libsndfile
|
|
|
|
# UV_PYTHON_DOWNLOADS=0: uv must never substitute a standalone CPython with
|
|
# its own bundled OpenSSL for the FIPS-linked system python.
|
|
ENV UV_PROJECT_ENVIRONMENT=/app/.venv \
|
|
UV_LINK_MODE=copy \
|
|
UV_PYTHON_DOWNLOADS=0 \
|
|
PATH="/app/.venv/bin:${PATH}"
|
|
|
|
COPY pyproject.toml uv.lock ./
|
|
COPY enterprise/pyproject.toml enterprise/
|
|
COPY litellm-proxy-extras/pyproject.toml litellm-proxy-extras/
|
|
|
|
RUN uv sync --frozen --no-install-project --no-install-workspace --no-default-groups --no-editable \
|
|
--extra proxy \
|
|
--extra proxy-runtime \
|
|
--extra extra_proxy \
|
|
--extra semantic-router \
|
|
--extra saml \
|
|
--extra bedrock-realtime \
|
|
--python python3.13
|
|
|
|
COPY . .
|
|
|
|
RUN rm -rf litellm/proxy/_experimental/out
|
|
COPY --from=ui-builder /ui/out/. litellm/proxy/_experimental/out/
|
|
|
|
RUN sed -i 's/\r$//' docker/build_admin_ui.sh && chmod +x docker/build_admin_ui.sh && ./docker/build_admin_ui.sh
|
|
|
|
RUN uv sync --frozen --no-default-groups --no-editable \
|
|
--extra proxy \
|
|
--extra proxy-runtime \
|
|
--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
|
|
|
|
USER root
|
|
|
|
# Unlike the non-FIPS images, the public Wolfi repo is deliberately NOT added
|
|
# here: apk in this image may only resolve FIPS-linked packages from the
|
|
# pinned Chainguard repo.
|
|
RUN --mount=type=secret,id=cgr-token \
|
|
HTTP_AUTH="basic:virtualapk.cgr.dev:user:$(cat /run/secrets/cgr-token)" \
|
|
apk add --no-cache bash openssl openssl-fips-test 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 --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
|
|
COPY --from=builder /app/enterprise /app/enterprise
|
|
COPY --from=builder /app/litellm-proxy-extras /app/litellm-proxy-extras
|
|
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"
|
|
|
|
# Build-time FIPS assertions. binutils (objdump) is installed only in this
|
|
# throwaway stage; the final image below is FROM runtime and never sees it.
|
|
FROM runtime AS fips-check
|
|
RUN --mount=type=secret,id=cgr-token \
|
|
HTTP_AUTH="basic:virtualapk.cgr.dev:user:$(cat /run/secrets/cgr-token)" \
|
|
apk add --no-cache binutils
|
|
RUN openssl-fips-test
|
|
RUN chmod +x docker/scan_bundled_crypto.sh && \
|
|
docker/scan_bundled_crypto.sh /app/.venv /opt/prisma /usr/local/bin
|
|
|
|
FROM runtime AS final
|
|
|
|
# Forces the fips-check stage to build and records its evidence in the image.
|
|
COPY --from=fips-check /fips-scan-report.txt /fips-scan-report.txt
|
|
|
|
EXPOSE 4000/tcp
|
|
|
|
ENTRYPOINT ["docker/prod_entrypoint.sh"]
|
|
CMD ["--port", "4000"]
|