fix(gateway): v1.0.1 — container/Helm serve path: config-driven entrypoint + /readyz + valid chart config#185
Merged
Conversation
…point + /readyz + valid chart config
The shipped container/Helm run path was broken end-to-end:
- The image CMD was a stale Phase-0 placeholder (printed the version and
exited); the image build itself also failed — sdks/python is a workspace
member but was never copied, so the full `uv sync` died with
"Distribution not found".
- The Helm chart set RAG_CONFIG_PATH with zero consumers in the codebase,
so pods ran the version-print CMD and CrashLooped.
- The chart's readinessProbe targeted /readyz, which did not exist.
- The chart's ConfigMap rendered an invalid rag.yaml (env:/log_level:/
service: against the strict extra='forbid' RagConfig schema), and the
0.1.0 appVersion pointed the default image tag at a tag that never
existed.
Fixes:
- New rag_gateway.serve:create_app uvicorn factory — RAG_CONFIG_PATH set →
build_app_from_config(load(path)); unset → noop build_app(); set but
broken → fail fast with ConfigError (never a silent noop fallback).
- Dockerfile CMD now serves: uvicorn rag_gateway.serve:create_app
--factory --host 0.0.0.0 --port 8000; builder + runtime stages copy
sdks/python so the image builds.
- GET /readyz public readiness route (wiring completes in the factory, so
ready == fully constructed); dist/openapi.* + rest-api.md regenerated.
- Chart renders a minimal valid rag.yaml with a config.ragYaml passthrough
(${VAR} env interpolation keeps secrets out of the ConfigMap); chart
0.2.0, appVersion 1.0.1; values.dev.yaml env: development → local
(not a valid PlatformEnv).
- Image-tag docs corrected: tags publish without the "v" prefix.
Verified: ruff / mypy --strict / pytest green; helm lint + template with
three config variants validated through the real RagConfig loader; live
uvicorn boots in noop / config / broken modes (broken exits 1 with
ConfigError); both Docker sync stages simulated with uv (docker
unavailable locally).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What broke (v1.0.0)
The shipped container/Helm run path was broken end-to-end, in four connected pieces:
python -c "import rag_gateway; print(...)"): it printed the version and exited instead of serving.sdks/pythonis a uv workspace member but was neverCOPY'd, so the Dockerfile's fulluv sync --frozen --no-devfails withDistribution not found at: …/sdks/python. The image could not even be built. (Verified by simulating both Docker stages with uv; note thedocker.ymlworkflow has also never actually run — every run since GA fails at job start with a GitHub billing/spending-limit error, which needs an account-settings fix outside this PR.)RAG_CONFIG_PATHhad zero consumers — the Helm chart sets it and mounts a ConfigMap, but nothing in the codebase read it, and the deployment has no command override → pods run the version-print CMD and CrashLoop./readyz(didn't exist); the ConfigMap rendered an invalidrag.yaml(env:/log_level:/service:against the strictextra='forbid'RagConfigschema);appVersion: 0.1.0pointed the default image tag at a tag that never existed;values.dev.yamlusedenv: development, which is not a validPlatformEnv.The fix
rag_gateway.serve:create_app(new) — uvicorn factory entrypoint.RAG_CONFIG_PATHset →build_app_from_config(load(path)); unset/empty → noopbuild_app(); set-but-broken → fail fast withConfigError(a typo'd mount crashes the pod loudly, never silently serves noop wiring in production).CMD ["uvicorn", "rag_gateway.serve:create_app", "--factory", "--host", "0.0.0.0", "--port", "8000"]; builder + runtime stages copysdks/python(members install editable, so the venv references the source trees).GET /readyz— public readiness route next to/healthz; all wiring happens in the app factory before the socket binds, soready⇒ fully constructed.dist/openapi.{json,yaml}+ generateddocs/reference/rest-api.mdregenerated (drift gates green).0.2.0/ appVersion1.0.1— ConfigMap renders a minimal validrag.yamlby default, with a newconfig.ragYamlvalues passthrough for complete platform configs;${VAR}/${VAR:-default}env interpolation keeps secrets inSecret-injected env vars, out of the ConfigMap.values.dev.yamlenv: local.vprefix (docker/metadata-actionsemver patterns);:v1.0.0-style pulls in README/guides never matched.ruff formatdrift in two test files included (CI hasn't run since the billing failure, so it crept in unnoticed).This is a v1.0.1 PATCH per the SemVer policy in ADR-0052 (
/readyzis additive; everything else is a fix).Verification
ruff check+ruff format --check+ RAG001 logging gate +mypy --strict(331 files) + fullpytest tests/ packages/ apps/— all green.helm lint+helm templatefor default values,values.dev.yaml, and aconfig.ragYamloverride — each renderedrag.yamlvalidated through the realrag_config.loads()(env interpolation exercised:${RAG_QDRANT_HOST}→ resolved URL)./healthz{"status":"ok"},/readyz{"status":"ready"},/v1/info200), config-driven mode (validrag.yamlviaRAG_CONFIG_PATH), broken path (uvicorn exits 1 withConfigError: config file not found).--no-install-workspace, 3 manifests) resolves; stage 2 (full source) failed exactly as the image would (sdks/pythonmissing) and resolves 144 packages incl.rag-gateway/rag-backends/uvicornafter the fix. A realdocker build && docker run+helm installsmoke test on a Docker-equipped machine is the remaining follow-through, ideally after the Actions billing issue is fixed sodocker.ymlcan publish.Documentation
docs/release-notes/v1.0.1.md— new patch release notes.docs/reference/gateway.md— new Config-driven serving section (entrypoint semantics, docker run examples, Helm flow internals, probes);/readyzin the route table.docs/reference/rest-api.md+dist/openapi.*— regenerated.docs/guides/packaging-distribution.md— image default CMD + corrected tag format.README.md— "Deploy to production" container/Helm rows updated; Known-gap callout removed.docs/README.md— release-notes index row.TRACKER.md— v1.0.1 entry, PR history (incl. backfilled docs: GA polish — site publishing scope, HLD v1.2, ragctl reference, port + link fixes #184), stale Milestone Summary corrected (77/84 → 84/84).🤖 Generated with Claude Code