Redis with Docker
Redis is an in-memory key-value store commonly used for caching, sessions, pub/sub and short-lived data. This docker redis tutorial shows how to run Redis in Docker, connect from an app, and cover caching basics and common pitfalls.
Concept explained
- Redis stores data in memory (very fast) and supports simple types: strings, lists, sets, hashes, sorted sets.
- Persistence is optional: RDB snapshots and AOF can persist data, but Redis is not a replacement for durable SQL/NoSQL databases.
- In Docker, treat Redis as a stateful service:
- use volumes for persistence,
- keep network access internal to your project,
- tune memory and eviction policy for caching use-cases.
tip
In Docker Compose, services can reach Redis using the service name (e.g., redis
) as hostname.
Step-by-step example
- Run a quick Redis container locally
# simple test container
docker run -d --name redis -p 6379:6379 redis:7
# quick health check
docker exec -it redis redis-cli ping
# expected output: PONG
- Minimal docker-compose (Redis + app environment variable)
# docker-compose.yml
services:
app:
build: .
environment:
- REDIS_HOST=redis
depends_on:
- redis
redis:
image: redis:7
volumes:
- redis-data:/data
command: ["redis-server", "--appendonly", "yes"]
volumes:
redis-data:
- Connect from a Node app (example)
# in your app container or local project
npm install redis
// src/redis-sample.js
const { createClient } = require("redis");
async function main() {
const client = createClient({ url: "redis://redis:6379" }); // in Compose, hostname is 'redis'
client.on("error", (err) => console.error("Redis error", err));
await client.connect();
await client.set("greeting", "hello from Redis");
const val = await client.get("greeting");
console.log(val); // -> hello from Redis
await client.quit();
}
main().catch(console.error);
- Add a password (simple example)
# redis service snippet
redis:
image: redis:7
command: ["redis-server", "--requirepass", "s3cr3t", "--appendonly", "yes"]
Connect with URL: redis://:s3cr3t@redis:6379
caution
Do not expose Redis directly to the public internet. Use network controls, firewalls, or private service networks.
Variations & gotchas
- Persistence:
- RDB snapshots are fast but infrequent; AOF is more durable but larger.
- If you need strict durability, Redis may not be ideal as the primary store.
- Memory limits:
- Redis keeps data in RAM. Set
maxmemory
and an eviction policy (e.g.,allkeys-lru
) for cache use.
- Redis keeps data in RAM. Set
- TLS / Authentication:
- Official Redis image doesn't enable TLS by default. For encrypted connections, use a proxy or a Redis build with TLS.
- Compose networking:
- Use the service name (not
localhost
) inside other services. From your host, use published ports.
- Use the service name (not
Common mistakes
- Expecting data to persist without a volume (data lost on container recreate).
- Exposing port 6379 to the internet without auth or firewall.
- Using Redis as the single source of truth for large datasets (runs out of RAM).
- Creating many short-lived connections instead of reusing a pool.
- Forgetting to tune eviction policy for caching workloads.
Best practices
- Use a named volume for /data if you need persistence.
- For caching: set
maxmemory
and choose an eviction policy (e.g.,volatile-lru
orallkeys-lru
). - Reuse connections (connection pooling) in your app.
- Keep Redis accessible only to services that need it; don't publish 6379 publicly.
- Monitor memory, hits/misses, and latency; adjust TTLs and sizes accordingly.
When to use / when not to use
When to use Redis:
- Fast caches for computed responses, API rate limiting, session stores, pub/sub for real-time features. When not to use Redis:
- As the only durable datastore for large datasets that don't fit in memory.
- For multi-terabyte datasets unless sharded and carefully managed.
Key takeaways
- Redis is great for fast, in-memory caching and short-lived state; it is not a drop-in durable database.
- In Docker, use volumes for persistence, service names for internal networking, and avoid exposing Redis publicly.
- Tune memory and eviction settings for cache workloads and reuse connections in your app.
- Monitor Redis usage (memory, hits/misses) and plan for eviction and persistence trade-offs.