Redis Docker Compose: The Complete Setup Guide

Redis Docker Compose: The Complete Setup and Caching Guide

Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

Adding a cache layer used to mean provisioning a separate service, wiring up network rules, and hoping the versions matched. A Redis Docker Compose setup collapses all of that into a few lines of YAML: one service block, one shared network, and Redis is reachable from every other container in your stack by name.

This guide walks through a production-ready Redis Docker Compose configuration, how to persist data across restarts, how to secure the connection with a password, and the mistakes that cause the most confusion when people wire Redis into an existing Postgres Docker Compose stack.

What a Redis Docker Compose Setup Actually Gives You

At its simplest, a Redis Docker Compose service is just an image reference and a port:

yaml
services:
cache:
image: redis:7-alpine
ports:
- "6379:6379"
`

That's enough to get Redis running, but a real Redis Docker Compose stack needs three more things most tutorials skip: a named volume for persistence, a password, and a healthcheck so dependent services don't start before Redis is actually ready to accept connections.

A Complete Redis Docker Compose Configuration

Here's a realistic Redis Docker Compose file for an API that uses Redis for session storage and caching, alongside Postgres for durable data:

`yaml
services:
api:
build: .
environment:
- REDIS_URL=redis://:$REDIS_PASSWORD@cache:6379
depends_on:
cache:
condition: service_healthy

cache:
image: redis:7-alpine
command: redis-server --requirepass $REDIS_PASSWORD --appendonly yes
volumes:
- redis_data:/data
healthcheck:
test: [CMD, redis-cli, --raw, -a, $REDIS_PASSWORD, ping]

volumes:
redis_data:
`

Every other service resolves the cache by its Compose service name, cache:6379, because Compose gives the project its own internal bridge network automatically. That's the core advantage of a Redis Docker Compose deployment over running docker run redis by hand.

Why the Healthcheck Matters

Without a healthcheck, depends_on only waits for the Redis container to start, not for the Redis server inside it to finish loading. The condition: service_healthy clause blocks the api service until redis-cli ping actually succeeds.

Persisting Redis Data with Docker Compose Volumes

By default, Redis is an in-memory store, restart the container and everything is gone. A Redis Docker Compose setup that cares about surviving restarts needs a named volume plus one of Redis's two persistence modes.

  • RDB snapshotting: periodic point-in-time dumps, smaller files, faster restarts, but you can lose the last few minutes of writes
  • AOF append-only file: logs every write operation, safer, larger on disk, slightly slower recovery on huge datasets
  • Checking That Persistence Is Actually Working

    `bash
    docker compose exec cache redis-cli -a $REDIS_PASSWORD set healthcheck ok
    docker compose down
    docker compose up -d
    docker compose exec cache redis-cli -a $REDIS_PASSWORD get healthcheck
    `

    If the second get returns ok, your Redis Docker Compose volume is correctly mounted and persistence is active.

    Securing a Redis Docker Compose Service

    Redis binds with no authentication by default, which is fine on an isolated Compose network but dangerous the moment a port gets accidentally exposed to the host or the internet.

  • Set –requirepass so every client needs a password, injected via a .env file
  • Drop the ports: mapping entirely unless you need to reach Redis from outside the Compose network
  • Common Redis Docker Compose Patterns

  • Session store: Express, Django, and Rails all have first-party Redis session adapters
  • Rate limiting: token-bucket limiters backed by Redis's atomic INCR and EXPIRE commands
  • Job queues: libraries like BullMQ or Celery use Redis as the broker between web and worker processes
  • Full-page and query caching: cache expensive database results with a TTL
  • Troubleshooting a Redis Docker Compose Stack

  • Connection refused from the app container: add the healthcheck shown above instead of a fixed sleep
  • NOAUTH Authentication required: confirm the connection string includes the password segment
  • Data disappears after docker compose down: check the volumes: mapping, or you ran docker compose down -v
  • High memory usage: set maxmemory and maxmemory-policy allkeys-lru in the command: block
  • Hosting a Redis Docker Compose Stack in Production

    Redis is memory-hungry by design. If you're outgrowing a budget droplet, DigitalOcean makes it easy to resize RAM, and Hetzner is a solid budget option. BetterStack gives you uptime monitoring for a wedged Redis container, and Cloudflare keeps DNS and TLS predictable in front of your API.

    Once your Redis Docker Compose service is stable, docker compose down is the safe way to stop it without touching the redis_data volume. Our guide to Docker Compose environment variables covers .env file precedence in more depth.

    Monitoring a Redis Docker Compose Service

    Once a Redis Docker Compose stack is running in production, memory pressure is the metric that matters most, since Redis keeps its entire working set in RAM. Two commands make quick diagnostics easy:

    `bash
    docker compose exec cache redis-cli -a $REDIS_PASSWORD info memory
    docker compose exec cache redis-cli -a $REDIS_PASSWORD info stats
    `

    The info memory output shows used_memory_human and maxmemory_human; if the two are converging, it's time to either raise the container's memory limit or tighten your maxmemory-policy. The info stats output includes keyspace_hits and keyspace_misses — a rising miss ratio over time usually means your cache TTLs are too short or your working set has outgrown the box.

    Setting Resource Limits in the Compose File

    A Redis Docker Compose service without a memory ceiling can consume all available host RAM during a traffic spike, starving the database and app containers sharing the same VPS. Pin it explicitly:

    `yaml
    cache:
    image: redis:7-alpine
    deploy:
    resources:
    limits:
    memory: 512M
    `

    Combined with maxmemory 400mb inside the command: block, this keeps a single Redis Docker Compose service from taking down its neighbors when key eviction alone isn't fast enough.

    Redis Docker Compose with Multiple Logical Databases

    Redis ships with 16 numbered logical databases (0-15) inside a single instance, selectable with SELECT n from redis-cli. For a small Redis Docker Compose stack running a cache and a job queue side by side, putting each on its own numbered database avoids a FLUSHDB in one context accidentally wiping the other. For anything beyond a handful of services, most teams prefer key prefixing (session:, queue:, cache:) over numbered databases, since prefixes show up clearly in monitoring dashboards while a bare database number does not.

    Recommended: Want to explore DigitalOcean yourself? DigitalOcean is a direct vendor link (not an affiliate/tracked link).

    FAQ

    Do I need a separate Dockerfile for Redis in a Docker Compose stack?
    No. Use the official
    redis:7-alpine image directly in your Redis Docker Compose file — you only need a custom Dockerfile if you're baking in custom modules that can't be passed via command: flags.

    Does Redis Docker Compose data survive docker compose down?
    Yes, as long as you're using a named volume and skip the
    -v flag. Plain docker compose down removes containers and networks but leaves volumes, and therefore your Redis data, intact.

    What's the difference between RDB and AOF persistence in a Redis Docker Compose setup?
    RDB snapshots recover faster but can lose a few minutes of recent writes; AOF logs every write and is safer but slightly slower to replay on restart. Many production Redis Docker Compose stacks enable both for defense in depth.

    Can multiple services share one Redis Docker Compose instance?
    Yes — use separate numbered Redis databases or key prefixing per service, so a cache flush in one service doesn't wipe session data for another.

    Is it safe to run one Redis Docker Compose instance for both caching and a job queue?
    Yes, as long as you isolate them with separate logical databases or key prefixes and set eviction policies that only apply to cache keys — you don't want
    allkeys-lru evicting queue jobs still waiting to be processed.

    How much RAM does a small Redis Docker Compose service actually need?
    For a low-traffic app using Redis purely for sessions and light caching, 128-256MB is typically enough; job queues holding large payloads need considerably more, and
    info memory is the fastest way to check actual usage rather than guessing.

    Wrapping Up

    A Redis Docker Compose setup is a handful of YAML lines once you know the pieces that matter: a named volume for persistence, –requirepass plus a .env` file for security, a healthcheck so dependent services wait for Redis to be truly ready, and a memory limit so one noisy cache doesn’t starve the rest of the stack. Get those right and Redis becomes a boring, reliable part of your stack instead of a source of cold-start races and vanished cache data.

    Comments

    Leave a Reply

    Your email address will not be published. Required fields are marked *