Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 771
xakepp35 Avatar asked Oct 07 '19 09:10

xakepp35


People also ask

Does RabbitMQ create queue if not exists?

If queue or exchange doesn't exist then it will throw error. if exists it will not do anything. Actually, this is the correct answer. the one that has been chosen as correct, emits a potential risk of declaring and creating abandoned Queues in RabbitMQ server.

How do I use RabbitMQ queue?

Server-named Queues In AMQP 0-9-1, the broker can generate a unique queue name on behalf of an app. To use this feature, pass an empty string as the queue name argument: The same generated name may be obtained by subsequent methods in the same channel by using the empty string where a queue name is expected.


Video Answer


2 Answers

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 $@
like image 184
DUDANF Avatar answered Oct 16 '22 09:10

DUDANF


You can predefine queues and exchanges without creating own rabbit-mq docker image.

Your docker-compose should look like this:

rabbit:
container_name: rabbitmq-preload-conf
image: rabbitmq:3-management
volumes:
  - ./init/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf:ro
  - ./init/definitions.json:/etc/rabbitmq/definitions.json:ro
ports:
  - "5672:5672"
  - "15672:15672"

In this case rabbitmq.conf and definitions.json files should be in init folder in the same parent folder as docker-compose file

rabbitmq.conf file

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

definitions.json file

{
"queues": [
    {
        "name": "externally_configured_queue",
        "vhost": "/",
        "durable": true,
        "auto_delete": false,
        "arguments": {
            "x-queue-type": "classic"
        }
    }
],
"exchanges": [
    {
        "name": "externally_configured_exchange",
        "vhost": "/",
        "type": "direct",
        "durable": true,
        "auto_delete": false,
        "internal": false,
        "arguments": {}
    }
],
"bindings": [
    {
        "source": "externally_configured_exchange",
        "vhost": "/",
        "destination": "externally_configured_queue",
        "destination_type": "queue",
        "routing_key": "externally_configured_queue",
        "arguments": {}
    }
  ]
 }

NOTE: After update in rabbit images, additional configuration may be required. If rabbit container failed to start with the configuration mentioned above (error message contains "vhost") following configuration should be added into definitions file:

 "users": [
    {
      "name": "guest",
      "password_hash": "BMfxN8drrYcIqXZMr+pWTpDT0nMcOagMduLX0bjr4jwud/pN",
      "hashing_algorithm": "rabbit_password_hashing_sha256",
      "tags": [
        "administrator"
      ],
      "limits": {}
    }
  ],
  "vhosts": [
    {
      "name": "/"
    }
  ],
  "permissions": [
    {
      "user": "guest",
      "vhost": "/",
      "configure": ".*",
      "write": ".*",
      "read": ".*"
    }
  ]

Using this additional configuration, default user will be guest with password guest.

Apart from queues, exchanges and bindings, definitions.json file can contain additional configuration

like image 7
SMilos Avatar answered Oct 16 '22 09:10

SMilos