Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add auth #110

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ 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
COPY default-user.tmpl /redis-conf/default-user.tmpl
COPY custom-user.tmpl /redis-conf/custom-user.tmpl

# Add startup script
COPY docker-entrypoint.sh /docker-entrypoint.sh
Expand Down
102 changes: 76 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ Docker image with redis built and installed from source and a cluster is built.

To find all redis-server releases see them here https://github.com/antirez/redis/releases


## Discussions, help, guides

Github have recently released their `Discussions` feature into beta for more repositories across the github space. This feature is enabled on this repo since a while back.
Expand All @@ -17,12 +16,11 @@ Becuase we now have this feature, the issues feature will NOT be a place where y

What can you expect to find in there?

- A place where you can freely ask any question regarding this repo.
- Ask questions like `how do i do X?`
- General help with problems with this repo
- Guides written by me or any other contributer with useful examples and ansers to commonly asked questions and how to resolve thos problems.
- Approved answers to questions marked and promoted by me if help is provided by the community regarding some questions

- A place where you can freely ask any question regarding this repo.
- Ask questions like `how do i do X?`
- General help with problems with this repo
- Guides written by me or any other contributer with useful examples and ansers to commonly asked questions and how to resolve thos problems.
- Approved answers to questions marked and promoted by me if help is provided by the community regarding some questions

## What this repo and container IS

Expand All @@ -32,7 +30,6 @@ I also aim to have every single release of redis that supports a cluster availab

I personally use this to develop redis cluster client code https://github.com/Grokzen/redis-py-cluster


## What this repo and container IS NOT

This container that i have built is not supposed to be some kind of production container or one that is used within any environment other then running locally on your machine. It is not ment to be run on kubernetes or in any other prod/stage/test/dev environment as a fully working commponent in that environment. If that works for you and your use-case then awesome. But this container will not change to fit any other primary solution then to be used locally on your machine.
Expand All @@ -41,7 +38,6 @@ If you are looking for something else or some production quality or kubernetes c

For all other purposes other then what has been stated you are free to fork and/or rebuild this container using it as a template for what you need.


## Redis instances inside the container

The cluster is 6 redis instances running with 3 master & 3 slaves, one slave for each master. They run on ports 7000 to 7005.
Expand All @@ -50,11 +46,8 @@ If the flag `-e "STANDALONE=true"` is passed there are, by default, 2 standalone

If the flag `-e "SENTINEL=true"` is passed there are 3 Sentinel nodes running on ports 5000 to 5002 matching cluster's master instances.


This image requires at least `Docker` version 1.10 but the latest version is recommended.



# Important for Mac users

If you are using this container to run a redis cluster on your mac computer, then you need to configure the container to use another IP address for cluster discovery as it can't use the default discovery IP that is hardcoded into the container.
Expand All @@ -73,8 +66,6 @@ If you are downloading the container from dockerhub, you must add the internal I
docker run -e "IP=0.0.0.0" -p 7000-7005:7000-7005 grokzen/redis-cluster:latest
```



# Usage

To build your own image run:
Expand All @@ -97,7 +88,6 @@ Or the built redis-cli tool inside the container that will connect to the cluste

make cli


## Include standalone redis instances

Standalone instances is not enabled by default, but available to use to run 2 standalone redis instances that is not clustered.
Expand All @@ -115,7 +105,6 @@ When running with docker-compose, set the environment variable on your system `R
environment:
STANDALONE: 'true'


## Include sentinel instances

Sentinel instances is not enabled by default.
Expand All @@ -131,18 +120,17 @@ When running with docker-compose set the environment variable on your system `RE
environment:
SENTINEL: 'true'


## Change number of nodes

Be default, it is going to launch 3 masters with 1 slave per master. This is configurable through a number of environment variables:

| Environment variable | Default |
| -------------------- |--------:|
| -------------------- | ------: |
| `INITIAL_PORT` | 7000 |
| `MASTERS` | 3 |
| `SLAVES_PER_MASTER` | 1 |
| `SLAVES_PER_MASTER` | 1 |

Therefore, the total number of nodes (`NODES`) is going to be `$MASTERS * ( $SLAVES_PER_MASTER + 1 )` and ports are going to range from `$INITIAL_PORT` to `$INITIAL_PORT + NODES - 1`.
Therefore, the total number of nodes (`NODES`) is going to be `$MASTERS * ( $SLAVES_PER_MASTER + 1 )` and ports are going to range from `$INITIAL_PORT` to `$INITIAL_PORT + NODES - 1`.

At the docker-compose provided by this repository, ports 7000-7050 are already mapped to the hosts'. Either if you need more than 50 nodes in total or if you need to change the initial port number, you should override those values.

Expand All @@ -157,7 +145,6 @@ Also note that the number of sentinels (if enabled) is the same as the number of
MASTERS: 2,
SLAVES_PER_MASTER: 2


## IPv6 support

By default, redis instances will bind and accept requests from any IPv4 network.
Expand All @@ -174,29 +161,93 @@ 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

## Authentication

Authentication is controlled by environment variables on your machine at the time the docker container is built. There are two users you can control and they can be set independently.
<br>

##### Default user

The `default` user is a special user name in Redis. It is the user that can authenticate into the cluster using just a password. It is also the user that the cluster nodes use to authenticate into the cluster itself. By default, Redis does not assign a password to user `default`. If the environment variable `REDIS_DEFAULT_PASSWORD` is set, then you must provide a password before issuing any Redis commands in redis-cli. Your application must provide a password to authenticate into the cluster as well.

To build the cluster with the default password, from the docker-redis-cluster directory:

```
export REDIS_DEFAULT_PASSORD=yourfavoritepassword
MAKE BUILD
MAKE UP
```

After the cluster is running, in a new terminal window

```
% redis-cli -c -p 7000
127.0.0.1:7000> cluster nodes
NOAUTH Authentication required
127.0.0.1:7000> AUTH yourfavoritepassword
OK
127.0.0.1:7000> cluster nodes
6edadac1532e3332d45ef31528355cf88da01689 127.0.0.1:7002@17002 master - 0 1611433806048 3 connected 10923-16383
.
.
.

```

<br>

##### Custom User

To create a custom user in your Redis cluster, add two environment variables: `REDIS_USER_NAME` and `REDIS_USER_PASSWORD`. The user created has full access to the system. To experiment with different kinds of access, edit the `default-user.tmpl` file. See https://redis.io/commands/acl-setuser for more information on configuring ACLs.

To build the cluster with the default password, from the docker-redis-cluster directory:

```
export REDIS_USER_NAME=username
export REDIS_USER_PASSWORD=userpassword
MAKE BUILD
MAKE UP
```

After the cluster is running, in a new terminal window

```
% redis-cli -c -p 7000
127.0.0.1:7000> cluster nodes
NOAUTH Authentication required
127.0.0.1:7000> AUTH username userpassword
OK
127.0.0.1:7000> cluster nodes
6edadac1532e3332d45ef31528355cf88da01689 127.0.0.1:7002@17002 master - 0 1611433806048 3 connected 10923-16383
.
.
.

```

<br>
##### Using user `default` in combination with a custom user
If you are testing with a custom user, it is recommeded to also set a password for user `default`. The reason is that you may accidentally authenticate to Redis as user `default`. Without a password, Redis sets a `nopass` ACL and quietly authenticates as user `default` when no other credentials are provided. By setting a password for user `default`, authentication will be required before Redis will allow commands to be issued. When both set, you can authenticate either as default or the custom user.
<br>

## Build alternative redis versions

For a release to be buildable it needs to be present at this url: http://download.redis.io/releases/


### docker build

To build a different redis version use the argument `--build-arg` argument.

# Example plain docker
docker build --build-arg redis_version=4.0.13 -t grokzen/redis-cluster .


### docker-compose

To build a different redis version use the `--build-arg` argument.

# Example docker-compose
docker-compose build --build-arg "redis_version=4.0.13" redis-cluster



# Available tags

The following tags with pre-built images is available on `docker-hub`.
Expand Down Expand Up @@ -284,7 +335,6 @@ Redis 3.0.x versions:
- 3.0.1
- 3.0.0


# License

This repo is using the MIT LICENSE.
Expand Down
1 change: 1 addition & 0 deletions custom-user.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
user ${USER_NAME} on allcommands allkeys >${USER_PASSWORD}
2 changes: 2 additions & 0 deletions default-user.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
requirepass ${DEFAULT_PASSWORD}
masterauth ${DEFAULT_PASSWORD}
17 changes: 10 additions & 7 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
version: '2'
version: "2"
services:
redis-cluster:
environment:
IP: ${REDIS_CLUSTER_IP}
SENTINEL: ${REDIS_USE_SENTINEL}
STANDALONE: ${REDIS_USE_STANDALONE}
IP: ${REDIS_CLUSTER_IP}
SENTINEL: ${REDIS_USE_SENTINEL}
STANDALONE: ${REDIS_USE_STANDALONE}
DEFAULT_PASSWORD: ${REDIS_DEFAULT_PASSWORD}
USER_NAME: ${REDIS_USER_NAME}
USER_PASSWORD: ${REDIS_USER_PASSWORD}
build:
context: .
args:
redis_version: '6.0.10'
redis_version: "6.0.10"
hostname: server
ports:
- '7000-7050:7000-7050'
- '5000-5010:5000-5010'
- "7000-7050:7000-7050"
- "5000-5010:5000-5010"
26 changes: 25 additions & 1 deletion docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,24 @@ if [ "$1" = 'redis-cluster' ]; then
fi
fi

# If environment variable REDIS_DEFAULT_PASSWORD had a value when container was built,
# append default-user.tmpl to the redis.conf file for this node
if [ -z "${DEFAULT_PASSWORD}" ]; then
echo "Starting without user 'default' password"
else
echo "Starting with user 'default' password set"
DEFAULT_PASSWORD=${DEFAULT_PASSWORD} envsubst < /redis-conf/default-user.tmpl >> /redis-conf/${port}/redis.conf
fi

# If environment USER_NAME has a value when container was built,
# append custom-user.tmpl to the redis.conf file for this node
if [ -z "${USER_NAME}" ]; then
echo "Starting without custom user"
else
echo "Starting with custom user ${USER_NAME}"
USER_NAME=${USER_NAME} USER_PASSWORD=${USER_PASSWORD} envsubst < /redis-conf/custom-user.tmpl >> /redis-conf/${port}/redis.conf
fi

done

bash /generate-supervisor-conf.sh $INITIAL_PORT $max_port > /etc/supervisor/supervisord.conf
Expand All @@ -88,7 +106,13 @@ if [ "$1" = 'redis-cluster' ]; then
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"
# If default user has a required password, it is necessary to pass the password as -a
# in order for the cluster nodes to be able to authenticate to the cluster.
if [ -z "${DEFAULT_PASSWORD}" ]; then
echo "yes" | eval /redis/src/redis-cli --cluster create --cluster-replicas "$SLAVES_PER_MASTER" "$nodes"
else
echo "yes" | eval /redis/src/redis-cli --cluster create --cluster-replicas "$SLAVES_PER_MASTER" "$nodes" -a "${DEFAULT_PASSWORD}"
fi
fi

if [ "$SENTINEL" = "true" ]; then
Expand Down