Redis
| Use | Image | Status |
|---|---|---|
| Redis | redis:8.8.2-trixie | default |
Pinned, as every compose file and Dockerfile writes them:
redis:8.8.2-trixie@sha256:37227fff5638322f4ebea25d6d0dc3ee50848604e82b81426f11507b3ec7d2ccThe tag and digest come from the approved images table; when they disagree, the table wins.
Local development
docker run -d --name redis-dev \
-p 127.0.0.1:6379:6379 \
-v redis-dev-data:/data \
--health-cmd 'redis-cli ping | grep -q PONG' \
--health-interval 5s --health-timeout 5s --health-retries 10 \
redis:8.8.2-trixie@sha256:37227fff5638322f4ebea25d6d0dc3ee50848604e82b81426f11507b3ec7d2cc \
redis-server --appendonly yesdocker exec redis-dev redis-cli set hello world
docker exec redis-dev redis-cli get helloConnect with redis://127.0.0.1:6379/0; there is no password locally. Remove it, data included, with docker rm -f redis-dev && docker volume rm redis-dev-data.
On a server
Prepare the host once, next to the compose file. Redis reads its password from its config file, so the config is a folder mounted read-only (see config mounts) and owned by the redis user.
mkdir -p redis
cat > redis/redis.conf <<CONF
appendonly yes
requirepass $(openssl rand -hex 24)
CONF
sudo chown -R 999:999 redis
sudo chmod 0400 redis/redis.confservices:
redis:
image: redis:8.8.2-trixie@sha256:37227fff5638322f4ebea25d6d0dc3ee50848604e82b81426f11507b3ec7d2cc
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
volumes:
- ./redis:/usr/local/etc/redis:ro
- redis-data:/data
ports:
- "127.0.0.1:6379:6379"
read_only: true
cap_drop: [ALL]
cap_add: [CHOWN, SETGID, SETPCAP, SETUID]
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD", "setpriv", "--reuid=redis", "--regid=redis", "--clear-groups", "sh", "-c", "REDISCLI_AUTH=\"$$(sed -n 's/^requirepass //p' /usr/local/etc/redis/redis.conf)\" redis-cli ping | grep -q PONG"]
interval: 10s
timeout: 5s
retries: 5
stop_grace_period: 30s
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
volumes:
redis-data: {}docker compose exec -u redis redis sh -c 'REDISCLI_AUTH="$(sed -n "s/^requirepass //p" /usr/local/etc/redis/redis.conf)" redis-cli set hello world'The service connects with the same password, from its own .env, as redis://:<password>@redis:6379/0.
Why each line is there:
appendonly yes. Every write is logged to disk, so a restart loses at most a second of writes instead of everything since the last snapshot.- The password in a config folder, not on the command line. A
--requirepassargument is visible to anyone who can runpsordocker inspect. REDISCLI_AUTHin the health check, for the same reason:redis-cli -aputs the password on the command line. The check runs as theredisuser (setpriv), because only that user can read the config.- The capabilities. The entrypoint starts as root, fixes the data folder's owner and drops to the
redisuser (999) withsetpriv; these four are what that needs. read_only. Redis writes only to/data.- Port on
127.0.0.1. Never publish Redis on0.0.0.0: an exposed Redis is taken over within hours.
Upgrading
Replace every redis:latest with the pinned tag. Moving from 7.x to 8 is an image change and a restart; take a snapshot first (redis-cli BGSAVE, then copy dump.rdb).