Docker Compose para Redis con contraseña
Un compose.yaml de Redis con contraseña (requirepass), persistencia AOF, healthcheck con redis-cli y puerto atado a localhost, más por qué un Redis sin AUTH y abierto se compromete en minutos.
Redis es rapidísimo y muy fácil de arrancar, y por eso es también muy fácil dejarlo mal configurado. Esta guía monta un Redis para desarrollo con dos cosas que mucha gente se salta: contraseña y persistencia. Sirve para usarlo como caché, cola o almacén de sesiones desde tu app local.
compose.yaml con AUTH y persistencia
services:
redis:
image: redis:7-alpine
restart: unless-stopped
command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}", "--appendonly", "yes"]
environment:
REDIS_PASSWORD: ${REDIS_PASSWORD}
ports:
- "127.0.0.1:6379:6379"
volumes:
- redis_data:/data
healthcheck:
test: ['CMD-SHELL', 'redis-cli -a "$$REDIS_PASSWORD" ping | grep -q PONG']
interval: 10s
timeout: 5s
retries: 5
start_period: 20s
volumes:
redis_data:El .env.example es de una sola línea. Cópialo a .env, pon una contraseña real y no subas el .env a git.
REDIS_PASSWORD=CHANGE_ME
Las decisiones que importan
- --requirepass. Activa la autenticación. Sin esto, cualquiera que alcance el puerto manda en tu Redis.
- command como lista. La forma exec deja que Compose sustituya
${REDIS_PASSWORD}desde el.envantes de arrancar, de modo que el servidor recibe la contraseña real. Una sola cadena sin shell dejaría la variable sin expandir. - --appendonly yes. Activa la persistencia AOF: cada escritura se registra en el volumen
redis_data:/data, así no pierdes todo si reinicias. - 127.0.0.1:6379:6379. El puerto solo se publica en tu loopback. Otros contenedores del compose llegan a Redis por su nombre (
redis:6379) sin necesidad de publicarlo. - healthcheck con redis-cli. Hace
pingautenticado y comprueba que respondePONG. Usa$$REDIS_PASSWORDpara que el$lo evalúe el shell dentro del contenedor.
Comprobar que funciona
docker compose up -d docker compose ps # debe aparecer healthy docker compose exec redis \ redis-cli -a "$REDIS_PASSWORD" ping # -> PONG docker compose exec redis \ redis-cli -a "$REDIS_PASSWORD" set saludo hola docker compose exec redis \ redis-cli -a "$REDIS_PASSWORD" get saludo
El riesgo de un Redis abierto
El incidente clásico: alguien publica 6379:6379 (sin 127.0.0.1) en un servidor y deja Redis sin contraseña. En cuestión de minutos un bot lo encuentra, escribe claves y, en los casos peores, consigue ejecución de comandos o borra todo con FLUSHALL. Dos hábitos lo evitan: contraseña siempre, y no publicar el puerto salvo que de verdad necesites acceso desde el host (y entonces, atado a loopback).
Siguientes pasos
Ajusta este stack en el generador de Docker Compose y vuelve al índice de ejemplos para combinar Redis con tu app o tu base de datos.
Preguntas frecuentes
- ¿Por qué el command va como lista ["redis-server", ...] y no como texto?
- Porque la forma de lista (exec) hace que Compose sustituya ${REDIS_PASSWORD} desde tu .env antes de arrancar el contenedor, así redis-server recibe la contraseña real. Si pones el command como una sola cadena, no pasa por una shell y la variable puede quedarse literal. La contraprestación es que docker compose config mostrará la contraseña ya sustituida: es asumible en local, pero por eso el secreto vive en el .env y no en el compose.
- ¿De verdad importa poner contraseña a Redis en local?
- Importa en cuanto publicas el puerto. Redis sin requirepass acepta cualquier comando de quien llegue, incluido FLUSHALL o escribir claves para ejecución remota. Hay bots que escanean el 6379 abierto a Internet de forma constante. En local con el puerto atado a 127.0.0.1 el riesgo baja mucho, pero acostúmbrate a poner AUTH siempre: el día que ese compose acabe en un servidor con el puerto abierto, ya estará protegido.
- ¿Qué diferencia hay entre AOF y RDB?
- Son las dos formas de persistir Redis. RDB hace snapshots periódicos del dataset (rápido, pero puedes perder lo último entre snapshots). AOF (--appendonly yes) registra cada escritura, así que pierdes menos datos ante un corte, a cambio de archivos mayores. Para desarrollo, AOF en el volumen /data es una opción sencilla y segura. Si usas Redis solo como caché de usar y tirar, puedes prescindir de persistencia.
- Me sale (error) NOAUTH Authentication required, ¿qué hago?
- Significa que Redis tiene contraseña pero tu cliente no la envía. Conéctate con redis-cli -a "$REDIS_PASSWORD" o, dentro del contenedor, docker compose exec redis redis-cli -a "$REDIS_PASSWORD". Si en su lugar ves (error) WRONGPASS, la contraseña no coincide: revisa que el .env y lo que pasa tu app sean el mismo valor y que no hayas dejado un volumen viejo con otra configuración.
- ¿Esto sirve para producción?
- Es un punto de partida para desarrollo. En producción no publicarías el puerto al host, tratarías la contraseña como un secreto gestionado fuera de git, decidirías la política de persistencia y memoria (maxmemory, política de expulsión) según el uso, y valorarías réplicas o un Redis gestionado. La idea aquí es que aprendas el patrón correcto, no que despliegues esto tal cual de cara a usuarios.