Skip to content

fix(gateway): v1.0.1 — container/Helm serve path: config-driven entrypoint + /readyz + valid chart config#185

Merged
officialCodeWork merged 1 commit into
mainfrom
fix/v1.0.1-serve-entrypoint
Jun 10, 2026
Merged

fix(gateway): v1.0.1 — container/Helm serve path: config-driven entrypoint + /readyz + valid chart config#185
officialCodeWork merged 1 commit into
mainfrom
fix/v1.0.1-serve-entrypoint

Conversation

@officialCodeWork

Copy link
Copy Markdown
Owner

What broke (v1.0.0)

The shipped container/Helm run path was broken end-to-end, in four connected pieces:

  1. Stale image CMD — the root Dockerfile still carried the Phase-0 placeholder (python -c "import rag_gateway; print(...)"): it printed the version and exited instead of serving.
  2. Image build failuresdks/python is a uv workspace member but was never COPY'd, so the Dockerfile's full uv sync --frozen --no-dev fails with Distribution not found at: …/sdks/python. The image could not even be built. (Verified by simulating both Docker stages with uv; note the docker.yml workflow 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.)
  3. RAG_CONFIG_PATH had 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.
  4. Chart internals — the readinessProbe targeted /readyz (didn't exist); the ConfigMap rendered an invalid rag.yaml (env:/log_level:/service: against the strict extra='forbid' RagConfig schema); appVersion: 0.1.0 pointed the default image tag at a tag that never existed; values.dev.yaml used env: development, which is not a valid PlatformEnv.

The fix

  • rag_gateway.serve:create_app (new) — uvicorn factory entrypoint. RAG_CONFIG_PATH set → build_app_from_config(load(path)); unset/empty → noop build_app(); set-but-broken → fail fast with ConfigError (a typo'd mount crashes the pod loudly, never silently serves noop wiring in production).
  • DockerfileCMD ["uvicorn", "rag_gateway.serve:create_app", "--factory", "--host", "0.0.0.0", "--port", "8000"]; builder + runtime stages copy sdks/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, so ready ⇒ fully constructed. dist/openapi.{json,yaml} + generated docs/reference/rest-api.md regenerated (drift gates green).
  • Helm chart 0.2.0 / appVersion 1.0.1 — ConfigMap renders a minimal valid rag.yaml by default, with a new config.ragYaml values passthrough for complete platform configs; ${VAR} / ${VAR:-default} env interpolation keeps secrets in Secret-injected env vars, out of the ConfigMap. values.dev.yaml env: local.
  • Docs tag fix — image tags publish without the v prefix (docker/metadata-action semver patterns); :v1.0.0-style pulls in README/guides never matched.
  • Pre-existing ruff format drift 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 (/readyz is additive; everything else is a fix).

Verification

  • ruff check + ruff format --check + RAG001 logging gate + mypy --strict (331 files) + full pytest tests/ packages/ apps/ — all green.
  • helm lint + helm template for default values, values.dev.yaml, and a config.ragYaml override — each rendered rag.yaml validated through the real rag_config.loads() (env interpolation exercised: ${RAG_QDRANT_HOST} → resolved URL).
  • Live boots of the exact image CMD: noop mode (/healthz {"status":"ok"}, /readyz {"status":"ready"}, /v1/info 200), config-driven mode (valid rag.yaml via RAG_CONFIG_PATH), broken path (uvicorn exits 1 with ConfigError: config file not found).
  • Docker is not available on this machine, so both Dockerfile sync stages were simulated with uv against the real lockfile: stage 1 (--no-install-workspace, 3 manifests) resolves; stage 2 (full source) failed exactly as the image would (sdks/python missing) and resolves 144 packages incl. rag-gateway/rag-backends/uvicorn after the fix. A real docker build && docker run + helm install smoke test on a Docker-equipped machine is the remaining follow-through, ideally after the Actions billing issue is fixed so docker.yml can 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); /readyz in 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

…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>
@officialCodeWork
officialCodeWork merged commit 47e40f2 into main Jun 10, 2026
13 of 23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant