34

I'm trying to run rabbitMQ using docker-compose, but the service is always starting or unhealthy.
rabbit is running fine, so I suspect there is something wrong with my health check.

Running the healthcheck command locally does return a value.

> curl -f http://localhost:5672
AMQP    %

But docker-compose ps always says the service is unhealthy (or starting, before it runs out of time).

> docker-compose ps
docker-entrypoint.sh rabbi ...   Up (unhealthy)   15671/tcp

Here is what my docker-compose.yml file looks like.

# docker-compose.yml
version: '2.3' # note: I can't change this version, must be 2.3

volumes: rabbit-data:

services: rabbit: hostname: 'rabbit' image: rabbitmq:3.8.5-management healthcheck: test: ["CMD", "curl", "-f", "http://localhost:5672"] interval: 30s timeout: 30s retries: 3 ports: - '5672:5672' - '15672:15672' volumes: - 'rabbit-data:/var/lib/rabbitmq/mnesia/' networks: - rabbitmq

networks: rabbitmq: driver: bridge

I have also tried using nc instead of curl in the healthcheck, but got the same result.

healthcheck:
  test: [ "CMD", "nc", "-z", "localhost", "5672" ]

From https://github.com/docker-library/rabbitmq/issues/326

ConorSheehan1
  • 515
  • 1
  • 7
  • 10

5 Answers5

51

You could use the command rabbitmq-diagnostics -q ping in case you just need a basic check.

healthcheck:
  test: rabbitmq-diagnostics -q ping
  interval: 30s
  timeout: 30s
  retries: 3

More information on how to run more advanced health checks could be found here

pmodernell
  • 626
  • 6
  • 3
9

If rabbitmq-diagnostics -q ping not working for you, check this

healthcheck:
  test: rabbitmq-diagnostics check_port_connectivity
  interval: 1s
  timeout: 3s
  retries: 30

In my example I also reduced interval.

shes
  • 91
  • 1
  • 1
9

I just want to add to above answers about rabbitmq-diagnostics, which worked great, however there was one missing part.

    depends_on:
      rabbitmq:
        condition: service_healthy

rabbitmq: image: rabbitmq:3.8.17-management healthcheck: test: rabbitmq-diagnostics check_port_connectivity interval: 30s timeout: 30s retries: 10

With that my dependent service waits exactly what is needed to.

coffekid
  • 191
  • 1
  • 3
2

Your solution is good if you do not own / control the RabbitMQ Compose code but still have to check the service presence and your RabbitMQ image contains the management plugin.

First of all you are using curl which sends an HTTP request which on the other hand rabbitmq is not HTTP.

To fix this you can modify you command as follows:

# Note the port 15672 is the RabbitMQ Management UI port
# It responds with 200 OK and the HTML page which is acceptable for a healcheck
test: ["CMD", "curl", "-f", "http://localhost:15672"]

Note also that localhost may not work. Instead you should most likely use the RabbitMQ service name declared externally as host name (e.g. http://rabbitmq-service:15672) and ensure your service containing health check is on the same external network with the RabbitMQ server.

As well you have to have curl or netcat package installed on the Docker image your run the container from. This would require to construct a custom dockerfile.

Other answers show lots of approaches the rabbitmq team suggests in case the RabbitMQ service is defined in your Docker Compose file.

1

I will go with this, I want to raise issues like "Publishers will be blocked until this alarm clears":

    healthcheck:
        test: rabbitmq-diagnostics -q status && rabbitmq-diagnostics -q check_local_alarms
        interval: 60s
        timeout: 30s
        retries: 3