RabbitMQ
| Use | Image | Status |
|---|---|---|
| RabbitMQ | rabbitmq:4.3.5-management | default |
Pinned, as every compose file and Dockerfile writes them:
rabbitmq:4.3.5-management@sha256:57bddb6fbc3498b5d8b5a14dc6f4506073ebcf94c66ba2a7678c335faa8dd631The tag and digest come from the approved images table; when they disagree, the table wins. RabbitMQ publishes no Debian variant: 4.3.5-management is Ubuntu 24.04, the glibc choice, for the same reason as the rest (see rule 4).
Local development
docker run -d --name rabbitmq-dev --hostname rabbitmq-dev \
-p 127.0.0.1:5672:5672 -p 127.0.0.1:15672:15672 \
-e RABBITMQ_DEFAULT_USER=app -e RABBITMQ_DEFAULT_PASS=dev \
-v rabbitmq-dev-data:/var/lib/rabbitmq \
--health-cmd 'rabbitmq-diagnostics -q ping' \
--health-interval 10s --health-timeout 10s --health-retries 12 \
rabbitmq:4.3.5-management@sha256:57bddb6fbc3498b5d8b5a14dc6f4506073ebcf94c66ba2a7678c335faa8dd631docker exec rabbitmq-dev rabbitmqctl list_usersConnect with amqp://app:dev@127.0.0.1:5672/; the management UI is on http://127.0.0.1:15672. Remove it, data included, with docker rm -f rabbitmq-dev && docker volume rm rabbitmq-dev-data.
On a server
Prepare the host once, next to the compose file. The user and password are in a config folder mounted read-only (see config mounts) and owned by the rabbitmq user. The folder replaces the image's own conf.d, so it carries the image's one setting worth keeping, logging to the console.
mkdir -p rabbitmq
cat > rabbitmq/10-app.conf <<CONF
log.console = true
default_user = app
default_pass = $(openssl rand -hex 24)
CONF
sudo chown -R 999:999 rabbitmq
sudo chmod 0400 rabbitmq/10-app.confservices:
rabbitmq:
image: rabbitmq:4.3.5-management@sha256:57bddb6fbc3498b5d8b5a14dc6f4506073ebcf94c66ba2a7678c335faa8dd631
hostname: rabbitmq
volumes:
- ./rabbitmq:/etc/rabbitmq/conf.d:ro
- rabbitmq-data:/var/lib/rabbitmq
ports:
- "127.0.0.1:5672:5672"
- "127.0.0.1:15672:15672"
read_only: true
tmpfs:
- /tmp:size=64m,mode=1777
cap_drop: [ALL]
cap_add: [CHOWN, SETGID, SETUID]
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD", "setpriv", "--reuid=rabbitmq", "--regid=rabbitmq", "--init-groups", "rabbitmq-diagnostics", "-q", "ping"]
interval: 10s
timeout: 10s
retries: 5
start_period: 30s
stop_grace_period: 1m
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
volumes:
rabbitmq-data: {}docker compose exec -u rabbitmq rabbitmq rabbitmqctl list_usersThe service connects with the same password, from its own .env, as amqp://app:<password>@rabbitmq:5672/.
Why each line is there:
hostname: rabbitmq. RabbitMQ names its noderabbit@<hostname>and keeps its data under that name. Without a fixed hostname every new container is a new node, and the queues in the volume are not found.default_userreplacesguest. With it set, theguestuser is never created; the image's own default letsguestin from anywhere.- The health check runs as
rabbitmq.rabbitmq-diagnosticsneeds the Erlang cookie, which only therabbitmquser can read once root has noDAC_OVERRIDE. - The capabilities. The entrypoint starts as root, fixes the data folder's owner and drops to the
rabbitmquser (999); these three are what that needs. read_only. RabbitMQ writes only to/var/lib/rabbitmqand/tmp.- Ports on
127.0.0.1. The management UI and AMQP are reached by the services over the compose network; the loopback ports are for a person on the host.
Upgrading from 3
- Upgrade from 3.13 only, with every stable feature flag enabled first (
rabbitmqctl enable_feature_flag all). An older 3.x goes to 3.13 before 4. - Classic mirrored queues are gone in 4. Queues that relied on mirroring become quorum queues (
x-queue-type: quorum). - A transient, non-exclusive queue declaration makes RabbitMQ 4 close the connection. A client that declares one on every reconnect loops forever. Check what each service declares before it moves: durable, or exclusive.