feat(raft): RAFT_* env vars + 3-node compose template#588
Merged
Conversation
Operationally, raft was hard to deploy: cfg.Raft was YAML-only, and
deploy/docker-compose had no template for a multi-node raft cluster.
This commit closes both gaps.
### RAFT_* env var bindings
pkg/config/config.go gains overrides for every cfg.Raft field that
operators tune:
- RAFT_ENABLED (bool)
- RAFT_SELF_ID (string)
- RAFT_BIND_ADDR (string, e.g. ":7000")
- RAFT_BOOTSTRAP (bool)
- RAFT_PEERS ("id=host:port,id=host:port,...")
- RAFT_HEARTBEAT_MS, RAFT_ELECTION_MS, RAFT_LEADER_LEASE_MS,
RAFT_COMMIT_MS, RAFT_APPLY_TIMEOUT_SECONDS (int)
RAFT_PEERS uses the same "id=addr,id=addr" shape as CLUSTER_NODES so
manifests look uniform. Malformed entries (no '=', empty id, etc.)
are silently dropped.
### Compose template
New deploy/docker-compose/raft-cluster/{compose.yaml,README.md}:
- 3 codeq services (node-a/b/c) on host ports 8080/8081/8082
- All three share a YAML anchor for the common env; only RAFT_SELF_ID,
RAFT_BIND_ADDR, and RAFT_BOOTSTRAP differ
- node-a has Bootstrap=true; the others wait via `depends_on` so
node-a's transport is listening before they try to join
- Per-node Pebble + artifacts volumes (no shared state)
- Bridge network with docker DNS resolution between peers
README walks through quick-start, status endpoint probing, failover
testing (kill leader, wait ~2s, verify new leader on a survivor), and
the path to multi-shard raft via PERSISTENCE_CONFIG.numShards.
### Tests
- TestLoadConfigOptional_RaftEnvOverrides: every RAFT_* env var lands
on the right cfg.Raft field.
- TestLoadConfigOptional_RaftDisabledByDefault: no env means
cfg.Raft.Enabled stays false.
- TestLoadConfigOptional_RaftPeersIgnoresMalformed: malformed peer
entries are dropped without failing the load.
This was referenced May 18, 2026
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
Operationally, raft was hard to deploy: `cfg.Raft` was YAML-only (no env-var overrides) and `deploy/docker-compose/` had no template for a multi-node raft cluster. Closes both gaps.
What landed
RAFT_* env var bindings
`pkg/config/config.go` gains overrides for every `cfg.Raft` field that operators tune:
Malformed peer entries (no `=`, empty id, etc.) are silently dropped so a typo doesn't crash startup.
Compose template
New `deploy/docker-compose/raft-cluster/{compose.yaml,README.md}`:
README walks through quick-start, status endpoint probing, failover testing, and the path to multi-shard raft.
Test plan
🤖 Generated with Claude Code