A three-node cluster with Docker Compose

Start three TeselaDB nodes in containers, join them with enrollment tokens and connect.

This guide sets up a three-node cluster on a single machine with Docker Compose. It is for trying range placement and what happens when a node goes down; in production, each node goes on its own machine.

1. The Compose file

Save this as compose.yaml. Nodes 2 and 3 are in the join profile because they need a token the first one creates.

YAML
services:
  node1:
    image: teseladb/teseladb:<version>
    command: start --dbpath /data --bind_ip 0.0.0.0 --peer-listen 0.0.0.0:27100 --admin-listen 0.0.0.0:27200
    ports: ["27017:27017"]
    volumes: ["node1:/data"]
  node2:
    image: teseladb/teseladb:<version>
    command: >
      start --dbpath /data --bind_ip 0.0.0.0 --peer-listen 0.0.0.0:27100 --admin-listen 0.0.0.0:27200
      --join node1:27100 --enroll-token ${TOKEN_NODE2}
    volumes: ["node2:/data"]
    profiles: ["join"]
  node3:
    image: teseladb/teseladb:<version>
    command: >
      start --dbpath /data --bind_ip 0.0.0.0 --peer-listen 0.0.0.0:27100 --admin-listen 0.0.0.0:27200
      --join node1:27100 --enroll-token ${TOKEN_NODE3}
    volumes: ["node3:/data"]
    profiles: ["join"]
volumes:
  node1:
  node2:
  node3:

2. Start the first node

Shell
docker compose up -d node1

The first start creates the CA and the root user in the node's volume.

3. Create one token per node

Each token is single-use:

Shell
export TOKEN_NODE2=$(docker compose exec node1 teseladb admin --dbpath /data token create --ttl 1h)
export TOKEN_NODE3=$(docker compose exec node1 teseladb admin --dbpath /data token create --ttl 1h)

4. Join the other two

Shell
docker compose --profile join up -d node2 node3
docker compose exec node1 teseladb admin --dbpath /data nodes

5. Connect

Shell
docker compose cp node1:/data/pki/ca.pem ./ca.pem
docker compose exec node1 cat /data/root-credentials.txt
mongosh "mongodb://root:<password>@127.0.0.1:27017/?tls=true&tlsCAFile=./ca.pem"

6. Try a failure

Insert some data, stop a node and check that you can still read and write:

Shell
docker compose stop node2
docker compose exec node1 teseladb admin --dbpath /data ranges

The ranges node2 led have a new leader. When you start it again, it catches up on its own.