Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/dockerimage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ jobs:
- uses: actions/checkout@v2
- name: Build the latest Docker image
run: make build
- name: Build the TLS Docker image
run: make build-tls

10 changes: 5 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ FROM redis@sha256:e422889e156ebea83856b6ff973bfe0c86bce867d80def228044eeecf92559
LABEL maintainer="Johan Andersson <Grokzen@gmail.com>"

# Some Environment Variables
ENV HOME /root
ENV DEBIAN_FRONTEND noninteractive
ENV HOME=/root
ENV DEBIAN_FRONTEND=noninteractive

# Install system dependencies
RUN apt-get update -qq && \
apt-get install --no-install-recommends -yqq \
net-tools supervisor ruby rubygems locales gettext-base wget gcc make g++ build-essential libc6-dev tcl && \
net-tools supervisor ruby rubygems locales locales-all gettext-base wget gcc make g++ build-essential libc6-dev tcl && \
apt-get clean -yqq

# # Ensure UTF-8 lang and locale
ENV LANG=en_US.UTF-8
ENV LC_ALL=en_US.UTF-8
RUN locale-gen en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LC_ALL en_US.UTF-8

# Necessary for gem installs due to SHA1 being weak and old cert being revoked
ENV SSL_CERT_FILE=/usr/local/etc/openssl/cert.pem
Expand Down
52 changes: 52 additions & 0 deletions Dockerfile.tls
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Build based on redis:7.2.5 from "2024-05-22T23:17:59Z"
FROM redis@sha256:e422889e156ebea83856b6ff973bfe0c86bce867d80def228044eeecf925592b

LABEL maintainer="Johan Andersson <Grokzen@gmail.com>"

# Some Environment Variables
ENV HOME=/root
ENV DEBIAN_FRONTEND=noninteractive

# Install system dependencies
RUN apt-get update -qq && \
apt-get install --no-install-recommends -yqq \
net-tools supervisor ruby rubygems locales locales-all gettext-base wget gcc make g++ build-essential libc6-dev tcl libssl-dev && \
apt-get clean -yqq

# # Ensure UTF-8 lang and locale
ENV LANG=en_US.UTF-8
ENV LC_ALL=en_US.UTF-8
RUN locale-gen en_US.UTF-8

# Necessary for gem installs due to SHA1 being weak and old cert being revoked
ENV SSL_CERT_FILE=/usr/local/etc/openssl/cert.pem

RUN gem install redis -v 4.1.3

# This will always build the latest release/commit in the 7.2 branch
ARG redis_version=7.2

RUN wget -qO redis.tar.gz https://github.com/redis/redis/tarball/${redis_version} \
&& tar xfz redis.tar.gz -C / \
&& mv /redis-* /redis

RUN (cd /redis && make BUILD_TLS=yes)

RUN mkdir /redis-conf && mkdir /redis-data

COPY redis-cluster.tmpl /redis-conf/redis-cluster.tmpl
COPY redis.tmpl /redis-conf/redis.tmpl
COPY sentinel.tmpl /redis-conf/sentinel.tmpl

# Add startup script
COPY docker-entrypoint.sh /docker-entrypoint.sh

# Add script that generates supervisor conf file based on environment variables
COPY generate-supervisor-conf.sh /generate-supervisor-conf.sh

RUN chmod 755 /docker-entrypoint.sh

EXPOSE 7000 7001 7002 7003 7004 7005 7006 7007 5000 5001 5002

ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["redis-cluster"]
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ help:
@echo " cli run redis-cli inside the container on the server with port 7000"

build:
docker-compose build
docker compose build

build-tls:
docker compose -f docker-compose.tls.yml build

up:
docker-compose up
Expand Down
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,38 @@ Unfortunately Docker does not handle IPv6 NAT so, when acceptable, `--network ho
# Example using plain docker
docker run -e "IP=::1" -e "BIND_ADDRESS=::" --network host grokzen/redis-cluster:latest

## Enable authentication
By default, authentication using a password is disabled.
This is configurable by an enviroment variable that specifies which a password string is required to authenticate itself using the AUTH command.

| Environment variable | Default |
| -------------------- | ------------------------------------------ |
| `PASSWORD` | "" (requirepass/masterauth not configured) |

## Announced hostname
By default, no announced hostname is set.
This is configurable by an enviroment variable that specifies which show hostname as additional metadata in the CLUSTER SLOTS command. This valus is communicated along the clusterbus to all nodes, setting it to an empty string will remove the hostname and also propagate the removal.

| Environment variable | Default |
| -------------------- | ------------------------------------------ |
| `CLUSTER_ANNOUNCE_HOSTNAME` | "" (empty announced hostname) |

## Protected mode
By default, Protected mode is enabled.
This is configurable by an enviroment variable that specifies which the system administator can still ignore the error given by Redis and just disable protected mode or manually bind all the interfaces.

| Environment variable | Default |
| -------------------- | ------------------------------------------ |
| `PROTECTED_MODE` | "" (protected-mode is yes) |

## Clean redis-data before start redis
By default, All file in folder redis-data will be remove before start redis.
This is configurable by an enviroment variable that specifies which the system administator can handle remove/keep all file in redis-data before start redis.

| Environment variable | Default |
| -------------------- | ------------------------------------------ |
| `RESET_DATA` | "" (redis-data will be clean) |


## Build alternative redis versions

Expand Down
17 changes: 17 additions & 0 deletions docker-compose.tls.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: '2'
services:
redis-cluster:
image: redis-cluster:tls-latest
environment:
IP: ${REDIS_CLUSTER_IP}
SENTINEL: ${REDIS_USE_SENTINEL}
STANDALONE: ${REDIS_USE_STANDALONE}
build:
context: .
dockerfile: ./Dockerfile.tls
args:
redis_version: '7.2.5'
hostname: server
ports:
- '7000-7050:7000-7050'
- '5000-5010:5000-5010'
79 changes: 56 additions & 23 deletions docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,51 @@ if [ "$1" = 'redis-cluster' ]; then
for port in $(seq $INITIAL_PORT $max_port); do
mkdir -p /redis-conf/${port}
mkdir -p /redis-data/${port}

if [ -e /redis-data/${port}/nodes.conf ]; then
rm /redis-data/${port}/nodes.conf
if [ -n "$RESET_DATA" -a "$RESET_DATA" = "false" ]; then
if [ ! -e /redis-data/${port}/nodes.conf ]; then
RESET_DATA="true"
fi
fi
done

if [ -e /redis-data/${port}/dump.rdb ]; then
rm /redis-data/${port}/dump.rdb
for port in $(seq $INITIAL_PORT $max_port); do
if [ -z "$RESET_DATA" -o "$RESET_DATA" = "true" ]; then
if [ -e /redis-data/${port}/nodes.conf ]; then
rm /redis-data/${port}/nodes.conf
fi

if [ -e /redis-data/${port}/dump.rdb ]; then
rm /redis-data/${port}/dump.rdb
fi

if [ -e /redis-data/${port}/appendonly.aof ]; then
rm /redis-data/${port}/appendonly.aof
fi
fi
if [ -z "$PROTECTED_MODE" -o "$PROTECTED_MODE" = "true" ]; then
protectedmode="protected-mode yes"
elif [ "$PROTECTED_MODE" = "false" ]; then
protectedmode="protected-mode no"
fi


if [ -e /redis-data/${port}/appendonly.aof ]; then
rm /redis-data/${port}/appendonly.aof
if [ -n "$CLUSTER_ANNOUNCE_HOSTNAME" ]; then
clusterannouncehostname="cluster-announce-hostname '${CLUSTER_ANNOUNCE_HOSTNAME}'"
clusterpreferedendpointtype="cluster-preferred-endpoint-type hostname"
fi

if [ "$port" -lt "$first_standalone" ]; then
PORT=${port} BIND_ADDRESS=${BIND_ADDRESS} envsubst < /redis-conf/redis-cluster.tmpl > /redis-conf/${port}/redis.conf
if [ -n "$PASSWORD" ]; then
requirepass="requirepass '${PASSWORD}'"
masterauth="masterauth '${PASSWORD}'"
fi
PORT=${port} BIND_ADDRESS=${BIND_ADDRESS} REQUIREPASS=${requirepass} MASTERAUTH=${masterauth} PROTECTED_MODE=${protectedmode} CLUSTER_ANNOUNCE_HOSTNAME=${clusterannouncehostname} CLUSTER_PREFERED_ENDPOINT_TYPE=${clusterpreferedendpointtype} envsubst < /redis-conf/redis-cluster.tmpl > /redis-conf/${port}/redis.conf
nodes="$nodes $IP:$port"
else
PORT=${port} BIND_ADDRESS=${BIND_ADDRESS} envsubst < /redis-conf/redis.tmpl > /redis-conf/${port}/redis.conf
if [ -n "$PASSWORD" ]; then
requirepass="requirepass '${PASSWORD}'"
fi
PORT=${port} BIND_ADDRESS=${BIND_ADDRESS} REQUIREPASS=${requirepass} PROTECTED_MODE=${protectedmode} envsubst < /redis-conf/redis.tmpl > /redis-conf/${port}/redis.conf
fi

if [ "$port" -lt $(($INITIAL_PORT + $MASTERS)) ]; then
Expand All @@ -80,21 +107,27 @@ if [ "$1" = 'redis-cluster' ]; then
## Check the version of redis-cli and if we run on a redis server below 5.0
## If it is below 5.0 then we use the redis-trib.rb to build the cluster
#
/redis/src/redis-cli --version | grep -E "redis-cli 3.0|redis-cli 3.2|redis-cli 4.0"

if [ $? -eq 0 ]
then
echo "Using old redis-trib.rb to create the cluster"
echo "yes" | eval ruby /redis/src/redis-trib.rb create --replicas "$SLAVES_PER_MASTER" "$nodes"
else
echo "Using redis-cli to create the cluster"
echo "yes" | eval /redis/src/redis-cli --cluster create --cluster-replicas "$SLAVES_PER_MASTER" "$nodes"
fi
if [ -z "$RESET_DATA" -o "$RESET_DATA" = "true" ]; then
/redis/src/redis-cli --version | grep -E "redis-cli 3.0|redis-cli 3.2|redis-cli 4.0"
if [ $? -eq 0 ]
then
echo "Using old redis-trib.rb to create the cluster"
echo "yes" | eval ruby /redis/src/redis-trib.rb create --replicas "$SLAVES_PER_MASTER" "$nodes"
else
echo "Using redis-cli to create the cluster"
if [ -z "$PASSWORD" ]; then
echo "yes" | eval /redis/src/redis-cli --cluster create --cluster-replicas "$SLAVES_PER_MASTER" "$nodes"
password_arg="-a $PASSWORD"
else
echo "yes" | eval /redis/src/redis-cli --cluster create --cluster-replicas "$SLAVES_PER_MASTER" -a "$PASSWORD" "$nodes"
fi
fi

if [ "$SENTINEL" = "true" ]; then
for port in $(seq $INITIAL_PORT $(($INITIAL_PORT + $MASTERS))); do
redis-sentinel /redis-conf/sentinel-${port}.conf &
done
if [ "$SENTINEL" = "true" ]; then
for port in $(seq $INITIAL_PORT $(($INITIAL_PORT + $MASTERS))); do
redis-sentinel /redis-conf/sentinel-${port}.conf &
done
fi
fi

tail -f /var/log/supervisor/redis*.log
Expand Down
6 changes: 5 additions & 1 deletion redis-cluster.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@ cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
dir /redis-data/${PORT}
protected-mode no
${REQUIREPASS}
${MASTERAUTH}
${PROTECTED_MODE}
${CLUSTER_ANNOUNCE_HOSTNAME}
${CLUSTER_PREFERED_ENDPOINT_TYPE}
3 changes: 2 additions & 1 deletion redis.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ bind ${BIND_ADDRESS}
port ${PORT}
appendonly yes
dir /redis-data/${PORT}
protected-mode no
${REQUIREPASS}
${PROTECTED_MODE}