Skip to content

feat(infra): add Kafka + Schema Registry + Vault behind distributed profile#83

Merged
phuongnse merged 2 commits into
mainfrom
feat/dev-stack-kafka-vault
May 23, 2026
Merged

feat(infra): add Kafka + Schema Registry + Vault behind distributed profile#83
phuongnse merged 2 commits into
mainfrom
feat/dev-stack-kafka-vault

Conversation

@phuongnse

@phuongnse phuongnse commented May 23, 2026

Copy link
Copy Markdown
Owner

Summary

Phase 1 PR #1 of the modulith-with-strict-service-boundaries rollout (ADR-010). Adds the three infrastructure services the new architecture contract depends on, behind the Compose distributed profile so the default dev stack stays light.

Service Image Host port ADR
Kafka (KRaft, single broker) confluentinc/cp-kafka:7.7.0 29092 (host), 9092 (in-network) ADR-013
Schema Registry confluentinc/cp-schema-registry:7.7.0 8081 ADR-019
Vault (dev mode) hashicorp/vault:1.18 8200 ADR-022

Usage:

docker compose up                            # default stack (postgres, redis, …)
docker compose --profile distributed up      # adds kafka, schema-registry, vault

The distributed profile will be removed once Phase 1 PR #2 wires WolverineFx.Kafka into the app — at that point the services become as mandatory as Postgres.

Decisions

  • KRaft mode (no ZooKeeper) — modern Kafka default, simpler ops, fewer containers.
  • Confluent CP images — pairs natively with Confluent Schema Registry; Community License is free for the single-broker setup we run.
  • Vault dev mode with fixed root token (axis-dev-root-token) — in-memory, restart wipes secrets. Acceptable for dev; production uses a separately-provisioned Vault cluster (per ADR-022).
  • Fixed Kafka cluster ID — KRaft metadata survives container recreate so docker compose down && up doesn't blow away topics.
  • Schema Registry BACKWARD-only compatibility — breaking schema changes require explicit override at publish time, matching the strict-evolution stance in ADR-019.

What this PR does NOT do

Requirements & rules followed

  • Spec → code — infrastructure-only change, no AC delivery
  • Gate 0 — N/A
  • Gate 1 — N/A: no src/, tests/, or frontend/ change. docker compose config not run locally (Docker CLI not installed on my Windows shell); CI doesn't currently validate compose either. Worst case: dev runs docker compose --profile distributed up and sees the error
  • Gate 2./scripts/check-doc-drift.sh N/A. CONTRIBUTING.md updated with a short "Local dev stack" section pointing at the new services
  • Gate 3 — no new durable rule; ADR-013/019/022 already specify the contract
  • No new TODO / FIXME / placeholder / stub

Summary by CodeRabbit

  • Documentation

    • Added a "Local dev stack" section with step-by-step instructions for running the default and optional distributed development setups, host/port guidance, compatibility and token notes, and a deprecation note for the distributed profile.
  • Chores

    • Introduced an opt-in distributed development profile that brings local Kafka, Schema Registry, and Vault services with data persistence and health checks.

Review Change Stack

…rofile

Phase 1 PR #1 of the modulith-with-strict-service-boundaries rollout
(ADR-010). Adds the three infrastructure services the architecture
contract depends on:

- Kafka (confluentinc/cp-kafka:7.7.0, KRaft mode, single broker) —
  cross-module event transport per ADR-013. Two listeners: PLAINTEXT
  on :9092 for other containers, PLAINTEXT_HOST on :29092 for processes
  on the host. Fixed cluster ID so KRaft metadata survives recreate.
- Schema Registry (confluentinc/cp-schema-registry:7.7.0) — Avro schema
  evolution per ADR-019, BACKWARD-only compatibility default.
- Vault (hashicorp/vault:1.18, dev mode) — secrets management surface
  per ADR-022. In-memory only — matches "dev convenience, prod is a
  separate cluster" stance in the ADR.

All three live behind the Compose `distributed` profile so a default
`docker compose up` stays light. Opt in with `--profile distributed`.
The profile will be removed once the first module's outbox publishes
to Kafka (Phase 1 PR #2 — WolverineFx.Kafka transport wiring).

No application code change; no `src/` / `tests/` impact. CONTRIBUTING.md
gets a short "Local dev stack" section pointing at the new services
and their host ports.
@coderabbitai

coderabbitai Bot commented May 23, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 88edf0cf-021f-40d0-a4b2-a289fe4f2d4a

📥 Commits

Reviewing files that changed from the base of the PR and between f6112cb and 0bd6fbb.

📒 Files selected for processing (1)
  • docker-compose.yml

📝 Walkthrough

Walkthrough

Adds an opt-in distributed Compose profile that starts Kafka, Schema Registry, and Vault, and documents how to run the local dev stack and the distributed profile in CONTRIBUTING.md.

Changes

Distributed Infrastructure Services

Layer / File(s) Summary
Distributed services and volume configuration
docker-compose.yml
Kafka is configured for single-broker KRaft operation with listener/advertised-listener configuration and healthcheck, Schema Registry depends on healthy Kafka and enforces BACKWARD schema compatibility, Vault runs in dev mode with IPC_LOCK and a healthcheck, and a kafka_data named volume persists Kafka state. All services live under the distributed profile.
Local dev stack documentation
CONTRIBUTING.md
Adds a “Local dev stack” section describing docker compose up vs --profile distributed up, a host-port/role table for Kafka, Schema Registry, and Vault, notes about Schema Registry compatibility, Vault dev root token/in-memory behavior, and a note that the distributed profile will be removed after the first module publishes to Kafka.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A rabbit nudges compose with cheer,
Kafka, Schema, Vault appear,
Profiles toggled, ports align,
Dev tokens hum, registries bind,
Local stacks ready — sip the gear! 🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: adding three infrastructure services (Kafka, Schema Registry, Vault) behind a distributed Docker Compose profile. It is concise, specific, and aligns with the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/dev-stack-kafka-vault

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docker-compose.yml`:
- Around line 98-99: Remove the unnecessary host port mapping "9092:9092" from
docker-compose.yml so only the intended host-exposed listener "29092:29092"
remains; edit the service's ports section to delete the entry matching
"9092:9092" (leaving "29092:29092") to avoid binding host port 9092 and
accidental mis-bootstrap or startup conflicts.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 29dbd3d5-0c84-4c4b-a473-a1511afe4900

📥 Commits

Reviewing files that changed from the base of the PR and between 04c84f5 and f6112cb.

📒 Files selected for processing (2)
  • CONTRIBUTING.md
  • docker-compose.yml

Comment thread docker-compose.yml Outdated
CodeRabbit flagged that both `9092:9092` and `29092:29092` were
mapped to the host even though the inline comment said `9092` was
"not used from host". Two real problems:

- Avoidable port-9092 collisions on dev machines (Mosquitto, jellyfin,
  many tools claim that port).
- Mis-bootstrap risk: a process connecting to `localhost:9092` would
  receive `kafka:9092` as the advertised listener, which only resolves
  inside the Compose network. Failure mode is confusing.

Keep only the `29092:29092` mapping. Inside the Compose network
containers continue to reach Kafka at `kafka:9092` via the in-network
listener, which is intentionally not published.
@phuongnse phuongnse merged commit bf5f3b1 into main May 23, 2026
6 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