chore(release): backport #33853 to stable/1.90.x and cut 1.90.6 - #33902
Conversation
…migrations work for any uid offline (#33853) * fix(docker): bake prisma CLI and engines at a fixed path so fresh-DB migrations work for any uid offline The runtime image shipped the prisma CLI and engines under /root/.cache, the default HOME-derived prisma-python cache location. Any deployment whose runtime HOME is not /root (kubernetes runAsUser, docker --user, HOME overrides) missed that cache on a fresh database, fell back to a nodeenv Node download that crashes on Wolfi (libatomic.so.1), and started the proxy with zero tables while every DB-backed endpoint returned 500 The bake now lives at /opt/prisma, a path no HOME resolution or cache volume mount can shadow. The builder records the engine paths there at generate time, and the runtime stage pins PRISMA_BINARY_CACHE_DIR, PRISMA_CLI_PATH, PRISMA_CLI_QUERY_ENGINE_TYPE=binary and PRISMA_OFFLINE_MODE so both litellm-proxy-extras and prisma-python resolve the baked CLI and engines directly. prisma migrate deploy on a fresh database now needs no npm and no network access for any runtime uid, including readOnlyRootFilesystem deployments Verified against live containers: fresh and existing databases as root, uid 12345, HOME overridden, on an internal-only docker network, and with a read-only root filesystem all migrate and serve /team/new successfully Fixes #33650, #24554 * chore(docker): fail the image build if the baked prisma CLI layout drifts Asserts the baked CLI shim is executable and its entrypoint exists in the runtime stage after the COPY and chmod, so a layout change in a future prisma-python release breaks the image build loudly instead of silently degrading the migration path at container startup (cherry picked from commit 567ebcb)
Greptile SummaryThis backport cherry-picks the Docker Prisma bake fix (#33853) onto
Confidence Score: 5/5The change is safe to merge: it touches only Dockerfiles, pyproject.toml, and uv.lock, with no Python source changes, and includes build-time assertions that would fail the image build if the binary layout drifted. The Prisma path migration is mechanically correct in both images: the build-stage override records the fixed path into the generated client, the runtime ENV block ensures all processes see the same paths regardless of uid or HOME, and chmod -R a+rX /opt/prisma makes the tree readable and traversable by non-root uids before the test -x guard fires. The dependency updates are lock-only with no pyproject.toml floor changes. No Python logic was touched. No files require special attention.
|
| Filename | Overview |
|---|---|
| Dockerfile | Redirects Prisma CLI and engine cache from HOME-derived /root/.cache to the fixed path /opt/prisma at build time; sets runtime env vars (PRISMA_BINARY_CACHE_DIR, PRISMA_CLI_PATH, PRISMA_OFFLINE_MODE) and adds build-time assertions to verify the binary layout before the image is sealed. |
| docker/Dockerfile.database | Applies identical Prisma bake changes as the main Dockerfile; migrates from /root/.cache/prisma to /opt/prisma with the same runtime env vars and build-time assertions. Uses a different Wolfi base image SHA, which is pre-existing and intentional for this variant. |
| pyproject.toml | Version bump from 1.90.5 to 1.90.6 in both the [project] table and [tool.commitizen] section; no dependency floor changes. |
Reviews (1): Last reviewed commit: "chore: refresh uv.lock for 1.90.6" | Re-trigger Greptile
Relevant issues
Backports the Docker prisma bake onto
stable/1.90.xand cuts 1.90.6. The runtime image previously shipped the prisma CLI and engines under/root/.cache, the default HOME-derived prisma-python cache location, so any deployment whose runtime HOME is not/root(kubernetesrunAsUser,docker --user, HOME overrides) missed that cache on a fresh database, fell back to a nodeenv Node download that crashes on Wolfi, and started the proxy with zero tables while every DB-backed endpoint returned 500. The bake now lives at/opt/prisma, a path no HOME resolution or cache volume mount can shadow. Relates to #33650 and #24554, both already fixed on the development line by #33853This PR also carries routine dependency maintenance on the line's lock file, and the version bump to 1.90.6
Linear ticket
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
make test-unit@greptileaiand received a Confidence Score of at least 4/5 before requesting a maintainer reviewThe picked commit carries no new tests because it changes only Dockerfiles; its correctness is proven by the live container run below, which is the meaningful test for this class of change. The unit-test box reflects a zero-regression delta against this line's pre-change baseline, measured as described below rather than as an absolute pass
Delays in PR merge?
If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).
CI (LiteLLM team)
Branch creation CI run
Link:
CI run for the last commit
Link:
Merge / cherry-pick CI run
Links:
Screenshots / Proof of Fix
The prisma bake, proven against a live container
Both images were built locally from a clean
git archiveof this branch, so the build context matches what CI would send. The pick's own build-time assertions are&&-chained into aRUN, so a drifted layout fails the build rather than silently degrading at container start; both builds passed them.The claim is that a fresh-database migration now works for any runtime uid with no network. That was exercised directly: a brand new Postgres with zero tables, on a Docker network created with
--internal, with the container running as uid 12345 andHOMEpointed at a path that does not exist.Confirming the network really has no egress, from inside that network:
Then the migration itself:
Verified against the database rather than trusting the exit message:
The baked CLI also resolves and runs under the same conditions, which is the specific thing that used to fall through to an npm download:
Both runtime images expose the pinned paths (
PRISMA_CLI_PATH=/opt/prisma/binaries/node_modules/.bin/prisma,PRISMA_BINARY_CACHE_DIR=/opt/prisma/binaries,PRISMA_CLI_QUERY_ENGINE_TYPE=binary,PRISMA_OFFLINE_MODE=true), and the database image ships the proxy-extras schema with 128 migration entries at the source path the migration job targets.The dependency bumps, measured as a delta
Each bumped package resolves to its target in a synced environment: starlette 1.3.1, python-multipart 0.0.30, mcp 1.28.1, pydantic-settings 2.14.2, pypdf 6.13.3.
The mirrored suite on this line is order-dependent under parallel execution, so a single run's failure set is not a reliable signal. The suite was therefore run once before the bumps and twice after, with byte-identical commands:
Comparing a single post-bump run against the baseline suggests 6 new failures in run 1 and 1 in run 2, but the two post-bump sets disagree with each other despite identical inputs, and every one of those tests passes when run on its own. Intersecting the two post-bump runs and subtracting the baseline, which is the set of failures that actually reproduce and are genuinely new, gives zero
Known noise on this line
The pre-change baseline already fails 71 distinct tests, so absolute red on this branch is not meaningful and only the delta above is. Collecting the whole
tests/test_litellmtree in one run also needs--import-mode=importlib, becausetests/test_litellm/models/test_models.pyandtests/test_litellm/proxy/client/test_models.pyshare a basename with no__init__.py. Both conditions predate this PR and also exist on the development lineOne new behavior worth flagging for reviewers: starlette 1.3.x deprecates using
httpxwithstarlette.testclientand emitsStarletteDeprecationWarningrecommendinghttpx2. It is a warning only, it does not affect the shipped proxy, and no test fails on it, but it will start appearing in test output on this lineType
🐛 Bug Fix
🚄 Infrastructure
Changes
In merge order:
uv.lockrefreshThe cherry-pick is byte-identical to its source on the development line:
git patch-id --stablereturns730c2276e12028cb46121514058d047d0f27acc3for both, andgit range-diffshows no difference beyond the added(cherry picked from commit ...)footer. No adaptation was needed, and the pick changes no Python source, so the whole branch diff isDockerfile,docker/Dockerfile.database,pyproject.tomlanduv.lockEvery dependency move is lock-only, each one confirmed to move exactly one package in
uv.lockby parsing both lock files rather than reading the diff. The lock was regenerated with uv 0.11.7, the version this line's Dockerfile pins, so the lock format revision is unchanged. Nopyproject.tomldependency floor changed, so the wheel's install contract is untouched and only the image's resolved versions move#33592 was requested but is already present on this line; it shipped in 1.90.5 as f0b7d8d
#33721 and #33864 were requested and are deliberately excluded. Together they regress
GET /v1/models: a deployment whosemodel_infocarries a non-numeric token limit is registered into the model cost map by the router, which reaches an unguardedint()in the cost-map branch ofcreate_model_info_responseand turns the whole listing into a 500, where this line currently returns 200 and omits that deployment's limits. #33864 hardened the router index path but not the cost-map path. The fix belongs on the development line first and can then be backported alongside both PRs, sostable/1.90.xkeeps parity withstable/1.91.xandstable/1.92.x, which excluded the same pair