Redis in Docker Compose

services: some-redis: image: redis:8.10 command: redis-server --save 60 1 --loglevel warning

In Docker Compose, the words after the image in docker run become the service’s command:, so Redis’s persistent-storage command turns into command: redis-server --save 60 1 --loglevel warning. That snapshots the dataset to /data/dump.rdb every 60 seconds when at least one key changed, which only survives if a volume is mounted at /data.

The docker run command, converted

The “start with persistent storage” command from the image’s Docker Hub page, with the tag pinned:

docker run --name some-redis -d redis:8.10 redis-server --save 60 1 --loglevel warning
services:
  some-redis:
    image: redis:8.10
    command: redis-server --save 60 1 --loglevel warning

The command has no -v, and redis:8.10 declares no VOLUME (the 7.2 image declared /data). So dump.rdb is written inside the container, and docker compose down removes it with the container. Without --save, Redis still snapshots on its default schedule, 3600 1 300 100 60 10000. --appendonly yes logs every write to an append-only file as well.

A cache the app waits for

services:
  cache:
    image: redis:8.10
    command: redis-server --save 60 1 --loglevel warning
    volumes:
      - redis-data:/data
    ports:
      - "127.0.0.1:6379:6379"
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5
  app:
    image: example/app:1.0
    environment:
      REDIS_URL: redis://cache:6379
    depends_on:
      cache:
        condition: service_healthy
volumes:
  redis-data:

With a password

The image turns protected mode off so other containers can connect, which also means a published port answers anyone, with no password. Once you set one, a plain redis-cli ping gets NOAUTH Authentication required. and still exits 0, so the check would pass whatever the password is. REDISCLI_AUTH gives redis-cli the password without putting it on the command line:

services:
  cache:
    image: redis:8.10
    command: redis-server --save 60 1 --loglevel warning --requirepass "${REDIS_PASSWORD}"
    environment:
      REDIS_PASSWORD: ${REDIS_PASSWORD}
    volumes:
      - redis-data:/data
    healthcheck:
      test: ["CMD-SHELL", "REDISCLI_AUTH=\"$$REDIS_PASSWORD\" redis-cli ping | grep -q PONG"]
      interval: 5s
      timeout: 3s
      retries: 5
volumes:
  redis-data:

Compose fills in ${REDIS_PASSWORD} from .env or the shell when it reads the file. $$ is a literal dollar, so the container’s shell expands that one when the check runs.

Gotchas

  • Keep the port on 127.0.0.1, or leave ports out entirely: other services reach cache:6379 on the project network.
  • docker compose down -v deletes redis-data and the snapshot in it.
  • redis:latest follows the newest release (8.10 today). Pin the series, so a pull doesn’t change the server under the data.

GitHub Actions

services:
  redis:
    image: redis:8.10
    ports:
      - 6379:6379
    options: >-
      --health-cmd "redis-cli ping"
      --health-interval 5s
      --health-retries 10

Try it in the docker run to Compose Converter

compose.yaml

1 service · 1 thing left out

Left out, and why

  • -dCompose starts services in the background already, so this flag needs no key.

Runs in your browser. Nothing you enter is sent anywhere.