Skip to content

Setting Up a Redis Cluster with Docker

This guide demonstrates how to set up a Redis cluster using Docker with three individual Redis containers.

Prerequisites

  • Docker installed on your system
  • Docker Compose (optional but recommended)
  • Basic understanding of Redis concepts
  • Basic knowledge of Docker networking

Overview

We'll create a three-node Redis cluster with the following characteristics:

  • Each node will run in its own container
  • The nodes will communicate with each other over a shared network
  • Cluster mode will be enabled for Redis
  • Each node will have a primary role with replicas configured automatically

Setup

Step 1: Create a Docker Network

First, create a dedicated Docker network for your Redis cluster:

bash
docker network create redis-cluster

Step 2: Create Configuration Files

Create a directory for Redis configuration:

bash
mkdir -p redis-cluster/config

Create a base configuration file redis-cluster/config/redis-base.conf:

port 6379
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
protected-mode no

Create configuration files for each node:

bash
# Node 1
cat > redis-cluster/config/redis-1.conf << EOF
port 6379
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 5000
appendonly yes
protected-mode no
EOF

# Node 2
cat > redis-cluster/config/redis-2.conf << EOF
port 6379
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 5000
appendonly yes
protected-mode no
EOF

# Node 3
cat > redis-cluster/config/redis-3.conf << EOF
port 6379
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 5000
appendonly yes
protected-mode no
EOF

Step 3: Create Docker Compose File

Create a redis-cluster/docker-compose.yml file with the following content:

yaml
version: "3.8"

services:
  redis1:
    image: redis:7.0-alpine
    container_name: redis1
    command: redis-server /usr/local/etc/redis/redis.conf
    volumes:
      - ./config/redis-1.conf:/usr/local/etc/redis/redis.conf
      - redis1-data:/data
    ports:
      - "6379:6379"
      - "16379:16379"
    networks:
      redis-cluster:
        ipv4_address: 172.28.0.11

  redis2:
    image: redis:7.0-alpine
    container_name: redis2
    command: redis-server /usr/local/etc/redis/redis.conf
    volumes:
      - ./config/redis-2.conf:/usr/local/etc/redis/redis.conf
      - redis2-data:/data
    ports:
      - "6380:6379"
      - "16380:16379"
    networks:
      redis-cluster:
        ipv4_address: 172.28.0.12

  redis3:
    image: redis:7.0-alpine
    container_name: redis3
    command: redis-server /usr/local/etc/redis/redis.conf
    volumes:
      - ./config/redis-3.conf:/usr/local/etc/redis/redis.conf
      - redis3-data:/data
    ports:
      - "6381:6379"
      - "16381:16379"
    networks:
      redis-cluster:
        ipv4_address: 172.28.0.13

networks:
  redis-cluster:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.28.0.0/16

volumes:
  redis1-data:
  redis2-data:
  redis3-data:

Step 4: Start the Containers

Start all Redis containers:

bash
cd redis-cluster
docker-compose up -d

Step 5: Create the Cluster

Once all containers are running, create the Redis cluster:

bash
docker exec -it redis1 redis-cli --cluster create 172.28.0.11:6379 172.28.0.12:6379 172.28.0.13:6379 --cluster-replicas 0

When prompted, type "yes" to accept the configuration.

Step 6: Verify the Cluster Status

Check the cluster status:

bash
docker exec -it redis1 redis-cli cluster info

And check the nodes:

bash
docker exec -it redis1 redis-cli cluster nodes

Alternative Setup: Using Standalone Docker Commands

If you prefer not to use Docker Compose, you can set up the cluster using standalone Docker commands:

Step 1: Create a Docker Network

bash
docker network create --subnet=172.28.0.0/16 redis-cluster

Step 2: Start the Redis Nodes

bash
# Start Redis Node 1
docker run -d \
  --name redis1 \
  --net redis-cluster \
  --ip 172.28.0.11 \
  -v $(pwd)/config/redis-1.conf:/usr/local/etc/redis/redis.conf \
  -p 6379:6379 \
  -p 16379:16379 \
  redis:7.0-alpine \
  redis-server /usr/local/etc/redis/redis.conf

# Start Redis Node 2
docker run -d \
  --name redis2 \
  --net redis-cluster \
  --ip 172.28.0.12 \
  -v $(pwd)/config/redis-2.conf:/usr/local/etc/redis/redis.conf \
  -p 6380:6379 \
  -p 16380:16379 \
  redis:7.0-alpine \
  redis-server /usr/local/etc/redis/redis.conf

# Start Redis Node 3
docker run -d \
  --name redis3 \
  --net redis-cluster \
  --ip 172.28.0.13 \
  -v $(pwd)/config/redis-3.conf:/usr/local/etc/redis/redis.conf \
  -p 6381:6379 \
  -p 16381:16379 \
  redis:7.0-alpine \
  redis-server /usr/local/etc/redis/redis.conf

Step 3: Create the Cluster

bash
docker exec -it redis1 redis-cli --cluster create 172.28.0.11:6379 172.28.0.12:6379 172.28.0.13:6379 --cluster-replicas 0

Working with Redis Cluster

Connect to the Cluster

You can connect to any node in the cluster:

bash
docker exec -it redis1 redis-cli -c

The -c flag enables cluster mode for the Redis CLI, which means it will follow redirections automatically.

Test the Cluster

Set a key:

bash
docker exec -it redis1 redis-cli -c set mykey "Hello Redis Cluster"

Get the key:

bash
docker exec -it redis2 redis-cli -c get mykey

Add More Hash Slots (Scaling the Cluster)

If you want to add more hash slots to the cluster:

bash
# Add a fourth node
docker run -d \
  --name redis4 \
  --net redis-cluster \
  --ip 172.28.0.14 \
  -v $(pwd)/config/redis-4.conf:/usr/local/etc/redis/redis.conf \
  -p 6382:6379 \
  -p 16382:16379 \
  redis:7.0-alpine \
  redis-server /usr/local/etc/redis/redis.conf

# Add the node to the cluster
docker exec -it redis1 redis-cli --cluster add-node 172.28.0.14:6379 172.28.0.11:6379

# Rebalance the cluster
docker exec -it redis1 redis-cli --cluster rebalance 172.28.0.11:6379

Adding Replicas for High Availability

To add replicas for high availability:

bash
# Add a replica for the first node
docker exec -it redis1 redis-cli --cluster add-node 172.28.0.15:6379 172.28.0.11:6379 --cluster-slave --cluster-master-id <MASTER_NODE_ID>

Replace <MASTER_NODE_ID> with the ID of the master node, which you can get from redis-cli cluster nodes.

Redis Cluster with Replication

To set up a Redis cluster with replication from the beginning:

bash
docker exec -it redis1 redis-cli --cluster create 172.28.0.11:6379 172.28.0.12:6379 172.28.0.13:6379 172.28.0.14:6379 172.28.0.15:6379 172.28.0.16:6379 --cluster-replicas 1

This creates a cluster with 3 masters and 3 replicas (one replica per master).

Troubleshooting

Cluster Creation Fails

If cluster creation fails, check that:

  1. All Redis nodes have cluster mode enabled
  2. The nodes can communicate with each other over the network
  3. The IP addresses are correctly set
  4. There are no existing cluster configuration files

Checking Logs

Check logs of the Redis containers:

bash
docker logs redis1
docker logs redis2
docker logs redis3

Resetting the Cluster

If you need to reset and recreate the cluster:

bash
# Stop and remove the containers
docker-compose down

# Remove volumes
docker volume rm redis-cluster_redis1-data redis-cluster_redis2-data redis-cluster_redis3-data

# Start the containers again
docker-compose up -d

# Recreate the cluster
docker exec -it redis1 redis-cli --cluster create 172.28.0.11:6379 172.28.0.12:6379 172.28.0.13:6379 --cluster-replicas 0

Monitoring the Cluster

You can use Redis Commander or RedisInsight to monitor your Redis cluster.

Using Redis Commander

bash
docker run --rm -it --name redis-commander \
  --network redis-cluster \
  -e REDIS_HOSTS=redis1:172.28.0.11:6379,redis2:172.28.0.12:6379,redis3:172.28.0.13:6379 \
  -p 8081:8081 \
  rediscommander/redis-commander:latest

Then open a browser and navigate to http://localhost:8081.

Cleanup

To stop and remove all containers, networks, and volumes:

bash
docker-compose down -v

Or if using standalone commands:

bash
docker stop redis1 redis2 redis3
docker rm redis1 redis2 redis3
docker network rm redis-cluster

Advanced Configuration

Redis Persistence

For production use, you may want to configure persistence. Redis offers two options:

  1. RDB (Redis Database): Point-in-time snapshots
  2. AOF (Append Only File): Logs every write operation

You can enable both in your configuration files:

appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec

save 900 1
save 300 10
save 60 10000

Security

For production, enable Redis security:

requirepass your_strong_password
masterauth your_strong_password

Remember to update your docker-compose.yml or Docker run commands to include this configuration.

Resources