Building Redis Cluster with docker-compose
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-clusterdb:
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.20redis-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-6redis-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.31redis-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.32redis-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.33redis-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.34redis-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.35redis-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.36volumes:
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: