From 1130c28fc897de5dffa49f1613b5b374a1e113cc Mon Sep 17 00:00:00 2001 From: superpoussin22 Date: Tue, 10 Mar 2026 16:24:26 +0100 Subject: [PATCH] Enhance Dockerfile with build and runtime improvements Updated Dockerfile to include additional build and runtime dependencies, improved caching mechanisms, and patched npm dependencies for security. --- docker/Dockerfile.non_root_macos | 71 +++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 5 deletions(-) diff --git a/docker/Dockerfile.non_root_macos b/docker/Dockerfile.non_root_macos index 22b6a599452..325737412be 100644 --- a/docker/Dockerfile.non_root_macos +++ b/docker/Dockerfile.non_root_macos @@ -4,6 +4,7 @@ ARG PROXY_EXTRAS_SOURCE=published WORKDIR /app +# Build deps (UI build + compiling wheels) RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential gcc g++ \ curl ca-certificates \ @@ -13,10 +14,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ RUN pip install --no-cache-dir --upgrade pip build +# Wheels cache COPY requirements.txt . RUN pip wheel --no-cache-dir --wheel-dir=/wheels/ -r requirements.txt \ - && pip wheel --no-cache-dir --wheel-dir=/wheels/ "semantic_router==0.1.11" "aurelio-sdk==0.0.19" "PyJWT==2.9.0" + && pip wheel --no-cache-dir --wheel-dir=/wheels/ "semantic_router==0.1.11" "aurelio-sdk==0.0.19" \ + && pip wheel --no-cache-dir --wheel-dir=/wheels/ "PyJWT==2.9.0" +# Source COPY . . ENV LITELLM_NON_ROOT=true @@ -54,7 +58,7 @@ RUN if [ "$PROXY_EXTRAS_SOURCE" = "local" ]; then \ cp dist/*.whl /wheels/; \ fi -# Cache Prisma engines/CLI in builder (for offline runtime) +# ---- Prisma cache (builder) ---- ENV HOME=/app \ XDG_CACHE_HOME=/app/.cache \ PRISMA_BINARY_CACHE_DIR=/app/.cache/prisma-python/binaries \ @@ -63,9 +67,10 @@ ENV HOME=/app \ RUN pip install --no-cache-dir prisma==0.11.0 nodejs-wheel-binaries==24.13.1 \ && mkdir -p /app/.cache/npm +# Cache Node Prisma CLI + engines into /app/.cache/prisma-python/binaries RUN python3 -c "import prisma.cli.prisma as p; p.ensure_cached()" -# Patch schema.prisma (remove binaryTargets for prisma-client-py generator) +# Patch schema.prisma: remove binaryTargets for prisma-client-py generator block RUN python3 - <<'PY' import re p="/app/schema.prisma" @@ -86,12 +91,16 @@ ARG PROXY_EXTRAS_SOURCE=published WORKDIR /app -# libatomic1 required for nodeenv's node binary used by prisma-client-py +# Runtime deps: +# - supervisor: required when SEPARATE_HEALTH_APP=1 causes prod_entrypoint.sh to exec supervisord +# - libatomic1: required for nodeenv node used by prisma generate RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates bash openssl \ + supervisor \ libatomic1 \ && rm -rf /var/lib/apt/lists/* +# Copy app bits + wheels COPY --from=builder /app/requirements.txt /app/requirements.txt COPY --from=builder /app/docker/entrypoint.sh /app/docker/prod_entrypoint.sh /app/docker/ COPY --from=builder /app/docker/supervisord.conf /etc/supervisord.conf @@ -105,14 +114,22 @@ COPY --from=builder /wheels /wheels # Copy cached prisma binaries/cli COPY --from=builder /app/.cache/prisma-python /app/.cache/prisma-python +# Offline + non-root friendly env ENV LITELLM_NON_ROOT=true \ HOME=/app \ XDG_CACHE_HOME=/app/.cache \ PRISMA_BINARY_CACHE_DIR=/app/.cache/prisma-python/binaries \ + PRISMA_CLI_BINARY_TARGETS=debian-openssl-3.0.x \ + PRISMA_SKIP_POSTINSTALL_GENERATE=1 \ + PRISMA_HIDE_UPDATE_MESSAGE=1 \ + PRISMA_ENGINES_CHECKSUM_IGNORE_MISSING=1 \ + NPM_CONFIG_PREFER_OFFLINE=true \ + PRISMA_OFFLINE_MODE=true \ NPM_CONFIG_CACHE=/app/.cache/npm \ LITELLM_MIGRATION_DIR=/app/.litellm_migrations -# Install deps offline +# Install deps offline. +# Important: install PyJWT last to avoid jwt/PyJWT resolution issues (mirrors non_root logic). RUN pip install --no-index --find-links=/wheels/ -r requirements.txt && \ pip install --no-index --find-links=/wheels/ /wheels/litellm-*-py3-none-any.whl && \ pip install --no-index --find-links=/wheels/ --no-deps semantic_router==0.1.11 && \ @@ -122,12 +139,56 @@ RUN pip install --no-index --find-links=/wheels/ -r requirements.txt && \ pip install --no-index --find-links=/wheels/ /wheels/litellm_proxy_extras-*.whl; \ fi; \ fi && \ + pip install --no-index --find-links=/wheels/ "PyJWT==2.9.0" && \ rm -rf /wheels # Install prisma tooling in runtime and generate client INTO runtime site-packages RUN pip install --no-cache-dir prisma==0.11.0 nodejs-wheel-binaries==24.13.1 && \ python3 -m prisma generate +# Patch bundled npm deps under nodejs-wheel-binaries to address known CVEs +# (tar, glob, brace-expansion, minimatch, diff). +RUN python3 - <<'PY' +import site, pathlib, subprocess, sys + +# Find site-packages +paths = [pathlib.Path(p) for p in site.getsitepackages() if p] +# Find nodejs-wheel-binaries package +pkg = None +for sp in paths: + cand = sp / "nodejs_wheel_binaries" + if cand.exists(): + pkg = cand + break + +if not pkg: + print("nodejs_wheel_binaries not found; skipping npm CVE patching", file=sys.stderr) + sys.exit(0) + +# npm node_modules is typically under nodejs_wheel_binaries/<...>/lib/node_modules/npm/node_modules +nm_roots = list(pkg.rglob("lib/node_modules/npm/node_modules")) +if not nm_roots: + print("npm bundled node_modules not found; skipping npm CVE patching", file=sys.stderr) + sys.exit(0) + +root = nm_roots[0] +print(f"Patching npm deps under: {root}") + +def npm_pack_install(name, ver): + # Use npm from system node if present; if not, skip (but on this image nodejs-wheel-binaries provides node runtime for prisma) + cmd = ["bash", "-lc", f"cd '{root}' && npm install --no-audit --no-fund --silent {name}@{ver}"] + subprocess.check_call(cmd) + +# Versions chosen to match typical non_root patch sets; bump if your security scanner requires newer +npm_pack_install("tar", "6.2.1") +npm_pack_install("glob", "10.4.5") +npm_pack_install("brace-expansion", "2.0.1") +npm_pack_install("minimatch", "9.0.5") +npm_pack_install("diff", "5.2.0") + +print("npm CVE patching done.") +PY + # scripts + permissions (non-root uid/gid 65534) RUN sed -i 's/\r$//' /app/docker/entrypoint.sh && \ sed -i 's/\r$//' /app/docker/prod_entrypoint.sh && \