feat(deployment): add production-shaped docker-compose sample module - #150
Conversation
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ar51meJEx6UqNR1kFRHn7y
- .gitignore: drop the by-name temp-keystore.p12 entry; the *.p12 pattern two lines above already covers it, and the file argues for pattern-over-name - generate-certificates.sh: collapse the single-use SCRIPT_DIR alias into CERT_DIR directly (it was re-assigned verbatim, no transformation) - wait-for-ready.sh: delete the unreachable empty-SERVICE guard. The embedded Python hard-exits on an empty target set and command substitution strips the trailing newline, so it can never fire -- and had it fired it would have skipped every probe and reported the stack ready, the vacuous green the empty-target hard failure exists to prevent. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ar51meJEx6UqNR1kFRHn7y
There was a problem hiding this comment.
Sorry @cuioss-oliver, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
|
Warning Review limit reached
Next review available in: 30 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Repository: cuioss/coderabbit/.coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (7)
📝 WalkthroughWalkthroughChangesCompose deployment sample
Possibly related PRs
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
PR Reviewer Guide 🔍(Review updated until commit 5b5a68e)
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 2
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository: cuioss/coderabbit/.coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 02c6fcfd-208a-429a-9740-a846ad7ea1e9
⛔ Files ignored due to path filters (1)
doc/resources/diagrams/compose-sample-topology.svgis excluded by!**/*.svg
📒 Files selected for processing (24)
.plan/project-architecture/_project.json.plan/project-architecture/deployment/enriched.jsondeployment/compose-sample/docker-compose.ymldeployment/compose-sample/docker/certificates/.gitignoredeployment/compose-sample/docker/certificates/generate-certificates.shdeployment/compose-sample/docker/keycloak/sample-realm.jsondeployment/compose-sample/docker/nginx/demo-api.confdeployment/compose-sample/docker/sheriff-config/endpoints/demo-api.yamldeployment/compose-sample/docker/sheriff-config/gateway.yamldeployment/compose-sample/docker/sheriff-config/topology.propertiesdeployment/compose-sample/scripts/start-sample.shdeployment/compose-sample/scripts/stop-sample.shdeployment/compose-sample/scripts/wait-for-ready.shdeployment/pom.xmldoc/README.adocdoc/adr/0027-The_token-validation_extensions_unqualified_health_probes_are_excluded_not_accommodated.adocdoc/adr/0032-The_shipped_artifact_declares_nothing_test-shaped_the_deployment_supplies_what_it_names.adocdoc/adr/0033-Absence_in_the_production_type_model_is_a_Nullable_type_not_a_stored_Optional.adocdoc/development/README.adocdoc/development/compose-sample.adocdoc/development/diagram-type-deployment.mddoc/user/README.adocdoc/user/compose-sample.adocpom.xml
Triage dispositionsIn reply to comment_id:
|
…p Keycloak Two CodeRabbit findings on #150. Single-source the gateway image reference. The published default was stated twice — once in docker-compose.yml as an inline ${VAR:-default} fallback and once in start-sample.sh — with only a prose comment asserting the two must match. That contradicts the sample's own ADR-0031 precedent, where wait-for-ready.sh derives its probe target from the resolved Compose model rather than restating it. The default now lives once in a new compose-sample/.env (auto-loaded by Compose); docker-compose.yml references ${API_SHERIFF_IMAGE} with no inline fallback, and start-sample.sh derives the effective value from "compose config --format json". An exported API_SHERIFF_IMAGE still wins, so the documented local-build override is unchanged. Both controls were verified: default resolves from .env, and the export overrides it. Note the suggested patch was not taken verbatim — it placed the derivation above the block that defines COMPOSE_CMD, so as written it would dereference an unset array. The derivation is placed after that block instead. Bump Keycloak 26.5.4 -> 26.5.7 (digest sha256:45ae2019...) in BOTH the sample and integration-tests/docker-compose.yml, keeping the two in lockstep as they were. 26.5.7 is the latest patch in the same minor line — the minimal change that addresses the patch-level concern without pulling two minor versions into the IT suite. The version and digest were read from the quay.io registry API, not taken from the review comment's unverified claim. Verified: sample brings up on the new digest and the gateway answers 200 through the proxy; clean teardown; integration-tests suite green (457s); quality gate green (315s). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ar51meJEx6UqNR1kFRHn7y
Triage dispositionsIn reply to comment_id:
|
|
/review |
…op swallowing teardown failures Two PR-Agent focus areas on #150, both verified against the code before acting. Temporary file leak. generate-certificates.sh creates an intermediate PKCS#12 keystore holding the private key, and removed it only on the success path. Under `set -e` a failing keytool or openssl aborts before that line, stranding the keystore in a directory operators are told to treat as generated-and-disposable. An EXIT trap is now armed immediately after the path is defined, so no failure between that point and the end can escape it; the redundant explicit removal is gone so cleanup has one owner. Verified with matched controls: on the success path no keystore remains; with a forced failure injected after the keystore is created the script aborts (exit 1) and the keystore is still removed. The first negative control attempted — an unknown openssl flag — was discarded because openssl ignored it and the script exited 0, which would have proven nothing. Swallowed teardown errors. The stop-sample-pre-clean and stop-sample-post-integration-test executions accepted exit code 1 as success, with a comment claiming "nothing running is the normal case". That premise is wrong: `docker compose down` is idempotent and exits 0 on an empty project (verified directly), and stop-sample.sh already returns 0 explicitly for a host with no Compose and for a stopped daemon. So exit 1 could only ever mean a teardown that genuinely failed — and accepting it would report a green build over a leaked stack, which is the exact port-conflict-looking-like-a-defect the pre-clean execution exists to prevent. Both overrides removed, with the reasoning recorded in place of the incorrect comment. Verified: `verify -Pcompose-sample -pl deployment -am` green (25s) with the overrides removed, so teardown really does return 0; quality gate green (374s). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ar51meJEx6UqNR1kFRHn7y
Triage dispositionsIn reply to comment_id:
|
|
/review |
Review closureAnswering the two remaining bot messages, both of which are rate-limit refusals rather than change requests, and recording the review coverage this PR actually got. Sourcery ( CodeRabbit (
It did not review the two subsequent fix commits ( Coverage the fix commits did get:
|
Summary
Adds a new top-level
deployment/Maven module carrying a production-shaped docker-compose sample — the artifact a 0.1.0 adopter copies to run API Sheriff — together with its user/developer documentation layers and an SVG deployment diagram. Also folds in an unrelated but urgent ADR-renumbering fix as the first commit.Changes
ADR renumbering (first commit, cherry-pickable)
doc/adr/0032-The_shipped_artifact_declares_nothing_test-shaped_the_deployment_supplies_what_it_names.adocanddoc/adr/0033-Absence_in_the_production_type_model_is_a_Nullable_type_not_a_stored_Optional.adoc, each with its internal= ADR-00NN:title line retargeted.doc/adr/0027-The_token-validation_extensions_unqualified_health_probes_are_excluded_not_accommodated.adocso the rename does not ship broken links.Module skeleton and reactor registration
deployment/pom.xml— packaging pom with the Java plugins skipped, mirroring theintegration-tests/anddemo-client/shape. Carries the opt-incompose-sampleprofile that runs the sample end to end.pom.xml— registersdeploymentin the root reactor.The compose sample
deployment/compose-sample/docker-compose.yml— gateway + Keycloak + one realistic upstream (a staticnginx:alpinedemo API), with the runtime hardening reused from the IT stack (security_opt: [no-new-privileges:true],cap_drop,read_only: true) applied per service. The gateway image is a pinned GHCR tag with a documented local-build override.deployment/compose-sample/docker/sheriff-config/gateway.yaml,.../topology.properties,.../endpoints/demo-api.yaml— the gateway configuration the sample runs on.deployment/compose-sample/docker/nginx/demo-api.conf— the canned upstream response, so the topology reads as "your API goes here".deployment/compose-sample/docker/keycloak/sample-realm.json— sample realm. Credentials are unmistakably sample-only and documented as must-change-before-production.deployment/compose-sample/docker/certificates/generate-certificates.shand.../certificates/.gitignore— local TLS material generated, never committed.Readiness gate
deployment/compose-sample/scripts/wait-for-ready.sh— host-side readiness gate following ADR-0031's shape: derives the probe target (published port + scheme) fromcompose config --format json, probes/q/health/ready, and fails loudly with adocker compose logshint. The gateway service deliberately carries nohealthcheck:(the distroless image ships neither a shell nor curl); Keycloak carries a curl-free/dev/tcpTCP probe and the gateway is ordered behind it.deployment/compose-sample/scripts/start-sample.shand.../stop-sample.sh— lifecycle wrappers wired to thecompose-sampleprofile, so the sample is activated rather than merely committed.Documentation and diagram
doc/user/compose-sample.adoc(operator layer, primary) anddoc/development/compose-sample.adoc.doc/resources/diagrams/compose-sample-topology.svg— authored to the shipped deployment-diagram template, render-and-read-back verified in both light and dark backgrounds.doc/README.adoc,doc/user/README.adoc,doc/development/README.adoc,doc/development/diagram-type-deployment.md— index and template updates.Plan artifacts
.plan/project-architecture/_project.json,.plan/project-architecture/deployment/enriched.json— architecture inventory updated for the new module.Test Plan
verify -Ppre-commit)verify)docker compose -f deployment/compose-sample/docker-compose.yml config -q)verify -Pcompose-sample -pl deployment -am) — the stack comes up andwait-for-ready.shasserts readinessmanage-adr scanreports 33 distinct ADR numbers with no duplicatesRelated Issues
None.
Generated by plan-finalize skill
Intent
Problem. A 0.1.0 adopter had nothing to copy. The only running compose topology in the tree is
integration-tests/docker-compose.yml, which is test scaffolding (toxiproxy, go-httpbin, passthrough origins) and misleads anyone who mistakes it for a deployment reference. There was no production-shaped sample, and no operator-facing document describing how to stand the gateway up.Approach. One new
deployment/module holding exactly one subtree,compose-sample/: gateway + Keycloak + a single static nginx upstream that reads as "your API goes here". Hardening (no-new-privileges,cap_drop,read_only) is reused from the IT stack rather than reinvented. Readiness is host-side per ADR-0031 — the gateway's distroless image ships neither a shell nor curl, so a composehealthcheck:on it is impossible, not merely awkward; that absence is recorded in-file so a reviewer reads it as deliberate. The readiness script derives its probe target fromcompose config --format jsonrather than restating host port or scheme, and probes/q/health/ready, not liveness. The sample is wired to an opt-incompose-sampleMaven profile so it is activated, not merely committed — a YAML lint would not have caught a stack that does not come up.TLS is configured through
QUARKUS_HTTP_SSL_CERTIFICATE_FILES/QUARKUS_MANAGEMENT_SSL_CERTIFICATE_FILESand their_KEY_FILESpeers.[Intent truncated — 1396 of 2189 characters shown; full outline in the plan workspace]
Non-goals (deliberately out of scope — please do not report these as gaps).
deployment/helm/, noChart.yaml, novalues.yaml, no chart CI job, and no Kubernetes deployment diagram. This was split out by operator decision on 2026-08-02 and moved to theapi-sheriff-nextroadmap (PLAN-41). The alpha ships compose. It was removed deliberately, not overlooked.api-sheriff/src/main/java/**change. The sample is configuration and documentation only. If the sample could only be made to work by changing gateway code, that is a finding about the config model to report — not something to patch here.integration-tests/docker-compose.ymlis referenced as prior art for runtime hardening and the Keycloak shape only. Its backends (toxiproxy, go-httpbin, nginx passthrough, asset origin, gRPC echo) are test scaffolding and are intentionally absent from the sample. This PR does not restructure the IT stack.doc/README.adocADR-index backfill. That table stops at ADR-0019 while the corpus now runs to ADR-0033. Neither renamed ADR appears in it, so the renumbering in this PR breaks no link there. Backfilling the 14 missing rows is separate work.Summary by CodeRabbit
New Features
Documentation