Quick start¶
Prerequisites¶
- Go 1.26+
- (Optional) Docker
Build & run a standalone node¶
git clone https://github.com/futureq-io/futureq.git
cd futureq
go build -o futureq ./cmd/futureq
cp config.example.yaml config.yaml # adjust as needed
./futureq start -c config.yaml
A standalone node (cluster.enabled: false) writes directly to Pebble with a synchronous fsync per publish batch — perfect for local development. See the gRPC API page for how to talk to it.
Run a 3-node cluster¶
On the first node, enable clustering and list its bootstrap member. Use addresses that other nodes and clients can reach:
api:
grpc:
advertise: "10.0.0.1:8443"
cluster:
enabled: true
nodeId: 1
shardId: 1
raft:
advertise: "10.0.0.1:50005"
initialMembers:
1: "10.0.0.1:50005"
For each additional node, give it a unique cluster.nodeId, its own api.grpc.advertise and cluster.raft.advertise, and a seed address. For example, node 2 uses:
api:
grpc:
advertise: "10.0.0.2:8443"
cluster:
enabled: true
nodeId: 2
raft:
advertise: "10.0.0.2:50005"
joinSeeds:
- "10.0.0.1:8443"
The --join flag overrides cluster.joinSeeds for one start:
./futureq start -c node2.yaml --join 10.0.0.1:8443
./futureq start -c node3.yaml --join 10.0.0.1:8443
Join flow
On first start the joining node contacts each seed until one accepts its JoinCluster request. Membership is registered on both the event shard and the metadata group — first as a non-voting member that catches up, then promoted to voter. Restarts detect local Raft data and skip the join flow automatically. cluster.raft.initialMembers and cluster.joinSeeds cannot both be set in a config file.
Docker¶
docker build -t futureq .
docker run -p 8443:8443 -p 9090:9090 -p 50005:50005 \
-v $(pwd)/config.yaml:/app/config.yaml \
futureq start -c /app/config.yaml