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 leaveportsout entirely: other services reachcache:6379on the project network. docker compose down -vdeletesredis-dataand the snapshot in it.redis:latestfollows 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