[Fix] Docker: restore pre-uv Prisma cache path - #26201
Conversation
The uv migration added PRISMA_BINARY_CACHE_DIR=/app/.cache/... and XDG_CACHE_HOME=/app/.cache to the runtime stages of Dockerfile and Dockerfile.database. BINARY_PATHS in the generated prisma client was baked to point into /app/.cache, so any deployment that mounts a volume there (common with securityContext.readOnlyRootFilesystem: true and an emptyDir/tmpfs for a writable cache) wipes the pre-downloaded query engine at pod startup, producing BinaryNotFoundError during connect(). Before the uv migration, prisma-python defaulted to $HOME/.cache = /root/.cache (runtime stage runs as root), which was unaffected by any /app/* volume mounts. Restore that behaviour: drop the env vars from the runtime stage, re-run prisma generate there so the query engine AND the baked BINARY_PATHS both land in /root/.cache, and remove the stale builder-stage /app/.cache (~800 MB). Dockerfile.non_root is intentionally left alone — its /app/.cache location is by design for the hardened offline-install flow.
Greptile SummaryThis PR fixes a startup failure ( Confidence Score: 5/5Safe to merge — the core fix is correct and the only remaining finding is a P2 image-size suggestion. All findings are P2 style/cleanup suggestions. The fix correctly roots out the bug, the binary path baked into the generated client now matches where the binary lands at runtime, and the COPY-from-builder approach avoids any network dependency in the runtime layer build. Dockerfile and docker/Dockerfile.database — both have the same broad /root/.cache copy that could be narrowed to /root/.cache/prisma-python.
|
| Filename | Overview |
|---|---|
| Dockerfile | Removes PRISMA_BINARY_CACHE_DIR and XDG_CACHE_HOME from both builder and runtime stages; adds COPY --from=builder /root/.cache /root/.cache — correct fix but copies the full root cache tree (including uv cache) rather than just the prisma-python subtree. |
| docker/Dockerfile.database | Identical changes to Dockerfile — correct fix, same overly broad /root/.cache copy concern applies. |
Sequence Diagram
sequenceDiagram
participant B as builder stage
participant R as runtime stage
participant D as Deployment (pod)
Note over B: prisma generate (no PRISMA_BINARY_CACHE_DIR)<br/>defaults to $HOME/.cache = /root/.cache
B->>B: write binary → /root/.cache/prisma-python/binaries/…
B->>B: write client BINARY_PATHS → /root/.cache/…
B->>R: COPY /app → /app (includes generated client)
B->>R: COPY /root/.cache → /root/.cache (includes query engine binary)
Note over D: volume mount on /app/.cache has no effect
D->>R: container start
R->>R: prisma client resolves BINARY_PATHS → /root/.cache/… ✓
Reviews (3): Last reviewed commit: "Merge remote-tracking branch 'origin/lit..." | Re-trigger Greptile
| # otherwise lose access to the pre-downloaded query engine at runtime. | ||
| # Drop the builder's /app/.cache afterwards — it's stale and adds ~800 MB | ||
| # the runtime doesn't use. | ||
| RUN rm -rf /app/.cache && prisma generate --schema=./schema.prisma |
There was a problem hiding this comment.
Binary re-download adds unnecessary network dependency
The rm -rf /app/.cache discards the query engine binary already downloaded by the builder, and prisma generate then fetches it again from the internet into /root/.cache. This doubles the download time and requires outbound internet access from the runtime layer — which may fail in air-gapped or --network=none build environments.
Consider copying the binary from the builder's /app/.cache into /root/.cache before running prisma generate, so the download only happens once.
Follow-up on review feedback: the previous commit had the builder download the query engine into /app/.cache, then threw it away in the runtime stage and re-downloaded into /root/.cache. That doubled the build-time network fetch. Remove PRISMA_BINARY_CACHE_DIR and XDG_CACHE_HOME from the builder stage as well, so its prisma generate lands in /root/.cache with the correct path layout on its own. Drop the runtime-stage prisma generate and instead COPY --from=builder /root/.cache /root/.cache. Single download, smaller image.
…itellm_prismaCacheRuntime
fc4fe34
into
litellm_internal_staging
[Fix] Docker: restore pre-uv Prisma cache path (cherry picked from commit fc4fe34)
[Fix] Docker: restore pre-uv Prisma cache path
Relevant issues
Summary
Failure Path (Before Fix)
When a deployment mounts a volume at
/app/.cache(common withsecurityContext.readOnlyRootFilesystem: trueplus an emptyDir for a writable cache), the proxy fails at startup:The uv migration (#25007) added
PRISMA_BINARY_CACHE_DIR=/app/.cache/...andXDG_CACHE_HOME=/app/.cacheto the runtime stages ofDockerfileandDockerfile.database. The generated prisma client'sBINARY_PATHSwas baked to point into/app/.cache. Any volume mount shadowing that directory removes the pre-downloaded query engine at pod startup.Before the uv migration the binaries lived in
/root/.cache(prisma-python's default underHOME=/root) and were unaffected by/app/*mounts.Fix
Drop the two env vars from the runtime stage, then re-run
prisma generatethere. With no override, prisma-python defaults to$HOME/.cache=/root/.cache, so both the downloaded query engine and the bakedBINARY_PATHSland outside/app. Remove the stale builder-stage/app/.cacheafterwards (~800 MB it would otherwise carry unused).Dockerfile.non_rootis intentionally unchanged — its/app/.cachelocation is by design for the hardened offline-install flow.Testing
Built both fixed images and ran a three-scenario matrix against a local Postgres:
docker run --tmpfs /app/.cache(reproduces pre-fix failure exactly)docker run --read-only --tmpfs /tmp --tmpfs /app/.cache --tmpfs /app/.npmVerified
BINARY_PATHSin the generated client resolves to/root/.cache/prisma-python/binaries/5.4.2/<engine-hash>/node_modules/prisma/query-engine-*on bothDockerfileandDockerfile.databaseoutputs.Type
🐛 Bug Fix
🚄 Infrastructure