How do you perform a HEALTHCHECK in the Redis Docker image?
Asked Answered
M

4

63

Recently, we had an outage due to Redis being unable to write to a file system (not sure why it's Amazon EFS) anyway I noted that there was no actual HEALTHCHECK set up for the Docker service to make sure it is running correctly, Redis is up so I can't simply use nc -z to check if the port is open.

Is there a command I can execute in the redis:6-alpine (or non-alpine) image that I can put in the healthcheck block of the docker-compose.yml file.

Note I am looking for command that is available internally in the image. Not an external healthcheck.

Mariel answered 9/6, 2021 at 12:56 Comment(0)
M
67

Although the ping operation from @nitrin0 answer generally works. It does not handle the case where the write operation will actually fail. So instead I perform a change that will just increment a value to a key I don't plan to use.

image: redis:6
healthcheck:
  test: [ "CMD", "redis-cli", "--raw", "incr", "ping" ]

Note this MUST NOT be performed on a cluster that is initialized by Docker. Since this health check will prevent the cluster from being formed as the Redis are not empty.

Mariel answered 14/1, 2022 at 6:7 Comment(1)
if you have a password for redis, you can use: test: [ "CMD", "redis-cli", "-a", "password", "--raw", "incr", "ping" ]Lasky
A
48

If I remember correctly that image includes redis-cli so, maybe, something along these lines:

...
healthcheck:
   test: ["CMD", "redis-cli","ping"]
Adenoma answered 9/6, 2021 at 13:33 Comment(0)
G
44

I've just noticed that there is a phase in which redis is still starting up and loading data. In this phase, redis-cli ping shows the error

LOADING Redis is loading the dataset in memory

but stills returns the exit code 0, which would make redis already report has healthy.

Also redis-cli --raw incr ping returns 0 in this phase without actually incrementing this key successfully.

As a workaround, I'm checking whether the redis-cli ping actually prints a PONG, which it only does after the LOADING has been finished.

services:
  redis:
    healthcheck:
      test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
      interval: 1s
      timeout: 3s
      retries: 5

This works because grep returns only 0 when the string ("PONG") is found.

Gyn answered 16/3, 2022 at 21:51 Comment(7)
[ "$(redis-cli ping)" = "PONG" ] for exact matchAleishaalejandra
Adding to that, here is how it can look in the yaml: test: "[ $$(redis-cli -a $REDIS_PASSWORD ping) = 'PONG' ]"Carat
Or simply test: redis-cli -a ${REDIS_PASSWORD} ping | grep PONG using grep. Note, this is equivalent to CMD-SHELL per docs.docker.com/compose/compose-file/compose-file-v3Carat
Or if you're using Docker secrets: test: ["CMD-SHELL", "redis-cli --no-auth-warning -a \"$$(cat $$REDIS_PASSWORD_FILE)\" ping | grep PONG"]Wagshul
Redis does not recommend use of -a and -u options for providing auth password. Here is what I came up with: test: ["CMD-SHELL", "echo 'auth ${REDIS_PASSWORD}\nping' | redis-cli | grep PONG"]Hysterics
If docker is configured to restart unhealthy containers, I would either recommend setting a start_period corresponding to the expected Redis loading time or not to use grep PONG. When starting up redis, loading the dataset in memory is a healthy state...even if the redis server is not usable.Rearm
what would be a kubernetes readinessProbe equivalent? readinessProbe: exec: command: - /bin/sh - -c - redis-cli ping | grep PONG will work?Adrianople
E
4

You can also add it inside the Dockerfile if your using a Redis image that contains the redis-cli:

Linux Docker

HEALTHCHECK CMD redis-cli ping || exit 1

Windows Docker

HEALTHCHECK CMD pwsh.exe -command \
try { \
    $response = ./redis-cli ping; \
    if ($response -eq 'PONG') { return 0} else {return 1}; \
} catch { return 1 }
Easter answered 3/8, 2021 at 11:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.