How to add initial users when starting a RabbitMQ Docker container?

You can create a simple Dockerfile that extends the functionality of the basic image and creates a default user. The Docker file you need is the following:

FROM rabbitmq

# Define environment variables.
ENV RABBITMQ_USER user
ENV RABBITMQ_PASSWORD user
ENV RABBITMQ_PID_FILE /var/lib/rabbitmq/mnesia/rabbitmq

ADD init.sh /init.sh
RUN chmod +x /init.sh
EXPOSE 15672

# Define default command
CMD ["/init.sh"]

And the init.sh:

#!/bin/sh

# Create Rabbitmq user
( rabbitmqctl wait --timeout 60 $RABBITMQ_PID_FILE ; \
rabbitmqctl add_user $RABBITMQ_USER $RABBITMQ_PASSWORD 2>/dev/null ; \
rabbitmqctl set_user_tags $RABBITMQ_USER administrator ; \
rabbitmqctl set_permissions -p / $RABBITMQ_USER  ".*" ".*" ".*" ; \
echo "*** User '$RABBITMQ_USER' with password '$RABBITMQ_PASSWORD' completed. ***" ; \
echo "*** Log in the WebUI at port 15672 (example: http:/localhost:15672) ***") &

# $@ is used to pass arguments to the rabbitmq-server command.
# For example if you use it like this: docker run -d rabbitmq arg1 arg2,
# it will be as you run in the container rabbitmq-server arg1 arg2
rabbitmq-server $@

This script also initialize and expose the RabbitMQ webadmin at port 15672.


Came up with a solution that suits my needs, leaving it here in case anybody else needs it.

Summary

The idea is to take a standard rabbitmq container with management plugin enabled and use it to create the required configuration, then export and use it to start new containers. The below solution creates a derived docker image but it also works to just mount the two files at runtime (e.g. using docker compose).

References

  • the info I started from
  • complete rabbitmq.config example

Components

  • official rabbitmq image, management plugin version (rabbitmq:management)

  • custom image based on the original one, with this Dockerfile (using version 3.6.6):

     FROM rabbitmq:3.6.6-management
     ADD rabbitmq.config /etc/rabbitmq/
     ADD definitions.json /etc/rabbitmq/
     RUN chown rabbitmq:rabbitmq /etc/rabbitmq/rabbitmq.config /etc/rabbitmq/definitions.json
     CMD ["rabbitmq-server"]
    
  • rabbitmq.config just tells rabbitmq to load definitions from the json file

  • definitions.json contains the users, vhosts, etc. and can be generated by the export function of the management web interface

rabbitmq.config example:

[
  {rabbit, [
    {loopback_users, []}
  ]},
  {rabbitmq_management, [
    {load_definitions, "/etc/rabbitmq/definitions.json"}
  ]}
].

definitions.json example:

{
 "rabbit_version": "3.6.6",
 "users": [
  {
   "name": "user1",
   "password_hash": "pass1",
   "hashing_algorithm": "rabbit_password_hashing_sha256",
   "tags": ""
  },
  {
   "name": "adminuser",
   "password_hash": "adminpass",
   "hashing_algorithm": "rabbit_password_hashing_sha256",
   "tags": "administrator"
  }
 ],
 "vhosts": [
  {
   "name": "\/vhost1"
  },
  {
   "name": "\/vhost2"
  }
 ],
 "permissions": [
  {
   "user": "user1",
   "vhost": "\/vhost1",
   "configure": ".*",
   "write": ".*",
   "read": ".*"
  }
 ],
 "parameters": [],
 "policies": [],
 "queues": [],
 "exchanges": [],
 "bindings": []
}

Alternave version

Deriving a new docker image is just one solution and works best when portability is key, since it avoids including host-based file management in the picture.

In some situations using the official image and providing configuration files from storage local to the host might be preferred.

The rabbitmq.config and definitions.json files are produced the same way, then mounted at runtime.

Notes:

  • I'm assuming they have been placed in /etc/so/ for the sake of these examples
  • files need to either be world readable or owned by the rabbitmq user or group (numerical id inside the docker container is 999), this needs to be handled by the host's sysadmin

docker run example:

    docker run --rm -it \
        -v /etc/so/rabbitmq.config:/etc/rabbitmq/rabbitmq.config:ro \
        -v /etc/so/definitions.json:/etc/rabbitmq/definitions.json:ro \
        rabbitmq:3.6-management

docker compose example:

    version: '2.1'
    services:
        rabbitmq:
            image: "rabbitmq:3.6-management"
            ports:
                - 5672:5672
                - 15672:15672
            volumes:
                - /etc/so/rabbitmq.config:/etc/rabbitmq/rabbitmq.config:ro
                - /etc/so/definitions.json:/etc/rabbitmq/definitions.json:ro