Contenido

Tutorial de Redis en Docker: configurar una contraseña y conservar y conectar datos

Redis es una base de datos de clave-valor que mantiene los datos en memoria. Se suele usar como caché, almacenamiento de sesiones, contador o cola. Solo necesitas unos segundos para ejecutarlo con Docker.

Ejecución básica

$ docker run -d --name redis -p 127.0.0.1:6379:6379 redis:8-alpine
Unable to find image 'redis:8-alpine' locally
8-alpine: Pulling from library/redis
Digest: sha256:3811787313eba226a2ef38658c6ccb91cd5e110edc89c37767de373120a0e5a0
Status: Downloaded newer image for redis:8-alpine
6fbb2effcf1bc874eda1064575153984b6223fd6de15ac2452eae0bbf71a74f1

$ docker exec redis redis-cli PING
PONG

$ docker exec redis redis-cli SET greeting hello
OK

$ docker exec redis redis-cli GET greeting
hello

$ docker exec redis redis-cli SET session:abc "user42" EX 60
OK

$ docker exec redis redis-cli TTL session:abc
60

$ docker exec redis redis-server --version
Redis server v=8.10.2 sha=00000000:1 malloc=jemalloc-5.3.0 bits=64 build=6583f6419e33bdeb

$ docker rm -f redis
redis
  • -p 127.0.0.1:6379:6379: solo permite el acceso desde el equipo local.
  • El contenedor ya incluye redis-cli, así que puedes ejecutar los comandos directamente.
  • SET ... EX 60 establece la expiración automática a los 60 segundos. TTL muestra los segundos restantes. Se suele usar para sesiones y cachés.

Para usar el modo interactivo, ejecuta docker exec -it redis redis-cli. Aparecerá el indicador 127.0.0.1:6379>. Escribe un comando y pulsa Enter; escribe exit para salir.

Configurar una contraseña

Redis no tiene contraseña de forma predeterminada. Si el puerto está expuesto, cualquiera puede leer y escribir datos, e incluso usar Redis para entrar en el host. Por eso:

  1. Si no necesitas conexiones externas, no uses -p. Si lo necesitas, enlázalo solo a 127.0.0.1.
  2. Configura una contraseña:
$ docker run -d --name redis redis:8-alpine redis-server --requirepass "change-me"
8dbd1f84d2541f264d93555142cb65f6497e9635111ff4f9544258516e06a0e2

$ docker exec redis redis-cli GET greeting
NOAUTH Authentication required.


$ docker exec redis redis-cli -a "change-me" PING
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
PONG

$ docker exec redis redis-cli -a "change-me" --no-auth-warning PING
PONG

$ docker exec -e REDISCLI_AUTH=change-me redis redis-cli PING
PONG

$ docker rm -f redis
redis
  • Sin contraseña, aparece NOAUTH Authentication required..
  • Puedes pasar la contraseña con -a, pero aparecerá una advertencia porque queda visible en la lista de procesos. --no-auth-warning solo oculta la advertencia.
  • Es mejor pasar la contraseña mediante la variable de entorno REDISCLI_AUTH. redis-cli la usará automáticamente y no mostrará ninguna advertencia.

Cadena de conexión de la aplicación (deja vacío el nombre de usuario):

redis://:change-me@redis:6379/0

El /0 final es el número de la base de datos (0–15).

Persistencia de datos

Redis mantiene los datos en memoria. Hay dos formas de guardarlos en disco: instantáneas RDB y registro AOF. La imagen oficial solo activa RDB de forma predeterminada y guarda los archivos en /data del contenedor, así que debes montar un Volume.

Prueba práctica: RDB no guarda los datos al instante

$ docker run -d --name redis -v redis_data:/data redis:8-alpine
882983e53f8e000fa65faaf8d71bbcbeb57192401b1854621172ce2df95c29a6

$ docker exec redis redis-cli SET visits 100
OK

$ docker rm -f redis
redis

$ docker run -d --name redis -v redis_data:/data redis:8-alpine
5ad1473152a6eafdfdb33df64f68355c73e454f10e6bc135688f7c51686bb059

$ docker exec redis redis-cli GET visits


$ docker exec redis redis-cli CONFIG GET save
save
3600 1 300 100 60 10000

Aunque hayas montado un Volume, visits está vacío después de ejecutar docker rm -f y crear el contenedor de nuevo. CONFIG GET save muestra las condiciones de guardado predeterminadas 3600 1 300 100 60 10000, que significan:

CondiciónSignificado
3600 1Guarda si cambia al menos 1 clave en 1 hora
300 100Guarda si cambian al menos 100 claves en 5 minutos
60 10000Guarda si cambian al menos 10000 claves en 1 minuto

Si solo cambias una clave, tendrás que esperar 1 hora para que se guarde. docker rm -f termina Redis directamente con SIGKILL, así que no tiene tiempo de guardar los datos.

Detén el contenedor correctamente con docker stop:

$ docker exec redis redis-cli SET visits 100
OK

$ docker stop redis
redis

$ docker logs redis 2>&1 | tail -n 5
1:M 13 Oct 2026 00:57:09.620 * User requested shutdown...
1:M 13 Oct 2026 00:57:09.620 * Saving the final RDB snapshot before exiting.
1:M 13 Oct 2026 00:57:09.621 * BGSAVE done, 1 keys saved, 0 keys skipped, 104 bytes written.
1:M 13 Oct 2026 00:57:09.623 * DB saved on disk
1:M 13 Oct 2026 00:57:09.623 # Redis is now ready to exit, bye bye...

$ docker start redis
redis

$ docker exec redis redis-cli GET visits
100

$ docker exec redis ls -l /data
total 4
-rw-------    1 redis    redis          104 Oct 13 00:57 dump.rdb

$ docker rm -f redis
redis

$ docker volume rm redis_data
redis_data

docker stop sends SIGTERM. Before exiting, Redis runs Saving the final RDB snapshot before exiting and saves the data. Therefore:

  • A normal stop (docker stop, docker compose down or a normal host shutdown) does not lose data.
  • A crash, power outage, docker rm -f or termination by the system due to low memory will lose data written after the last snapshot.

AOF: registra cada escritura

Para conservar los datos de forma más fiable, activa AOF (Append Only File). Se registrará cada comando de escritura:

$ docker run -d --name redis -v redis_data:/data redis:8-alpine redis-server --appendonly yes
aaac5c67a222018db886e0f3a3306841ec4bba7e8ae0b4b4eca71dc5cede91c9

$ docker exec redis redis-cli SET visits 41
OK

$ docker exec redis redis-cli INCR visits
42

$ docker rm -f redis
redis

$ docker run -d --name redis -v redis_data:/data redis:8-alpine redis-server --appendonly yes
1c880b5c2e8ef54b65baaa1fd99b1b9c976eb42f2d9c52f1eb9188eaeda955e4

$ docker exec redis redis-cli GET visits
42

$ docker exec redis ls /data/appendonlydir
appendonly.aof.1.base.rdb
appendonly.aof.1.incr.aof
appendonly.aof.manifest

$ docker rm -f redis
redis

$ docker volume rm redis_data
redis_data

Aunque elimines el contenedor a la fuerza con docker rm -f, visits seguirá teniendo el valor 42 después de volver a crearlo. En /data/appendonlydir están los archivos AOF: base.rdb es la instantánea base, incr.aof registra cada escritura posterior y manifest contiene la lista de archivos.

MétodoVentajasDesventajas
RDB (predeterminado)Archivo pequeño, carga rápida al reiniciarSi el proceso termina de forma inesperada, pueden perderse los datos posteriores a la última instantánea
AOFDe forma predeterminada, escribe en el disco cada segundo; como máximo se pierde aproximadamente 1 segundo de datosEl archivo es más grande y el disco soporta más carga cuando hay muchas escrituras
Sin persistenciaEs la opción más rápidaTodos los datos desaparecen al reiniciar; solo sirve para una caché pura

Para usarlo solo como caché, puedes desactivar por completo la persistencia: redis-server --save "" --appendonly no.

Usa un archivo de configuración y establece un límite de memoria

Cuando hay muchos parámetros, usa un archivo de configuración. redis-demo/redis.conf:

requirepass change-me
appendonly yes
maxmemory 64mb
maxmemory-policy allkeys-lru

Cuando uses Redis como caché, establece siempre maxmemory. De lo contrario, Redis seguirá ocupando memoria hasta que la memoria del host se agote. Al alcanzar el límite, Redis aplica la política de maxmemory-policy:

PolíticaComportamiento
noevictionValor predeterminado: rechaza las nuevas escrituras y devuelve un error
allkeys-lruExpulsa la clave que lleva más tiempo sin usarse entre todas las claves; es la opción más habitual para caché
volatile-lruExpulsa solo las claves que tienen configurado un tiempo de expiración
allkeys-lfuExpulsa las claves menos utilizadas

Prueba: escribe más datos que el límite

Usa la herramienta integrada redis-benchmark de Redis para escribir 300 000 registros de 500 bytes cada uno (unos 150 MB), muy por encima del límite de 64 MB:

$ docker run -d --name redis -v "$(pwd)/redis.conf:/usr/local/etc/redis/redis.conf:ro" -v redis_data:/data redis:8-alpine redis-server /usr/local/etc/redis/redis.conf
af187c21e0d6ecb0e9a0299200a6d866dc605d92c715e49df8a7abd850107040

$ docker exec -e REDISCLI_AUTH=change-me redis redis-cli CONFIG GET maxmemory*
maxmemory
67108864
maxmemory-clients
0
maxmemory-eviction-tenacity
10
maxmemory-samples
5
maxmemory-policy
allkeys-lru

$ docker exec redis redis-benchmark -a change-me -t set -n 300000 -r 300000 -d 500 -q
SET: 31043.05 requests per second, p50=0.903 msec

$ docker exec -e REDISCLI_AUTH=change-me redis redis-cli INFO memory | grep -E "^(used_memory_human|maxmemory_human|maxmemory_policy)"
used_memory_human:63.89M
maxmemory_human:64.00M
maxmemory_policy:allkeys-lru

$ docker exec -e REDISCLI_AUTH=change-me redis redis-cli INFO stats | grep evicted_keys
evicted_keys:95511

$ docker exec -e REDISCLI_AUTH=change-me redis redis-cli DBSIZE
115038

Forma de escribir en Windows (haz clic en las pestañas para cambiar):

docker run -d --name redis -v "$(pwd)/redis.conf:/usr/local/etc/redis/redis.conf:ro" -v redis_data:/data redis:8-alpine redis-server /usr/local/etc/redis/redis.conf
docker run -d --name redis -v "${PWD}/redis.conf:/usr/local/etc/redis/redis.conf:ro" -v redis_data:/data redis:8-alpine redis-server /usr/local/etc/redis/redis.conf
docker run -d --name redis -v "%cd%/redis.conf:/usr/local/etc/redis/redis.conf:ro" -v redis_data:/data redis:8-alpine redis-server /usr/local/etc/redis/redis.conf
  • CONFIG GET maxmemory* confirma que se ha aplicado el archivo de configuración: 67108864 bytes equivalen a 64 MB y la política es allkeys-lru.
  • Después de escribir, la memoria se queda en 63.89M, sin superar el límite.
  • evicted_keys:95511: se expulsaron automáticamente más de 90 000 claves y al final quedaron unas 115 000.

Repite la misma prueba con noeviction:

$ docker exec -e REDISCLI_AUTH=change-me redis redis-cli CONFIG SET maxmemory-policy noeviction
OK

$ docker exec -e REDISCLI_AUTH=change-me redis sh -c 'head -c 2000000 /dev/zero | tr "\\0" x | redis-cli -x SET big-value'
OOM command not allowed when used memory > 'maxmemory'.


$ docker exec -e REDISCLI_AUTH=change-me redis redis-cli GET greeting

La memoria está llena. Al intentar escribir un valor de 2 MB, aparece OOM command not allowed when used memory > 'maxmemory' y la aplicación falla. Por eso, usa allkeys-lru para una caché pura. Si Redis almacena datos que no se pueden perder, como una cola, usa noeviction y supervisa el uso de memoria.

Combinar aplicaciones en Compose

Crea un contador con Flask que incremente visits en Redis con cada solicitud:

redis-demo/
├── compose.yaml
├── .env
└── app/
    ├── app.py
    ├── requirements.txt
    └── Dockerfile

app/app.py:

import os

import redis
from flask import Flask

app = Flask(__name__)
r = redis.Redis.from_url(os.environ["REDIS_URL"], decode_responses=True)


@app.get("/")
def index():
    visits = r.incr("visits")
    return {"message": "Hello from Flask + Redis", "visits": visits}

app/requirements.txt:

flask==3.1.*
gunicorn==23.*
redis==6.*

app/Dockerfile (para ver una explicación de la sintaxis, consulta Aplicación Python):

FROM python:3.14-slim
ENV PYTHONUNBUFFERED=1 PIP_NO_CACHE_DIR=1
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
USER nobody
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]

.env:

REDIS_PASSWORD=change-this-password

compose.yaml:

services:
  app:
    build: ./app
    ports:
      - "8000:8000"
    environment:
      REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0
    depends_on:
      redis:
        condition: service_healthy

  redis:
    image: redis:8-alpine
    command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}", "--appendonly", "yes"]
    environment:
      REDISCLI_AUTH: ${REDIS_PASSWORD}
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD-SHELL", "redis-cli ping | grep -q PONG"]
      interval: 5s
      retries: 10
    restart: unless-stopped

volumes:
  redis_data:
ConfiguraciónDescripción
@redis:6379 en REDIS_URLConéctate usando el nombre del servicio
${REDIS_PASSWORD} en commandCompose lo sustituye por la contraseña real desde .env
REDISCLI_AUTHHace que redis-cli dentro del contenedor (incluida la comprobación de estado) envíe la contraseña automáticamente
redis no tiene portsSolo app necesita conectarse; no se expone al exterior
$ docker compose up -d --build

[+] Building 0.3s (12/12) FINISHED
 => [internal] load local bake definitions                                                                                                       0.0s
 => => reading from stdin 486B                                                                                                                   0.0s
 => [internal] load build definition from Dockerfile                                                                                             0.0s
 => => transferring dockerfile: 263B                                                                                                             0.0s
 => [internal] load metadata for docker.io/library/python:3.14-slim                                                                              0.0s
 => [internal] load .dockerignore                                                                                                                0.0s
 => => transferring context: 2B                                                                                                                  0.0s
 => [1/5] FROM docker.io/library/python:3.14-slim@sha256:a2b82f3c48559aa0a8446d9af49826b6e2b2016f4cd2afabfe6013ec53729170                        0.0s
 => => resolve docker.io/library/python:3.14-slim@sha256:a2b82f3c48559aa0a8446d9af49826b6e2b2016f4cd2afabfe6013ec53729170                        0.0s
 => [internal] load build context                                                                                                                0.0s
 => => transferring context: 93B                                                                                                                 0.0s
 => CACHED [2/5] WORKDIR /app                                                                                                                    0.0s
 => CACHED [3/5] COPY requirements.txt .                                                                                                         0.0s
 => CACHED [4/5] RUN pip install -r requirements.txt                                                                                             0.0s
 => CACHED [5/5] COPY . .                                                                                                                        0.0s
 => exporting to image                                                                                                                           0.0s
 => => exporting layers                                                                                                                          0.0s
 => => exporting manifest sha256:2cb1f769137117a44dde49bfb2f8551a8ce989fe8bd0a72696ba37987c29fd13                                                0.0s
 => => exporting config sha256:88373d2af6030b965f8b4e878d871e906738cd9194ec77bd007c6bbbace7c1b9                                                  0.0s
 => => exporting attestation manifest sha256:c8f570c26323c3e08476544296d44ed0e159d27d9f25b86bf879cd08c6b6e186                                    0.0s
 => => exporting manifest list sha256:46bd2450b425a935481fb6ef8567c915f5543996f4e35018bdb955ecf858b361                                           0.0s
 => => naming to docker.io/library/redis-demo-app:latest                                                                                         0.0s
 => => unpacking to docker.io/library/redis-demo-app:latest                                                                                      0.0s
 => resolving provenance for metadata file                                                                                                       0.0s
[+] up 5/5
 ✔ Image redis-demo-app         Built                                                                                                             0.4s
 ✔ Network redis-demo_default   Created                                                                                                           0.0s
 ✔ Volume redis-demo_redis_data Created                                                                                                           0.0s
 ✔ Container redis-demo-redis-1 Healthy                                                                                                           5.8s
 ✔ Container redis-demo-app-1   Started                                                                                                           5.9s

$ curl -s http://localhost:8000/
{"message":"Hello from Flask + Redis","visits":1}

$ curl -s http://localhost:8000/
{"message":"Hello from Flask + Redis","visits":2}

$ curl -s http://localhost:8000/
{"message":"Hello from Flask + Redis","visits":3}

La aplicación se inicia cuando Redis pasa a Healthy, y visits aumenta en 1 con cada solicitud. Como activaste AOF y montaste un Volume, el contador sigue aumentando después de recrear todos los contenedores:

$ docker compose up -d --force-recreate
[+] up 2/2
 ✔ Container redis-demo-redis-1 Healthy                                                                                                           6.1s
 ✔ Container redis-demo-app-1   Started                                                                                                           6.2s

$ curl -s http://localhost:8000/
{"message":"Hello from Flask + Redis","visits":4}

Por qué el health check busca PONG con grep

Una forma habitual de escribirlo en Internet es test: ["CMD", "redis-cli", "ping"]. Comprobemos su código de salida:

$ docker compose exec redis redis-cli ping; echo "exit code: $?"
PONG
exit code: 0

$ docker compose exec -e REDISCLI_AUTH=wrong redis redis-cli ping; echo "exit code: $?"
AUTH failed: WRONGPASS invalid username-password pair or user is disabled.
NOAUTH Authentication required.

exit code: 0

$ docker compose exec -e REDISCLI_AUTH=wrong redis sh -c "redis-cli ping | grep -q PONG"; echo "exit code: $?"
AUTH failed: WRONGPASS invalid username-password pair or user is disabled.
exit code: 1

Cuando la contraseña es incorrecta, redis-cli imprime NOAUTH Authentication required., pero el código de salida sigue siendo 0. Docker solo comprueba el código de salida para determinar si el servicio está en buen estado. Por eso, si la contraseña está mal, el health check se aprueba igualmente y la app falla al conectarse después de iniciarse. Al añadir | grep -q PONG, el código de salida solo es 0 cuando realmente se recibe PONG.

Comandos habituales de redis-cli

docker exec redis redis-cli INFO memory      # uso de memoria
docker exec redis redis-cli INFO stats       # estadísticas, incluidos evicted_keys
docker exec redis redis-cli DBSIZE           # cantidad de keys
docker exec redis redis-cli --scan --pattern 'session:*' | head
docker exec -it redis redis-cli MONITOR      # muestra todos los comandos en tiempo real (para depuración; afecta al rendimiento; termina con Ctrl+C)

Si has configurado una contraseña, añade -e REDISCLI_AUTH=contraseña a docker exec.

Evita usar KEYS * en producción: analiza todas las keys y bloquea Redis. Si hay muchas keys, puede quedarse bloqueado varios segundos. Usa SCAN en su lugar (redis-cli --scan).

Para explorar los datos con una interfaz gráfica, puedes usar Redis Insight, la herramienta oficial (imagen redis/redisinsight, puerto predeterminado 5540). La primera vez que la abras, debes leer y aceptar sus términos de licencia. Después, añade una conexión e indica el nombre del servicio de Compose redis como host, el puerto 6379 y la contraseña.

Acerca de las licencias de Redis y Valkey

En 2024, Redis cambió su licencia a opciones no open source como RSALv2 y SSPL. A partir de Redis 8, también añadió AGPLv3 como opción. En 2024, la Linux Foundation lanzó Valkey, una bifurcación open source compatible con licencia BSD. Sus comandos y su uso son casi idénticos:

$ docker run -d --name valkey valkey/valkey:8-alpine
Unable to find image 'valkey/valkey:8-alpine' locally
8-alpine: Pulling from valkey/valkey
Digest: sha256:081c2f5cb575efc901aa80ff9cdbd1ec6a301682fd35e1ebb4b0990a4a4a8507
Status: Downloaded newer image for valkey/valkey:8-alpine
3e7385b8f0d22a999ccf9306938e178c8f82bb4bc1ef9d304bd307917a890087

$ docker exec valkey valkey-cli PING
PONG

$ docker exec valkey redis-cli SET greeting hello
OK

$ docker exec valkey valkey-server --version
Valkey server v=8.1.10 sha=00000000:1 malloc=jemalloc-5.3.0 bits=64 build=fd3b186b1408478b

$ docker rm -f valkey
valkey

La imagen de Valkey incluye tanto valkey-cli como redis-cli, que es compatible, y las bibliotecas de Redis de las aplicaciones también pueden conectarse directamente. El cambio de licencia no afecta al uso personal habitual de Redis. Si vas a ofrecer Redis como servicio a terceros, comprueba las condiciones de la licencia.

Resumen

  • Redis no tiene contraseña de forma predeterminada. Configúrala con --requirepass y pásala mediante REDISCLI_AUTH.
  • RDB no guarda los datos en tiempo real. Activa --appendonly yes si necesitas fiabilidad.
  • Si lo usas como caché, configura maxmemory y allkeys-lru.
  • Escribe el health check como redis-cli ping | grep -q PONG.

Ejercicios

Ejercicio 1: Usa docker exec redis redis-cli para crear una key que caduque en 30 segundos y consulta el tiempo restante.

Respuesta
docker exec redis redis-cli SET temp hello EX 30
docker exec redis redis-cli TTL temp

Si hay una contraseña, añade -e REDISCLI_AUTH=contraseña.

Preguntas frecuentes

¿Es necesario configurar una contraseña para Redis?

Sí, siempre que otras personas puedan conectarse. Lo mejor es no exponer el puerto y configurar una contraseña.

¿Han desaparecido los datos después de reiniciar Redis?

RDB, que viene activado de forma predeterminada, escribe en el disco solo cuando se cumplen las condiciones de guardado o al detenerse correctamente; docker rm -f o un fallo pueden hacer que se pierdan datos. Activa AOF si necesitas conservarlos de forma fiable.

¿Valkey y Redis son intercambiables?

Valkey es una bifurcación de código abierto de Redis. Sus comandos y protocolo son compatibles, por lo que normalmente no hace falta modificar la aplicación.

Actualizado 14 de octubre de 2026