dockerrabbitmq

How to create a queue in RabbitMQ upon startup


I am trying to start RMQ inside docker container, with precreated queue qwer.

Prior to this, I was using simple docker-compose.yml file:

rabbit:
    image: rabbitmq:management-alpine
    environment:
      RABBITMQ_DEFAULT_USER: guest
      RABBITMQ_DEFAULT_PASS: guest

And it worked fine, except that it has no queues pre-created at start. Now I've switched to custom image, with following Dockerfile:

FROM rabbitmq:management-alpine

ADD rabbitmq.conf /etc/rabbitmq/
ADD definitions.json /etc/rabbitmq/

RUN chown rabbitmq:rabbitmq /etc/rabbitmq/rabbitmq.conf /etc/rabbitmq/definitions.json

where rabbitmq.conf is v3.7+ sysctl-styled config, with line:

management.load_definitions = /etc/rabbitmq/definitions.json

and definitions.json contains attempt to create queue:

{
    "vhosts":[
        {"name":"/"}
    ],
    "queues":[
        {"name":"qwer","vhost":"/","durable":true,"auto_delete":false,"arguments":{}}
    ]
}

Now it started to refuse login:

Error on AMQP connection <0.660.0> (172.18.0.6:48916 -> 172.18.0.10:5672, state: starting):
PLAIN login refused: user 'guest' - invalid credentials

I thought that the task is somewhat simple, but configuration process of rabbit itself is most complex task, and documentation is somewhat unclear.

I was unable to figure out how should it work, even after 4 days of trials and googling..

Could you help me, how to write configuration file, in order to create a queue and preserve ability to connect and talk to it?


Solution

  • You are almost there actually.

    RabbitMQ has a rule that the "guest" user can only connect from localhost. Since you are running it on a docker, I'm assuming you are trying to access it from outside by exposing port "15672" by doing: docker run <rabbitmq-docker-img> -p 15672:15672

    So to get around this, what you have to do is create a user with admin privileges.

    Firstly, change this:

    rabbit:
        image: rabbitmq:management-alpine
        environment:
          RABBITMQ_DEFAULT_USER: user
          RABBITMQ_DEFAULT_PASS: password
    

    You can use ath, I used user/password as your user/password.

    In your Dockerfile, you can add: EXPOSE 15672 If you don't want to expose each time you run.

    Lastly, make amends to your definitions.json file as follows:

    {
        "users": [
          {
            "name": "user",  
            "password_hash": "password",
            "hashing_algorithm": "rabbit_password_hashing_sha256",
            "tags": "administrator"
          }
        ],
    
        "vhosts":[
            {"name":"/"}
        ],
        "queues":[
            {"name":"qwer","vhost":"/","durable":true,"auto_delete":false,"arguments":{}}
        ]
    }
    

    Let me know how it goes!

    Check out this link

    Use this Dockerfile:

    FROM rabbitmq
    
    # Define environment variables.
    ENV RABBITMQ_USER user
    ENV RABBITMQ_PASSWORD password
    
    ADD init.sh /init.sh
    EXPOSE 15672
    
    # Define default command
    CMD ["/init.sh"]
    

    And use this init.sh:

    #!/bin/sh
    
    # Create Rabbitmq user
    ( sleep 5 ; \
    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 $@