Redis Self-Hosted con Docker: Caché y Colas para tus Servicios
- Fabrizio Piminchumo
- Application , Technology
- 15 Apr, 2026
Con PostgreSQL ya desplegado como base de datos persistente, el último componente de la infraestructura base es Redis. En el stack de n8n en alta disponibilidad lo usamos como broker de cola para el modo queue, pero Redis es mucho más versátil que eso: caché de sesiones, pub/sub, rate limiting, leaderboards, almacenamiento temporal — prácticamente cualquier servicio que despliegues en esta serie va a querer una instancia Redis cerca.
La decisión de tener una sola instancia Redis compartida entre servicios, en lugar de una por servicio, es la que guía toda la configuración que vamos a analizar.
¿Por qué Redis 7?
image: redis:7
Redis 7 trajo cambios significativos respecto a versiones anteriores:
- Redis Functions: reemplaza a los scripts Lua con un modelo más estructurado y persistente
- Multi-Part AOF: el log de persistencia se divide en archivos más pequeños y manejables
- Mejoras en ACL v2: control de acceso más granular por usuario y comando
- Mejor rendimiento en operaciones sobre estructuras de datos complejas (streams, sorted sets)
Para el uso que le damos — broker de colas con Bull y caché general — Redis 7 es la versión estable más recomendada. El tag :7 te da la última versión dentro de la rama 7.x con parches de seguridad incluidos.
El docker-compose.yml
services:
redis:
image: redis:7
container_name: redis
restart: unless-stopped
command: redis-server --requirepass TU_REDIS_PASSWORD --databases 32
ports:
- "127.0.0.1:6379:6379"
volumes:
- redis_data:/data
networks:
- backend-net
volumes:
redis_data:
networks:
backend-net:
external: true
Análisis de las decisiones de configuración
Autenticación por command, no por archivo de configuración
command: redis-server --requirepass TU_REDIS_PASSWORD --databases 32
Redis admite dos formas de configurarse: mediante un archivo redis.conf montado como volumen, o pasando flags directamente al comando de inicio. Para una configuración mínima como esta, pasar los parámetros por command es más transparente — todo lo que necesitas saber está visible en el compose, sin tener que buscar un archivo externo.
Si en algún momento la configuración crece (maxmemory, políticas de eviction, AOF persistence, ACL), lo correcto es migrar a un archivo:
command: redis-server /etc/redis/redis.conf
volumes:
- ./redis.conf:/etc/redis/redis.conf
- redis_data:/data
Pero para el caso de uso actual, los dos flags son suficientes.
—requirepass: autenticación obligatoria
--requirepass TU_REDIS_PASSWORD
Sin esta flag, Redis acepta conexiones sin autenticación — cualquier proceso que llegue a la red puede leer y escribir datos. En una red Docker privada hay cierto aislamiento, pero si algún contenedor comprometido llega a backend-net, tendría acceso total a Redis sin credenciales.
Para generar una contraseña segura:
openssl rand -base64 32
Redis es sensible a la latencia, así que la contraseña se valida una sola vez al conectar y no impacta el rendimiento posterior.
Nota: En versiones antiguas de Redis,
--requirepassse podía eludir con el comandoCONFIG SET requirepass "". Desde Redis 7, si tienes ACL configuradas, esto ya no es posible sin los permisos adecuados.
—databases 32: instancia compartida entre servicios
--databases 32
Redis por defecto crea 16 bases de datos lógicas (numeradas del 0 al 15). Expandir a 32 responde a una decisión de arquitectura: una sola instancia Redis para todos los servicios, con cada uno usando una base de datos distinta para aislar sus datos.
Esto es más eficiente que levantar un Redis por servicio porque:
- Un proceso Redis consume ~5MB de RAM en idle — con 5 servicios son 25MB vs 5MB compartido
- Menos contenedores que monitorear y actualizar
- Las conexiones entre servicios y Redis son más eficientes (misma red, mismo host)
La distribución de bases de datos que usamos en esta serie:
| DB | Servicio | Uso |
|---|---|---|
| 0 | n8n | Cola Bull (ejecuciones de flujos) |
| 1 | Reservado | Caché general |
| 2 | Reservado | Sesiones |
| 3+ | Futuros servicios | A asignar |
Cuando conectes un nuevo servicio, elige la siguiente base de datos disponible. Con 32 tienes margen suficiente para crecer sin tocar la configuración.
container_name y hostname en la red
container_name: redis
Al igual que con PostgreSQL, el container_name registra ese nombre como hostname en la red Docker. Esto es lo que permite a n8n conectarse con:
- QUEUE_BULL_REDIS_HOST=redis
Sin container_name, el hostname en la red sería el nombre del servicio en el compose (que en este caso es redis de todas formas). Fijarlo explícitamente lo hace predecible independientemente de cómo se llame el servicio en el compose.
Puerto: enlazar solo a localhost
La configuración original expone el puerto a todas las interfaces:
ports:
- "6379:6379" # ⚠️ accesible desde cualquier IP
Al igual que con PostgreSQL, lo correcto para producción es enlazarlo solo a localhost:
ports:
- "127.0.0.1:6379:6379" # solo accesible desde el propio servidor
Los servicios dentro de backend-net se conectan directamente por la red Docker sin pasar por el puerto del host — esta restricción solo afecta el acceso externo.
Para administración remota, usa un túnel SSH:
ssh -L 6379:localhost:6379 usuario@tu-servidor
# Luego conecta con redis-cli o RedisInsight en localhost:6379
restart: unless-stopped
Consistente con PostgreSQL: Redis es infraestructura que puedes necesitar detener para mantenimiento (flush de datos, cambio de configuración, upgrade). Con unless-stopped, un docker stop redis no se revierte automáticamente.
Volumen local
volumes:
redis_data:
Redis puede operar completamente en memoria (sin persistencia en disco) o con AOF/RDB habilitado. En esta configuración, el volumen redis_data está montado pero la persistencia por defecto de Redis 7 es RDB snapshot — guarda el estado en disco periódicamente, lo que permite recuperar datos tras un reinicio del contenedor.
Para el uso como broker de colas de n8n, esto es relevante: si Redis se reinicia sin persistencia, las ejecuciones en cola se pierden. Con el volumen y RDB, se recuperan automáticamente al volver a levantar.
Si quieres persistencia más estricta (sin pérdida de datos entre snapshots), activa AOF:
command: redis-server --requirepass TU_REDIS_PASSWORD --databases 32 --appendonly yes
Levantar el stack
# La red debe existir (se crea una sola vez por servidor)
docker network create backend-net
# Levantar Redis
docker compose up -d
# Verificar que está corriendo
docker compose ps
# Conectarse a redis-cli dentro del contenedor
docker exec -it redis redis-cli -a TU_REDIS_PASSWORD
# Verificar las bases de datos disponibles
127.0.0.1:6379> CONFIG GET databases
# Ver logs
docker compose logs -f redis
Comandos útiles de administración
# Ver todas las claves de la DB actual
docker exec -it redis redis-cli -a TU_REDIS_PASSWORD KEYS "*"
# Cambiar a la base de datos 1
docker exec -it redis redis-cli -a TU_REDIS_PASSWORD -n 1
# Ver cuánta memoria está usando
docker exec -it redis redis-cli -a TU_REDIS_PASSWORD INFO memory
# Ver el estado de las colas de n8n (DB 0)
docker exec -it redis redis-cli -a TU_REDIS_PASSWORD -n 0 KEYS "bull:*"
Infraestructura base completa
Con Redis levantado, tienes los tres componentes que forman la base de la serie:
backend-net
├── postgres (pgvector:pg16) → persistencia relacional + vectores
├── redis (redis:7) → caché, colas, estado efímero
└── n8n (n8n + workers) → automatización, conectado a ambos
Cualquier servicio nuevo que despliegues puede unirse a backend-net y acceder a PostgreSQL y Redis inmediatamente, sin modificar los stacks existentes.
Consideraciones para producción
- maxmemory: Sin límite configurado, Redis usará toda la RAM disponible si los datos crecen indefinidamente. Define un límite y una política de eviction:
command: redis-server --requirepass TU_REDIS_PASSWORD --databases 32 --maxmemory 512mb --maxmemory-policy allkeys-lru
-
Monitoreo: El comando
INFO statsdentro deredis-climuestra hits/misses de caché, conexiones activas y comandos procesados por segundo. Herramientas como RedisInsight ofrecen una interfaz visual. -
No uses la DB 0 para múltiples propósitos: Mantener una base de datos por servicio/propósito hace el debugging mucho más fácil — puedes hacer
FLUSHDBen una base de datos sin afectar las demás.