rabbitmq:4.0-management-alpine image with a named volume, health check, and custom credentials to run a production-ready RabbitMQ message broker in Docker Compose.docker compose up -d with rabbitmq:4.0-management-alpine image, ports 5672:5672 and 15672:15672/var/lib/rabbitmq which is ephemeral without a named volume.| Service | Image | Ports | Volumes | Key Env |
|---|---|---|---|---|
| rabbitmq | rabbitmq:4.0-management-alpine | 5672:5672 (AMQP), 15672:15672 (mgmt UI) | rabbitmq_data:/var/lib/rabbitmq | RABBITMQ_DEFAULT_USER, RABBITMQ_DEFAULT_PASS |
| rabbitmq (TLS) | rabbitmq:4.0-management | 5671:5671 (AMQPS), 15671:15671 (mgmt TLS) | rabbitmq_data:/var/lib/rabbitmq, ./certs:/etc/rabbitmq/certs:ro | RABBITMQ_SSL_CERTFILE, RABBITMQ_SSL_KEYFILE |
| rabbitmq (cluster) | rabbitmq:4.0-management | 5672, 15672, 25672 (inter-node) | rabbitmq_data_N:/var/lib/rabbitmq | RABBITMQ_ERLANG_COOKIE, RABBITMQ_NODENAME |
| Port | Protocol | Purpose |
|---|---|---|
| 5672 | AMQP 0-9-1 / AMQP 1.0 | Message broker (primary) |
| 5671 | AMQPS | TLS-encrypted AMQP |
| 15672 | HTTP | Management UI + HTTP API |
| 15692 | HTTP | Prometheus metrics (rabbitmq_prometheus plugin) |
| 25672 | TCP | Erlang distribution (inter-node clustering) |
| 4369 | TCP | EPMD (Erlang Port Mapper Daemon) |
| 61613 | STOMP | STOMP protocol (rabbitmq_stomp plugin) |
| 1883 | MQTT | MQTT protocol (rabbitmq_mqtt plugin) |
| Variable | Default | Purpose |
|---|---|---|
RABBITMQ_DEFAULT_USER | guest | Initial admin username |
RABBITMQ_DEFAULT_PASS | guest | Initial admin password |
RABBITMQ_DEFAULT_VHOST | / | Default virtual host |
RABBITMQ_ERLANG_COOKIE | (random) | Cluster authentication secret |
RABBITMQ_NODENAME | rabbit@hostname | Node identifier (critical for data directory) |
RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS | (empty) | Extra Erlang VM args |
RABBITMQ_CONFIG_FILES | (empty) | Directory for additional .conf files |
START: What RabbitMQ setup do you need?
├── Single node for development?
│ ├── YES → Use basic docker-compose.yml (Step 1)
│ └── NO ↓
├── Single node for production?
│ ├── YES → Add health check + custom config + TLS (Steps 1-3)
│ └── NO ↓
├── Multi-node cluster?
│ ├── YES → 3-node cluster with quorum queues (Step 4)
│ └── NO ↓
├── Need monitoring?
│ ├── YES → Enable rabbitmq_prometheus plugin + Grafana (Step 5)
│ └── NO ↓
└── DEFAULT → Start with single node + management UI (Step 1)
Start with a single RabbitMQ node with the management plugin enabled. The -management image variant includes the web UI. [src1]
# docker-compose.yml -- RabbitMQ with management UI
services:
rabbitmq:
image: rabbitmq:4.0-management-alpine
container_name: rabbitmq
hostname: rabbitmq
ports:
- "5672:5672"
- "15672:15672"
environment:
RABBITMQ_DEFAULT_USER: myuser
RABBITMQ_DEFAULT_PASS: mypassword
volumes:
- rabbitmq_data:/var/lib/rabbitmq
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "check_port_connectivity"]
interval: 30s
timeout: 10s
retries: 5
start_period: 40s
restart: unless-stopped
volumes:
rabbitmq_data:
Verify: docker compose up -d && docker compose ps -- status should show healthy. Open http://localhost:15672.
Mount rabbitmq.conf for memory limits, disk thresholds, and logging. [src2]
# rabbitmq.conf -- production configuration (sysctl format)
listeners.tcp.default = 5672
default_user = $(RABBITMQ_DEFAULT_USER)
default_pass = $(RABBITMQ_DEFAULT_PASS)
vm_memory_high_watermark.relative = 0.6
disk_free_limit.absolute = 1GB
log.console = true
log.console.level = info
loopback_users = none
management.tcp.port = 15672
# enabled_plugins
[rabbitmq_management,rabbitmq_prometheus].
Verify: docker compose exec rabbitmq rabbitmq-diagnostics environment | grep vm_memory -- should show 0.6.
Enable TLS on AMQP and management ports for production. [src2]
# rabbitmq.conf -- TLS section
listeners.ssl.default = 5671
ssl_options.cacertfile = /etc/rabbitmq/certs/ca.pem
ssl_options.certfile = /etc/rabbitmq/certs/server.pem
ssl_options.keyfile = /etc/rabbitmq/certs/server-key.pem
ssl_options.verify = verify_peer
ssl_options.fail_if_no_peer_cert = false
management.ssl.port = 15671
management.ssl.cacertfile = /etc/rabbitmq/certs/ca.pem
management.ssl.certfile = /etc/rabbitmq/certs/server.pem
management.ssl.keyfile = /etc/rabbitmq/certs/server-key.pem
Verify: openssl s_client -connect localhost:5671 -- should complete TLS handshake.
Deploy a RabbitMQ cluster with quorum queues. All nodes must share the same Erlang cookie. [src3]
Full script: docker-compose-cluster.yml (72 lines)
Verify: docker compose exec rabbitmq1 rabbitmqctl cluster_status -- should show all 3 nodes.
Enable the rabbitmq_prometheus plugin to expose metrics. [src2]
[rabbitmq_management,rabbitmq_prometheus].
Verify: curl http://localhost:15692/metrics -- should return Prometheus-format metrics.
Full script: python-pika-producer-consumer.py (58 lines)
# Input: RabbitMQ at localhost:5672
# Output: Messages sent to and received from "task_queue"
import pika # pika==1.3.2
credentials = pika.PlainCredentials('myuser', 'mypassword')
params = pika.ConnectionParameters(
host='localhost', port=5672,
credentials=credentials,
heartbeat=600,
blocked_connection_timeout=300,
)
conn = pika.BlockingConnection(params)
ch = conn.channel()
ch.queue_declare(queue='task_queue', durable=True,
arguments={'x-queue-type': 'quorum'})
Full script: nodejs-amqplib-producer-consumer.js (56 lines)
// Input: RabbitMQ at localhost:5672
// Output: Messages sent to and received from "task_queue"
const amqplib = require('amqplib'); // [email protected]
const RABBITMQ_URL = 'amqp://myuser:mypassword@localhost:5672';
const conn = await amqplib.connect(RABBITMQ_URL);
const ch = await conn.createChannel();
await ch.assertQueue('task_queue', {
durable: true,
arguments: { 'x-queue-type': 'quorum' },
});
Full script: docker-compose-production.yml (45 lines)
# Input: rabbitmq.conf + enabled_plugins in same directory
# Output: Production-ready RabbitMQ with monitoring
services:
rabbitmq:
image: rabbitmq:4.0-management-alpine
hostname: rabbitmq
ports:
- "5672:5672"
- "15672:15672"
- "15692:15692"
volumes:
- rabbitmq_data:/var/lib/rabbitmq
- ./rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf:ro
- ./enabled_plugins:/etc/rabbitmq/enabled_plugins:ro
# List all queues with message counts
docker compose exec rabbitmq rabbitmqctl list_queues name messages consumers type
# Declare a durable quorum queue
docker compose exec rabbitmq rabbitmqadmin declare queue \
name=orders durable=true \
arguments='{"x-queue-type":"quorum"}' \
--username=myuser --password=mypassword
# Export all definitions (backup)
docker compose exec rabbitmq rabbitmqctl export_definitions /tmp/definitions.json
# BAD -- all data lost when container restarts
services:
rabbitmq:
image: rabbitmq:4.0-management-alpine
ports:
- "5672:5672"
# No volumes defined
# GOOD -- data persists across container restarts
services:
rabbitmq:
image: rabbitmq:4.0-management-alpine
hostname: rabbitmq
volumes:
- rabbitmq_data:/var/lib/rabbitmq
volumes:
rabbitmq_data:
# BAD -- guest/guest accessible from any host
services:
rabbitmq:
image: rabbitmq:4.0-management-alpine
ports:
- "15672:15672"
# No RABBITMQ_DEFAULT_USER/PASS set
# GOOD -- custom credentials set via environment
services:
rabbitmq:
image: rabbitmq:4.0-management-alpine
environment:
RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER:-admin}
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASS:?Set RABBITMQ_PASS}
# BAD -- hostname changes on every container recreate
services:
rabbitmq:
image: rabbitmq:4.0-management-alpine
# No hostname set
volumes:
- rabbitmq_data:/var/lib/rabbitmq
# GOOD -- fixed hostname ensures same data dir
services:
rabbitmq:
image: rabbitmq:4.0-management-alpine
hostname: rabbitmq
volumes:
- rabbitmq_data:/var/lib/rabbitmq
# BAD -- app starts before RabbitMQ accepts connections
services:
rabbitmq:
image: rabbitmq:4.0-management-alpine
app:
depends_on:
- rabbitmq # Only waits for container start
# GOOD -- app waits until RabbitMQ is actually ready
services:
rabbitmq:
image: rabbitmq:4.0-management-alpine
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "check_port_connectivity"]
interval: 30s
timeout: 10s
retries: 5
start_period: 40s
app:
depends_on:
rabbitmq:
condition: service_healthy
/var/lib/rabbitmq/mnesia/rabbit@<hostname>. If hostname changes on recreate, the node sees an empty data directory. Fix: Always set hostname: rabbitmq. [src1]RABBITMQ_ERLANG_COOKIE to the same value on all nodes. [src3]vm_memory_high_watermark (default 0.4), all publishers are blocked. Fix: Set vm_memory_high_watermark.relative = 0.6 and monitor. [src2]disk_free_limit (default 50MB), all publishers are blocked. Fix: Set disk_free_limit.absolute = 1GB for production. [src2]guest/guest can only connect from localhost. From another container, auth fails. Fix: Create a non-guest user or set loopback_users = none. [src2]rabbitmq image has no web UI. Fix: Use rabbitmq:4.0-management-alpine or mount enabled_plugins. [src1]ha-mode policies silently ignored. Fix: Migrate to quorum queues. [src4]# Check container status and health
docker compose ps
docker compose logs rabbitmq --tail=50
# Check RabbitMQ node status
docker compose exec rabbitmq rabbitmqctl status
# Check cluster status
docker compose exec rabbitmq rabbitmqctl cluster_status
# List queues with message counts
docker compose exec rabbitmq rabbitmqctl list_queues name messages consumers type
# List connections
docker compose exec rabbitmq rabbitmqctl list_connections user peer_host state
# Check alarms (memory/disk)
docker compose exec rabbitmq rabbitmqctl node_health_check
# Check effective configuration
docker compose exec rabbitmq rabbitmq-diagnostics environment
# Test AMQP connectivity
docker compose exec rabbitmq rabbitmq-diagnostics check_port_connectivity
# Export definitions (backup)
docker compose exec rabbitmq rabbitmqctl export_definitions /tmp/definitions.json
| Version | Status | Breaking Changes | Migration Notes |
|---|---|---|---|
| 4.0.x | Current (Oct 2024) | Classic queue mirroring removed; default delivery-limit 20 on quorum queues; queue storage v1 removed | Migrate HA policies to quorum queues before upgrading; can run alongside 3.13.x |
| 3.13.x | LTS until 2025-12 | Classic queue v2 default; Khepri metadata store (opt-in) | Last version supporting classic mirrored queues |
| 3.12.x | EOL | Stream filtering; classic queues v2 opt-in | Upgrade to 3.13 before jumping to 4.0 |
| Tag Pattern | Example | Notes |
|---|---|---|
rabbitmq:X.Y | rabbitmq:4.0 | Base image, no management UI |
rabbitmq:X.Y-management | rabbitmq:4.0-management | Includes management plugin + web UI |
rabbitmq:X.Y-alpine | rabbitmq:4.0-alpine | Alpine Linux base (smaller image) |
rabbitmq:X.Y-management-alpine | rabbitmq:4.0-management-alpine | Alpine + management (recommended) |
| Use When | Don't Use When | Use Instead |
|---|---|---|
| Need reliable async message delivery between services | Need simple in-memory pub/sub | Redis pub/sub |
| Need message persistence, routing, and dead-letter queues | Need event streaming with replay/retention | Apache Kafka |
| Need work queue pattern (distribute tasks to workers) | Need real-time WebSocket communication | Socket.IO / native WebSockets |
| Need flexible routing (topic, fanout, headers exchanges) | Need simple point-to-point only | AWS SQS or cloud-native queues |
| Need cross-language support (AMQP, STOMP, MQTT) | Need sub-millisecond latency | ZeroMQ or shared memory |
ha-mode / ha-params policies are silently ignored after upgrade; you must migrate to quorum queues for HAguest user can only connect from localhost by default -- containers connecting from a different network namespace need a dedicated userRABBITMQ_DEFAULT_USER only apply on first boot when the Mnesia database is empty -- changing them on existing volumes has no effect; use rabbitmqctl or definitions import instead