Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Run a three-node cluster locally

In this tutorial you run a real three-node Raft cluster on one machine, publish to it, read from a different node, and watch it stay up when the leader stops. It uses loopback addresses and separate data directories, so nothing conflicts. You need a boatramp binary built with the cluster feature.

For the production version of this, see Deploy a self-hosted cluster.

1. Write three configs

Each node gets its own boatramp.cfg: a distinct node_id, serve port, mesh listen port, and store_dir. All three list the same peers and voters. Only node 1 sets bootstrap.

node1.cfg:

(
    serve: ( addr: "127.0.0.1:8001", data_dir: "/tmp/br1" ),
    cluster: (
        node_id: 1,
        listen: "127.0.0.1:7001",
        bootstrap: true,
        voters: [1, 2, 3],
        store_dir: "/tmp/br1/raft",
        peers: {
            "1": (url: "https://127.0.0.1:7001", pubkey: "…node-1…"),
            "2": (url: "https://127.0.0.1:7002", pubkey: "…node-2…"),
            "3": (url: "https://127.0.0.1:7003", pubkey: "…node-3…"),
        },
    ),
)

node2.cfg and node3.cfg are identical except serve.addr (127.0.0.1:8002 / :8003), data_dir (/tmp/br2 / /tmp/br3), node_id (2 / 3), listen (:7002 / :7003), store_dir — and they omit bootstrap.

2. Collect the mesh public keys

The peer mesh runs over raw-public-key mutual TLS, so each node must know the others’ keys. Start each node once to generate and log its key:

boatramp serve --config node1.cfg
mesh identity ed25519:9f86d081… (/tmp/br1/mesh/identity.key)
cluster listen 127.0.0.1:7001 — waiting for peers [2, 3]

Do the same for node2.cfg and node3.cfg, copy each logged pubkey into the peers map of all three configs, then stop the nodes.

3. Bring up the cluster

Start node 1 (the bootstrap node) first, then 2 and 3, each in its own terminal:

boatramp serve --config node1.cfg
boatramp serve --config node2.cfg
boatramp serve --config node3.cfg

Confirm membership and the leader:

boatramp status --server https://127.0.0.1:8001
cluster: 3 nodes, leader = 1, term 3
node 1  voter  applied 12
node 2  voter  applied 12
node 3  voter  applied 12

4. Publish to one node, read from another

Writes forward to the leader; every node serves reads from its applied state. Publish to node 1 and read the same content from node 3:

boatramp sync ./site --site my-site --server https://127.0.0.1:8001
curl https://127.0.0.1:8003/

my-site is the only site, so every node serves it at the root. The page served from node 3 is the deployment you published to node 1 — the write replicated through Raft.

5. Watch it survive a leader loss

Stop node 1 (Ctrl-C its terminal). The remaining two nodes still have a quorum, so they elect a new leader. Ask a survivor:

boatramp status --server https://127.0.0.1:8002
cluster: 3 nodes, leader = 2, term 4
node 2  voter  applied 12
node 3  voter  applied 12
node 1  down

Reads and writes continue against the new leader. Restart node 1 and it rejoins and catches up from the log.