Setup Redis with TLS using Docker

Configuring Redis with SSL is a cumbersome task. Learn how to do it in 5 minutes.

image.png Recently, I was trying to set up Redis for a production environment and I must say it was a bumpy ride. I ran into a lot of problems while setting up TLS.

If you don't know What is Redis?

Redis is an open-source (BSD licensed), in-memory data structure store, used as a database, cache, and message broker. - redis.io

In this guide, I will show you how you can set up Redis w/ TLS using Docker. The TLS part can be used for standalone installation. But bear in mind, you will need to build Redis from the source in order to use TLS in standalone mode.

So, let's get started.

Prerequisites

  • Docker installed.
  • Docker Compose Installed.
  • A client to test the Redis installation. I recommend, github.com/ekvedaras/redis-gui. It's simple but feel free to use whatever you like.

Running the Redis container

Let's run the Redis container without TLS first -

Create a file compose.yml and paste the content below.

services:
  redis:
    image: docker.io/bitnami/redis:6.2
    user: "${UID}:${GID}"
    environment:
      - ALLOW_EMPTY_PASSWORD=false 
      - REDIS_PASSWORD=the-stronge-one
      - REDIS_DISABLE_COMMANDS=FLUSHDB,FLUSHALL
    ports:
      - '6379:6379'
    volumes:
      - 'redis_data:/bitnami/redis/data'

volumes:
  redis_data:
    driver: local

In the compose.yml file we are doing

  1. Specifying an image to run. Here I picked binami image instead of the official docker image since it has the ability to run with TLS without needing to be built from the source.
  2. Specifying the port 6379 and a docker volume to persist the data.
  3. Setting some environment variables

Let's run the container

docker-compose up -d

Your container should be up and running. You should be able to connect to your Redis instance by using Redis GUI or any other client. Make sure you do not specify any TLS options as we will come to that later in this guide.

Generating Certificates

In order to run Redis with TLS, we need to supply our own SSL certificate. You can buy one or for this use case we don't need to buy but generate our own self-signed certificate for both our Redis instance and the client connecting to it. This was the part that was most troublesome for me.

This might be confusing but bear with me and it should be fine.

The Script

We can do this step manually but since on the Redis GitHub repository, there is a script that generates some certificates for our use case, we will use that.

wget https://raw.githubusercontent.com/redis/redis/cc0091f0f9fe321948c544911b3ea71837cf86e3/utils/gen-test-certs.sh

Once the script is downloaded, let's run it by

sh gen-test-certs.sh

The script will create a tests/tls folder, which contains all the certificates we will need.

Additionally, you can modify the script to add your organization name, fqdn, and other important parameters for the SSL certificate. Go ahead and take a look at the files in that directory.

We're interested in the below files -

  • redis.crt
  • redis.key
  • ca.crt
  • client.crt
  • client.key

Let's go to the next step, which is to update our compose.yml file and include these certificate files to tell Redis to start with TLS.

Configuring TLS

Let's tell Redis container about the above files by specifying them as environment variables. Here, the best part of bitnami image is you can do start the container with TLS without building the original redis image again.

Update your compose.yml file to match below


services:
  redis:
    image: docker.io/bitnami/redis:6.2
    user: "${UID}:${GID}"
    environment:
      - ALLOW_EMPTY_PASSWORD=false
      - REDIS_PASSWORD=the-strong-one
      - REDIS_DISABLE_COMMANDS=FLUSHDB,FLUSHALL
      - REDIS_TLS_CERT_FILE=/tls/redis.crt
      - REDIS_TLS_KEY_FILE=/tls/redis.key
      - REDIS_TLS_CA_FILE=/tls/ca.crt
      - REDIS_TLS_ENABLED=yes
      - REDIS_TLS_PORT=6379
    ports:
      - '6379:6379'
    volumes:
      - 'redis_data:/bitnami/redis/data'
      - ./tests/tls:/tls

volumes:
  redis_data:
    driver: local

Notice that we've specified the environment variable and specified a path (i.e. /tls/*) inside the container for cert files. And we mounted the cert files folder (i.e. ./tests/tls) to the container on the same path (i.e. /tls*).

Phew! That's it. Now we can run our container again and it will start with TLS enabled.

docker-compose up -d

Now, test with your client. You will need to configure your client to use our self-signed client certificate and ca certificate to connect.

Happy Caching.


Feel free to ask if you face any problems on the way.