Building Redis Cluster with docker-compose

Pierre Abreu
3 min readMay 29, 2021

--

Redis is very notorious key-value store, very fast and stable. However, there are some situations which we need real time applications and scale up our application in some high traffic moments.

Bellow I paste my final docker-compose file and to explain some important parts. In that case, my application is build on NodeJS with MariaDb.

version: '3.5'services:
app:
build:
context: ./
dockerfile: Dockerfile
ports:
- 3000:3000
environment:
REDIS_NODE_1: redis-node-1:6373
REDIS_NODE_2: redis-node-2:6374
REDIS_NODE_3: redis-node-3:6375
REDIS_NODE_4: redis-node-4:6376
REDIS_NODE_5: redis-node-5:6377
REDIS_NODE_6: redis-node-6:6378
volumes:
- '.:/usr/src/app'
- nodemodules:/usr/local/app/node_modules
networks:
app_subnet:
ipv4_address: 172.20.0.10
depends_on:
- db
- redis-cluster
db:
image: mariadb
restart: always
environment:
MYSQL_ROOT_PASSWORD: feedback
MYSQL_DATABASE: feedback
MYSQL_USER: feedback
MYSQL_PASSWORD: feedback
volumes:
- db-data:/var/lib/mysql
ports:
- 3306:3306
networks:
app_subnet:
ipv4_address: 172.20.0.20
redis-cluster:
image: 'redis:6.0-alpine'
command: redis-cli --cluster create 172.20.0.31:6373 172.20.0.32:6374 172.20.0.33:6375 172.20.0.34:6376 172.20.0.35:6377 172.20.0.36:6378 --cluster-replicas 1 --cluster-yes
networks:
app_subnet:
ipv4_address: 172.20.0.30
depends_on:
- redis-node-1
- redis-node-2
- redis-node-3
- redis-node-4
- redis-node-5
- redis-node-6
redis-node-1:
image: 'redis:6.0-alpine'
command: redis-server /usr/local/etc/redis/redis.conf
ports:
- '6373:6373'
volumes:
- redis-node-1-data:/var/lib/redis
- ./docker/redis-node-1.conf:/usr/local/etc/redis/redis.conf
networks:
app_subnet:
ipv4_address: 172.20.0.31
redis-node-2:
image: 'redis:6.0-alpine'
command: redis-server /usr/local/etc/redis/redis.conf
ports:
- '6374:6374'
volumes:
- redis-node-2-data:/var/lib/redis
- ./docker/redis-node-2.conf:/usr/local/etc/redis/redis.conf
networks:
app_subnet:
ipv4_address: 172.20.0.32
redis-node-3:
image: 'redis:6.0-alpine'
command: redis-server /usr/local/etc/redis/redis.conf
ports:
- '6375:6375'
volumes:
- redis-node-3-data:/var/lib/redis
- ./docker/redis-node-3.conf:/usr/local/etc/redis/redis.conf
networks:
app_subnet:
ipv4_address: 172.20.0.33
redis-node-4:
image: 'redis:6.0-alpine'
command: redis-server /usr/local/etc/redis/redis.conf
ports:
- '6376:6376'
volumes:
- redis-node-4-data:/var/lib/redis
- ./docker/redis-node-4.conf:/usr/local/etc/redis/redis.conf
networks:
app_subnet:
ipv4_address: 172.20.0.34
redis-node-5:
image: 'redis:6.0-alpine'
command: redis-server /usr/local/etc/redis/redis.conf
ports:
- '6377:6377'
volumes:
- redis-node-5-data:/var/lib/redis
- ./docker/redis-node-5.conf:/usr/local/etc/redis/redis.conf
networks:
app_subnet:
ipv4_address: 172.20.0.35
redis-node-6:
image: 'redis:6.0-alpine'
command: redis-server /usr/local/etc/redis/redis.conf
ports:
- '6378:6378'
volumes:
- redis-node-6-data:/var/lib/redis
- ./docker/redis-node-6.conf:/usr/local/etc/redis/redis.conf
networks:
app_subnet:
ipv4_address: 172.20.0.36
volumes:
db-data:
redis-node-1-data:
redis-node-2-data:
redis-node-3-data:
redis-node-4-data:
redis-node-5-data:
redis-node-6-data:
nodemodules:
networks:
app_subnet:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/24

1 —Static IP

Static IP is required because redis-cluster doesn't works with domains. In that case, I have to create a docker subnet network to make all redis nodes together in the same network

In addition, I have to set port for each redis node to avoid port collision inside docker network.

Moreover, the same port specified on docker-compose ports argument must be the same port specified on redis.conf file

Let's take a look of redis.conf file

port 6373
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

I have to create a redis.conf for each node available in the cluster. I my situation, I have 6 redis nodes, so I need 6 redis.conf files.

The only difference among all redis.conf files is port number. Pay attention to ensure port number the same inside redis.conf file and ports arguments in docker-compose.yml

2 —Mount Redis data volume

It's make data available to whole cluster and application when containers start over again

3 — Docker container to create the cluster

When all redis node are up, I have to join all them in a cluster. To achieve it, I create redis-cluster service to run redis-cli cluster command.

Remember, as I said before, redis-cli cluster only works with static IP, so when I have to pay attention on IP and ports values.

The purpose of the service is only to run redis-cli cluster. There is no problem service dies when the command has been finished

Final thoughts

My article is focused on Redis cluster, so of that, I don’t explain anything about NodeJs and Mariadb services.

However, feel free to ask me for information about it. It Will be a pleasure to help you :)

References:

--

--

Pierre Abreu
Pierre Abreu

Written by Pierre Abreu

10+ experience as a Software developer working in areas as Education, E-commerce, and AdNetwork Mobile

Responses (5)