Skip to main content

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

  1. 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
  1. 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:
  1. 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);
  1. 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.
  • 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.

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 or allkeys-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.