RabbitMQ in Docker Compose

services: some-rabbit: image: rabbitmq:4.3-management hostname: my-rabbit ports: - "15672:15672" - "5672:5672" environment: RABBITMQ_DEFAULT_USER: user RABBITMQ_DEFAULT_PASS: password

In Docker Compose, give RabbitMQ a fixed hostname:, such as hostname: my-rabbit. RabbitMQ names its node after the hostname, rabbit@my-rabbit, and keeps the node’s data in a directory with that name under /var/lib/rabbitmq/mnesia.

The docker run command, converted

The default-user command from the image’s Docker Hub page, with the tag pinned:

docker run --detach --hostname my-rabbit --name some-rabbit \
    --env RABBITMQ_DEFAULT_USER=user \
    --env RABBITMQ_DEFAULT_PASS=password \
    --publish 15672:15672 \
    --publish 5672:5672 \
     rabbitmq:4.3-management
services:
  some-rabbit:
    image: rabbitmq:4.3-management
    hostname: my-rabbit
    ports:
      - "15672:15672"
      - "5672:5672"
    environment:
      RABBITMQ_DEFAULT_USER: user
      RABBITMQ_DEFAULT_PASS: password

What goes wrong without it

Without hostname:, a container’s hostname is its ID, and docker compose down followed by up makes a new container with a new ID. The node comes up as rabbit@57c4a12114a1 with an empty directory next to the old one in the same volume: the vhosts, users and durable queues you made seem gone. They are still on disk, under the old name.

A broker the workers wait for

services:
  rabbitmq:
    image: rabbitmq:4.3-management
    hostname: my-rabbit
    ports:
      - "127.0.0.1:15672:15672"
      - "127.0.0.1:5672:5672"
    environment:
      RABBITMQ_DEFAULT_USER: user
      RABBITMQ_DEFAULT_PASS: password
    volumes:
      - rabbitmq-data:/var/lib/rabbitmq
    healthcheck:
      test: ["CMD", "rabbitmq-diagnostics", "-q", "check_port_connectivity"]
      interval: 10s
      timeout: 10s
      retries: 5
      start_period: 20s
  worker:
    image: example/worker:1.0
    environment:
      AMQP_URL: amqp://user:password@rabbitmq:5672/
    depends_on:
      rabbitmq:
        condition: service_healthy
volumes:
  rabbitmq-data:

rabbitmq-diagnostics -q ping is the lightest check RabbitMQ’s monitoring guide gives, but it only proves the Erlang runtime answers, and it can pass before the AMQP listener on 5672 opens. check_port_connectivity opens a TCP connection to every listener, so a worker that starts on service_healthy finds the port ready.

Gotchas

  • RABBITMQ_DEFAULT_USER and RABBITMQ_DEFAULT_PASS only apply when the node starts with an empty database. Without them you get guest/guest, and this image lets guest log in from anywhere (its /etc/rabbitmq/conf.d/10-defaults.conf sets loopback_users.guest = false), so a published port is open with a password everyone knows.
  • The -management tags enable the management UI on port 15672; the plain tags don’t have it switched on.
  • docker compose down -v deletes rabbitmq-data with every queue and message in it.
  • rabbitmq:latest is 4.3 without the management plugin. Pin the series, here 4.3-management.

Try it in the docker run to Compose Converter

compose.yaml

1 service · 1 thing left out

Left out, and why

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

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