> ## Documentation Index
> Fetch the complete documentation index at: https://docs.minimus.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Redis TLS Tutorial

> A guide to setting up Redis and testing that it accepts TLS connections, enforces authentication, and allows secure read/write operations from a test client

The following guide will help you deploy the Minimus Redis image with self-signed, locally issued certificates to help you get started. Run the code to try it for yourself.

<Info>
  For production purposes, we recommend using publicly trusted certificates issued by a Certificate Authority (CA).
</Info>

## Components

* **Redis image built by Minimus**: Redis container configured to require secure connections via TLS.
* Dynamic certificate generation via OpenSSL:
  * **certgen.sh script**: Shell script that generates a custom CA, server, and client certificates using OpenSSL.
  * **minidebug image**: A Minimus dev toolkit that provides a shell, OpenSSL, and other utilities used to generate the certificates.

## What this guide demonstrates

* TLS handshake validation
* Server/client certificate trust
* Basic auth and Redis operations
* Image compatibility

## Directory structure

```bash theme={null}
.
├── certgen.sh             # Certificate generation script
├── create-certs.yml       # Compose file to run certgen container
└── docker-compose.yml     # Compose file to run Redis
```

## Deploy Redis with TLS certificates

### Prerequisite: Authenticate to the Minimus Registry

Run the docker login command to authenticate to the Minimus registry:

```shellscript theme={null}
echo "{token}" | docker login reg.mini.dev -u minimus --password-stdin
```

### Step 1: Generate TLS certificates

<Steps>
  <Step title="Save script that generates TLS certificates">
    Save the following script to a file named `certgen.sh`. The script is used to generate the TLS certificates and store them in a `certs` folder on the host.

    ```bash certgen.sh expandable theme={null}
    #!/bin/sh
    set -e
    cd /certs

    cat > openssl.cnf <<EOF
    [ req ]
    default_bits       = 2048
    distinguished_name = req_distinguished_name
    prompt             = no

    [ req_distinguished_name ]
    CN = redis

    [ v3_ca ]
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always,issuer
    basicConstraints = critical, CA:true
    keyUsage = critical, keyCertSign, cRLSign

    [ v3_server ]
    basicConstraints = CA:false
    keyUsage = digitalSignature, keyEncipherment
    extendedKeyUsage = serverAuth
    subjectAltName = @alt_names

    [ v3_client ]
    basicConstraints = CA:false
    keyUsage = digitalSignature, keyEncipherment
    extendedKeyUsage = clientAuth

    [ alt_names ]
    DNS.1 = redis
    DNS.2 = localhost
    IP.1  = 127.0.0.1
    IP.2  = 192.168.10.0
    IP.3  = 192.168.10.2
    IP.4  = 192.168.10.3
    EOF

    # Optional: clean old stuff so we don't mix CAs
    rm -f ca*.pem ca.srl server-*.pem client-*.pem

    # ----- CA -----
    openssl genrsa -out ca-key.pem 2048
    openssl req -x509 -new -nodes -key ca-key.pem \
      -sha256 -days 365 -out ca.pem \
      -subj "/CN=Test CA" \
      -extensions v3_ca -config openssl.cnf

    # ----- Server cert (with SAN + serverAuth) -----
    openssl genrsa -out server-key.pem 2048
    openssl req -new -key server-key.pem -out server.csr -config openssl.cnf
    openssl x509 -req -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial \
      -out server-cert.pem -days 365 -sha256 \
      -extensions v3_server -extfile openssl.cnf

    # ----- Client cert (clientAuth only) -----
    openssl genrsa -out client-key.pem 2048
    openssl req -new -key client-key.pem -out client.csr -subj "/CN=root"
    openssl x509 -req -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial \
      -out client-cert.pem -days 365 -sha256 \
      -extensions v3_client -extfile openssl.cnf

    # Permissions / ownership (as you had)
    chmod 600 *.pem || true
    chown -R 1000:1000 /certs/*.pem || true
    chmod 644 /certs/*.pem || true
    ```
  </Step>

  <Step title="Save Docker Compose configuration">
    Save the following YAML file to run with Docker Compose. It uses the [**Minimus minidebug image**](https://images.minimus.io/gallery/images/minidebug/quick-start?__hstc=180987128.11065ee83c8bdcec1851176c12d849d3.1762436227738.1762436227738.1762436227738.1&__hssc=180987128.1.1762436227739&__hsfp=2666866004) to generate the certificates with the `certgen.sh` shell script. Minidebug is a Minimus dev toolkit that provides a shell, OpenSSL, and other utilities. The certificates will be persisted in the `certs` volume on the host.

    ```yaml create-certs.yml theme={null}
    services:
      certgen:
        image: reg.mini.dev/minidebug:latest
        container_name: redis_certgen
        volumes:
        - ./certs:/certs
        - ./certgen.sh:/certgen.sh:ro
        entrypoint: ["/bin/sh", "/certgen.sh"]    
    ```
  </Step>

  <Step title="Generate certificates">
    Run the following to generate the certificates:

    ```shellscript theme={null}
    docker compose -f create-certs.yml up
    ```
  </Step>
</Steps>

Congrats! You have just generated the following self-signed certificates:

* Self-signed CA certificate (`ca.pem`)
* Server certificates (`server-cert.pem`, `server-key.pem`) with SANs: `Redis`, `localhost`, and `192.168.20.3`
* Client certificates for `testuser`(`client.csr`, `client-key.pem`)

Certificate permissions are adjusted to support non-root containers. In the next steps, you will mount these certificates into the Redis container.

### Step 2: Deploy Redis server

<Steps>
  <Step title="Save Docker Compose script">
    Save the following Docker Compose script to a file named `docker-compose.yml`. This script sets up the Redis service with a healthcheck, mounts a volume with the certificates, and maps port 6379. The container is configured with `"--tls-auth-clients", "yes"` to require client certificates.

    ```yaml docker-compose.yml expandable theme={null}
    services:
      redis:
        image: reg.mini.dev/redis:latest
        command: [
          "redis-server",
          "--tls-port", "6379",
          "--port", "0",
          "--tls-cert-file", "/certs/server-cert.pem",
          "--tls-key-file", "/certs/server-key.pem",
          "--tls-ca-cert-file", "/certs/ca.pem",
          "--requirepass", "testpass",
          "--tls-auth-clients", "yes"
        ]
        volumes:
          - ./certs:/certs:ro
        ports:
          - "6379:6379"
    ```
  </Step>

  <Step title="Run Redis">
    Start the Redis container:

    ```shellscript theme={null}
    docker compose -f docker-compose.yml up
    ```
  </Step>
</Steps>

### Step 3: Test your Redis server

We will use redis-cli to connect over TLS and run tests. For example, here are a few commands you can try out:

1. Check server info and health:

   <CodeGroup>
     ```bash Check info over TLS theme={null}
     redis-cli \
       -h 127.0.0.1 \
       -p 6379 \
       --tls \
       --cacert ./certs/ca.pem \
       --cert  ./certs/client-cert.pem  \
       --key   ./certs/client-key.pem \
       -a testpass \
       info
     ```

     ```bash Expected response theme={null}
     Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
     # Server
     redis_version:8.2.3
     redis_git_sha1:ceb01e15
     redis_git_dirty:1
     redis_build_id:7fe6dd1915e7cd11
     redis_mode:standalone
     os:Linux 6.1.0-29-cloud-amd64 x86_64
     arch_bits:64
     monotonic_clock:POSIX clock_gettime
     multiplexing_api:epoll
     atomicvar_api:c11-builtin
     gcc_version:15.2.0
     process_id:1 
     ...
     ```
   </CodeGroup>
2. Add test key to a database:

   <CodeGroup>
     ```bash Set key theme={null}
     redis-cli \
       -h 127.0.0.1 \
       -p 6379 \
       --tls \
       --cacert ./certs/ca.pem \
       --cert  ./certs/client-cert.pem  \
       --key   ./certs/client-key.pem \
       -a testpass \
       -n 1 \
       set mykey "Hello from Minimus"
     ```

     ```bash Expected response theme={null}
     Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
     OK
     ```
   </CodeGroup>

   <Info>
     Redis has numbered logical databases (default 0–15) rather than named databases.
   </Info>

   Verify the key:

   <CodeGroup>
     ```bash Verify key theme={null}
     redis-cli \
       -h 127.0.0.1 \
       -p 6379 \
       --tls \
       --cacert ./certs/ca.pem \
       --cert  ./certs/client-cert.pem  \
       --key   ./certs/client-key.pem \
       -a testpass \
       -n 1 \
       get mykey
     ```

     ```bash Expected response theme={null}
     Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
     "Hello from Minimus"
     ```
   </CodeGroup>
3. Test data persistence:
   ```bash Save data theme={null}
   redis-cli \
     -h 127.0.0.1 \
     -p 6379 \
     --tls \
     --cacert ./certs/ca.pem \
     --cert  ./certs/client-cert.pem  \
     --key   ./certs/client-key.pem \
     -a testpass \
     save
   ```
   Stop the container, then restart it:
   ```bash theme={null}
   docker ps 
   docker stop {Redis container ID}
   docker restart {Redis container ID}
   ```
   Check the key you added in the previous step:
   ```bash Get key theme={null}
   redis-cli \
     -h 127.0.0.1 \
     -p 6379 \
     --tls \
     --cacert ./certs/ca.pem \
     --cert  ./certs/client-cert.pem  \
     --key   ./certs/client-key.pem \
     -a testpass \
     -n 1 \
     get mykey
   ```
4. Delete the key:
   <CodeGroup>
     ```bash Delete key theme={null}
     redis-cli \
       -h 127.0.0.1 \
       -p 6379 \
       --tls \
       --cacert ./certs/ca.pem \
       --cert  ./certs/client-cert.pem  \
       --key   ./certs/client-key.pem \
       -a testpass \
       -n 1 \
       del mykey
     ```
   </CodeGroup>
