M19 — operational hardening: Docker cluster, observability stack, chaos tests#5
Merged
Merged
Conversation
…, chaos tests) Make the POC runnable and demoable as a real multi-node cluster, and exercise the HTTP transport that nothing tested before. Operational only — no consensus-core changes. Docker / cluster: - Multi-stage Dockerfile (build on node:20 → prod-pruned run on node:20-slim) and a .dockerignore. - docker-compose.yml: a 3-node book-service cluster wired via NODE_ID/PORT/PEERS/ ADVERTISE_URL/DATA_DIR (PEERS excludes self, ADVERTISE_URL uses compose DNS), named per-node volumes, and a /ready healthcheck. Observability stack: - Prometheus (deploy/prometheus.yml) scraping all three nodes' /metrics; avoids a target `node` label since the app already emits node="<id>". - Grafana provisioning (datasource + dashboard provider) and a raft-cluster dashboard wired to the real metric names: leadership/cluster size, commit/apply progress, elections, replication lag, HTTP throughput/p95 latency, read barriers and follower reads. Fault-injection over the REAL HttpTransport: - tests/chaos.test.ts spins up a 3-node cluster on actual HTTP sockets (two-pass ephemeral-port allocation, stdlib http client, no new deps) and covers: single leader election, replicated write readable on another node, leader-failure recovery + new commit, partition tolerance (majority commits / isolated minority cannot, then heals), and a strong (ReadIndex) read — with teardown that stops every node and closes every server. Docs: docs/OPERATIONS.md (run the cluster, hit the API, change membership, scrape metrics, open Grafana) plus a README pointer. Verified: tsc --noEmit clean; chaos suite stable across repeated runs; full suite green (25 suites / 201 tests). `docker compose config` validates; an end-to-end image build/boot was not run (no Docker daemon in CI sandbox). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01NneoGGKxBp5ZExL7D7i1Lu
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.
Summary
Makes the POC runnable and demoable as a real multi-node cluster, and exercises the HTTP transport that nothing tested before. Operational only — no consensus-core changes. Builds on the merged M11–M18 work (#4).
Docker / cluster
Dockerfile(build onnode:20→ prod-pruned run onnode:20-slim) +.dockerignore.docker-compose.yml: a 3-node book-service cluster wired viaNODE_ID/PORT/PEERS/ADVERTISE_URL/DATA_DIR(PEERS excludes self, ADVERTISE_URL uses compose DNS names), named per-node volumes, and a/readyhealthcheck.Observability stack
deploy/prometheus.yml) scraping all three nodes'/metrics— avoids a targetnodelabel since the app already emitsnode="<id>".raft-clusterdashboard wired to the real metric names: leadership/cluster size, commit/apply progress, elections, replication lag, HTTP throughput + p95 latency, read barriers and follower reads.Fault-injection over the real
HttpTransporttests/chaos.test.tsspins up a 3-node cluster on actual HTTP sockets (two-pass ephemeral-port allocation, stdlibhttpclient, no new deps) and covers:--detectOpenHandles --forceExit).Docs
docs/OPERATIONS.md(run the cluster, hit the API, change membership, scrape metrics, open Grafana) + a README pointer.Verification
npx tsc --noEmitclean.docker compose configvalidates and the Grafana dashboard JSON parses.docker compose up --build(image build + cluster boot) was not run — no Docker daemon in the sandbox. Worth a local smoke test.🤖 Generated with Claude Code
Generated by Claude Code