# Docker - Compose - RabbitMQ
###### tags: `Docker` `Compose` `RabbitMQ`
---
## My case
### ``elite_lin_rabbitmq_docker-compose.yml``:
```
version: '3.8'
services:
rabbitmq:
image: rabbitmq:3-management-alpine
hostname: my-rabbit
volumes:
- ./definitions.json:/etc/rabbitmq/definitions.json
- ./rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf
- ./rabbitmq/data:/var/lib/rabbitmq/elite_lin/rabbit@my-rabbit
- ./rabbitmq/logs:/var/log/rabbitmq/log
ports:
- 5672:5672
- 15672:15672
```
#### ``./rabbitmq/etc/definitions.json:/etc/rabbitmq/definitions.json``
#### ``./rabbitmq/etc/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf``:
```
cd /etc
sudo mkdir rabbitmq
sudo cp definitions.json /etc/rabbitmq/
sudo cp rabbitmq.conf /etc/rabbitmq/
sudo cp enabled_plugins /etc/rabbitmq/
```
```
cd /var/lib
sudo mkdir rabbitmq
cd rabbitmq
sudo mkdir elite_lin
cd elite_lin
sudo touch rabbit@my-rabbit
```
#### ``./rabbitmq/logs:/var/log/rabbitmq/log``:
```
cd /var/log/
sudo mkdir rabbitmq
sudo touch log
```
### ``rabbitmq.conf``:
```
loopback_users.guest = false
listeners.tcp.default = 5672
management.listener.port = 15672
management.listener.ssl = false
management.load_definitions = /etc/rabbitmq/definitions.json
```
### ``enabled_plugins``:
```
[rabbitmq_management,rabbitmq_management_agent,rabbitmq_mqtt,rabbitmq_prometheus,rabbitmq_web_dispatch].
```
目前測試,要拿掉
```
volumes:
- ./rabbitmq/etc/definitions.json:/etc/rabbitmq/definitions.json
- ./rabbitmq/etc/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf
```
才會正常
---
# [RabbitMQ container with Docker Compose](https://zgadzaj.com/development/docker/docker-compose/containers/rabbitmq)
## ``docker-compose.yml``:
### Example container configuration:
* [docker docs: rabbitmq](https://docs.docker.com/samples/library/rabbitmq/)
```
services:
rabbitmq:
image: rabbitmq:3-management-alpine
container_name: rabbitmq
volumes:
- ./.docker/rabbitmq/etc/:/etc/rabbitmq/
- ./.docker/rabbitmq/data/:/var/lib/rabbitmq/
- ./.docker/rabbitmq/logs/:/var/log/rabbitmq/
environment:
RABBITMQ_ERLANG_COOKIE: ${RABBITMQ_ERLANG_COOKIE}
RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER}
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS}
ports:
- 5672:5672
- 15672:15672
```
### What does it all mean?
```
image: rabbitmq:3-management-alpine
```
* [docker docs: image](https://docs.docker.com/compose/compose-file/#image)
Specifies an image to use, in this case the ``rabbitmq:3-management-alpine``,
which is based on the popular __Alpine Linux project__,
and comes with the __management plugin installed and enabled by default__,
which is available on the __standard management port of ``15672``__,
with __the default username and password of ``guest`` / ``guest``__.
If you'd rather avoid Alpine, you could use ``rabbitmq:3-management image``,
which would __increase the image size by around 100 MB__.
Specifies a custom container name, rather than a generated default name.
```
container_name: rabbitmq
```
* [docker docs: container_name](https://docs.docker.com/compose/compose-file/#container_name)
```
volumes:
```
* [docker docs: volumes](https://docs.docker.com/compose/compose-file/#volumes)
__Mounts host paths or named volumes__, specified as sub-options to a service.
In case of the above configuration:
```
- ./.docker/rabbitmq/etc/:/etc/rabbitmq/
```
will __mount local ``.docker/rabbitmq/etc/`` directory
as ``/etc/rabbitmq/`` in the container__,
allowing easy __modification to the configuration files__.
把 local path ``/etc/rabbitmq/`` 指定成為 ``.docker/rabbitmq/etc/`` 來用
組態設定
```
- ./.docker/rabbitmq/data/:/var/lib/rabbitmq/
```
will mount local ``.docker/rabbitmq/data/`` directory
as ``/var/lib/rabbitmq/`` in the container,
allowing easy __local access to RabbitMQ data__.
RabbitMQ data
```
- ./.docker/rabbitmq/logs/:/var/log/rabbitmq/
```
will mount local ``.docker/rabbitmq/logs/`` directory
as ``/var/log/rabbitmq/`` in the container,
allowing easy __local access to RabbitMQ logs__.
RabbitMQ logs
* [rabbitmq docs: Config file](https://www.rabbitmq.com/configure.html#config-file)
If you want to __provide your own configuration file__
instead of using one automatically generated by ``docker-entrypoint.sh``
you might mount your config file as ``/etc/rabbitmq/rabbitmq.conf``
(sysctl format, for RabbitMQ versions 3.7.0 and up) or
``/etc/rabbitmq/rabbitmq.config``
(Erlang term configuration format, for versions prior to 3.7.0).
``docker-entrypoint.sh`` 會自動產生組態檔
自己的態檔可以放在 ``/etc/rabbitmq/rabbitmq.conf``
為 __sysctl__ 格式,3.7.0 以上使用
或 ``/etc/rabbitmq/rabbitmq.config``
Erlang 格式, 向下相容模式用
```
environment:
RABBITMQ_ERLANG_COOKIE: ${RABBITMQ_ERLANG_COOKIE}
RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER}
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS}
```
* [docker docs: environment](https://docs.docker.com/compose/compose-file/#environment)
Add environment variables, either as an array or a dictionary.
```
ports:
- 5672:5672
- 15672:15672
```
Port mapping defined in short syntax: ``HOST:CONTAINER``.
``5672:5672`` means that port ``5672`` on host
will forward all its traffic to RabbitMQ's main port ``5672`` in the container.
Same with management plugin's port ``15672:15672``.
Note that while you are free to modify host ports to your liking,
you __should not change container ports
unless you change them in the [``rabbitmq.conf`` configuration file](https://zgadzaj.com/development/docker/docker-compose/containers/rabbitmq#docker-rabbitmq-rabbitmq-conf) too__.
container 用到的 ports 不用特別去改,除非有異動 ``rabbitmq.conf`` 組態檔
## ``.docker/rabbitmq/rabbitmq.conf``:
* [rabbitmq docs: Configuration](https://www.rabbitmq.com/configure.html)
Default ``rabbitmq.conf`` configuration file could either be
automatically generated by the ``docker-entrypoint.sh`` script
on container initialization, or we could provide our own, for example:
```
loopback_users.guest = false
listeners.tcp.default = 5672
default_pass = guest
default_user = guest
hipe_compile = false
management.listener.port = 15672
management.listener.ssl = false
```
## ``.docker/rabbitmq/enabled_plugins``:
* [rabbitmq docs: Plugins](https://www.rabbitmq.com/plugins.html)
The ``rabbitmq:3-management image`` (and its -alpine version too)
__ships with only one plugin installed by default__ - ``management plugin``.
Once it is enabled, the plugin configuration file
``/etc/rabbitmq/enabled_plugins`` looks as follows:
```
[rabbitmq_management].
```
RabbitMQ ships with several [Tier 1 (Core) plugins](https://www.rabbitmq.com/plugins.html#tier1-plugins) included in the distribution.
### Q&A: What are plugin tiers?
Plugins that ship with the RabbitMQ distributions are often referred to as tier 1 plugins. Provided that a standard distribution package is used they do not need to be installed but do need to be enabled before they can be used.
In addition to the plugins bundled with the server, team RabbitMQ offers binary downloads of curated plugins which have been contributed by authors in the community. See the community plugins page for more details.
Even more plugins can be found on GitHub, GitLab, Bitbucket and similar services.
Other community-developed plugins need to be downloaded and installed first before enabling them for RabbitMQ.
* [rabbitmq docs: Installing additional plugins](https://www.rabbitmq.com/installing-plugins.html)
---
## [Get Started with RabbitMQ on Docker](https://codeburst.io/get-started-with-rabbitmq-on-docker-4428d7f6e46b)
### [changhuixu / rabbitmq-labs](https://github.com/changhuixu/rabbitmq-labs)
[RabbitMQ](https://www.rabbitmq.com/#features) is the most widely-deployed open source message broker.
A __message broker__ is a __computer program module__ that
__exchanges messages between the message producers and consumers__,
thus is able to effectively decouple different software components.
RabbitMQ is lightweight and easy to deploy on premises and in the cloud.
Moreover, its [official tutorials](https://www.rabbitmq.com/getstarted.html) are extremely easy to follow.
In this article, we will talk about how to quickly spin up RabbitMQ instances on Docker.
We will go through two ways to run a RabbitMQ Docker image in a container:
(1) using the ``docker run`` command;
(2) using Docker Compose.
Getting familiar with these two approaches should
greatly accelerate your learning on RabbitMQ.
I will not talk about any RabbitMQ client code here,
because the official tutorials have already done an awesome job
in explaining code details in different scenarios.
For your information, the demos in this article are written in .NET
(should be transferable to other languages),
and the complete code can be found in my [GitHub repository](https://github.com/changhuixu/rabbitmq-labs).
Now let’s dive into the world of RabbitMQ and Docker.
### Using the RabbitMQ Docker Image
The RabbitMQ container registry ([link](https://registry.hub.docker.com/_/rabbitmq/)) includes
a variety of images for different platforms.
In this article, we will use the RabbitMQ image with a tag ``3-management``,
which is a Docker image with the RabbitMQ management plugin
installed and enabled by default.
Assuming the Docker Desktop has been installed,
we use the command
```
docker pull rabbitmq:3-management
```
to pull a RabbitMQ Docker image from DockerHub.
After the Docker image is downloaded and saved locally,
we can start a RabbitMQ container using the following command.
```
docker run --rm -it --hostname my-rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3-management
```
In the command above, the ``port 5672`` is used for the RabbitMQ client connections,
and the port ``15672`` is for the RabbitMQ management website.
This command may take a minute to execute. After that,
we can open a browser window and use the URL http://localhost:15672
to visit the RabbitMQ management website.
The following screenshot shows the website login page.
We can use the default username and password, ``guest:guest``,
to log into the website.
The following screenshot shows the homepage of a management website.
After login, we are able to explore the RabbitMQ
configurations, connections, channels, exchanges and queues.
We can also set up new login accounts with different permissions.
Easy-peasy! We now have an instance of RabbitMQ server.
We can keep everything untouched in the management website,
and start learning RabbitMQ by following its official tutorials.
For example, following the __publish/subscribe__ tutorial,
I have created a demo solution in my GitHub repository.
The solution contains two Console projects:
one message producer and one message consumer.
We can play with the solution
by starting the producer program and sending messages.
Since the exchange type is fanout,
we can spin up two or more consumer Console apps
to receive the same messages using exclusive queues.
The following screen recording shows a demo process.
### Docker Compose
The default RabbitMQ definitions are sufficient
for learning purposes and some development scenarios,
but not for most real-world projects. In reality,
we usually __need to set up predefined exchanges and queues__,
as well as a set of users with their permissions.
Moreover, when we update the RabbitMQ definitions,
it’s a __good idea to export the definitions as a file__
and commit the definitions file to a version control system.
In this section, I will first show you
__how to export the RabbitMQ definitions__.
Then I will show you __how to load the definitions
in a Docker container using Docker Compose__.
#### Export/Backup RabbitMQ Definitions
It’s not uncommon that we have __customized RabbitMQ definitions__ for our applications.
For example, in a demo in my GitHub repository,
I configured a __predefined ``topic`` exchange__,
which is __bound to a queue named ``mytest``
with a __routing key of ``order.created``__.
See the screenshot below.
I also deleted the default ``guest`` user, then created an ``admin`` user,
a message producer user, and a message consumer user. See the screenshot below.
After everything is configured, we can export the definitions
by clicking a button on the homepage of the management website,
as in the following screenshot.
Let’s name the downloaded RabbitMQ definitions file as ``definitions.json``,
and place it in a folder ``rabbit/etc`` under our solution folder.
The management website also provides a functionality for us to import definitions.
But we will not use this feature today,
because we want the RabbitMQ server to have all our definitions at startup.
#### Load/Import Broker Definitions using Docker Compose
Even though there are many answers on StackOverflow related to this topic,
most of them are out-of-date.
Here, we will use the latest versions of all dependencies.
We create a ``docker-compose.yml`` file with its content as follows.
```
version: '3.8'
services:
rabbitmq:
image: rabbitmq:3-management
hostname: my-rabbit
volumes:
- ./rabbitmq/etc/definitions.json:/etc/rabbitmq/definitions.json
- ./rabbitmq/etc/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf
- ./rabbitmq/data:/var/lib/rabbitmq/mnesia/rabbit@my-rabbit
- ./rabbitmq/logs:/var/log/rabbitmq/log
ports:
- 5672:5672
- 15672:15672
```
In the ``docker-compose.yml`` file, line 8 is required
if we want to let RabbitMQ load our customized definitions.
Line 8 mounts our ``definitions.json`` file to the Docker container.
Lines 9 to 11 are some optional volumes, but are frequently used.
Lines 10 and 11 are the RabbitMQ server’s database and log files.
We can store them in our local disk
in case we want to restore the message history.
Note that these two local folders need to be ignored in Git.
Line 9 is related to the ``rabbitmq.conf`` file (link).
The configuration file ``rabbitmq.conf``
allows the RabbitMQ server and plugins to be configured.
Starting with RabbitMQ 3.7.0,
the configuration file is in the [``sysctl`` format](https://github.com/basho/cuttlefish/wiki/Cuttlefish-for-Application-Users).
The RabbitMQ git repository has an [example ``rabbitmq.conf`` file](https://github.com/rabbitmq/rabbitmq-server/blob/v3.7.x/docs/rabbitmq.conf.example),
which includes most of the configuration items we might want to set,
along with documentation for those settings.
In my demo, I included a minimal ``rabbitmq.conf`` file,
which is totally optional. The following code snippet
shows the content and format of this ``rabbitmq.conf`` file.
```
loopback_users.guest = false
listeners.tcp.default = 5672
management.listener.port = 15672
management.listener.ssl = false
management.load_definitions = /etc/rabbitmq/definitions.json
```
Alright. With the ``docker-compose.yml`` file, we can easily spin up a RabbitMQ server with our customized definitions and configurations. The command we will use is docker-compose up. A quick way to verify the custom definitions is to log into the management website as the admin user (admin:admin123). We should see that the guest user is no longer existing in the RabbitMQ server.
With customized definitions, we are able to launch RabbitMQ instances with the same behaviors in different environments and platforms. That’s cool.
基本上,把存下來的 ``*.json`` 設定檔保留,就能 import 回去 restore 設定
* __Exchanges__:

* __Queues__:

* __Admin__:

* __User elite_lin__:

* __User ops0:__

* __User ops1__:

---
# [Get Started with RabbitMQ 2: Consume Messages Using Hosted Service](https://codeburst.io/get-started-with-rabbitmq-2-consume-messages-using-hosted-service-e7e6a20b15a6)
In my last article, Get Started with RabbitMQ on Docker, we learned how to run RabbitMQ instances in Docker containers, as well as load customized RabbitMQ server definitions at startup using Docker Compose. To continue with the learning momentum, in this article, we are going to run a message consumer in a Docker container, which shares the same network as the RabbitMQ container.
Most introductory tutorials use Console applications to demonstrate how to produce and consume messages. Even though Console applications are sufficient in some scenarios, it’s better to implement message consumers as hosted services when we run consumers in the background. Background tasks are important components in a microservices architecture. We can implement a single microservice process to run these background tasks in a container so that we can scale it up/down as needed.
In the following sections, we will first create an ASP.NET Core Worker Service project and implement a background service to consume RabbitMQ messages. Then we will make a ``docker-compose.yml`` file to run both the RabbitMQ server and the message consumer app in containers.
The complete source code and commands can be found in my GitHub repository.
The solution demonstrates a contrived scenario in which
the consumer program listens to ``order.created`` events from the upstream in RabbitMQ,
and sends order confirmation emails. Now, let’s dive in.
## Create a Worker Service Project
The ASP.NET Core Worker Service template provides a starting point
for writing cross-platform long-running service apps.
First things first, we create a Worker Service project,
``EmailWorker``, using the dotnet CLI or Visual Studio.
We will mainly work on the default ``Worker`` class to implement the background service.
The ``Worker`` class inherits the ``BackgroundService`` class,
which is the base class for implementing a long running ``IHostedService``.
A hosted service is a class with the background task logic that
implements the ``IHostedService`` interface. Thus the Worker class is a hosted service.
The ``IHostedService`` interface includes two useful methods,
``StartAsync`` and ``StopAsync``, for objects that are managed by the host.
We can utilize these two methods to manage the RabbitMQ connections,
so that the connection is properly configured when the host starts,
and the connection is gracefully closed when when the host shuts down.
The skeleton of an example ``Worker`` class is as follows.
---
# Enable MQTT Plugin
Source:
[Docker RabbitMQ镜像的management、MQTT和STOMP插件配置](https://blog.csdn.net/xuan602/article/details/84307981)
```
docker run --rm -it --hostname my_rabbit --name elite_rabbit -p 15672:15672 -p 5672:5672 -p 1883:1883 rabbitmq:3-management
or
docker run -d --hostname my_rabbit --name elite_rabbit -p 15672:15672 -p 5672:5672 -p 1883:1883 rabbitmq:3-management
```
1. -p 8080:15672 将在容器15672接口的控制台map到本地的8080接口
2. -p 1883:1883 暴露MQTT插件的默认服务端口
3. -p 61613:61613 暴露STOMP插件的默认服务端口
4. 如果报错 docker: Got permission denied 在指令前加sudo
```
elite_lin@elite-lin-VirtualBox:~$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
178440f965d9 rabbitmq:3-management "docker-entrypoint.s…" About a minute ago Up About a minute 4369/tcp, 0.0.0.0:1883->1883/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, 15671/tcp, 15691-15692/tcp, 0.0.0.0:15672->15672/tcp, 25672/tcp elite_rabbit
```
```
elite_lin@elite-lin-VirtualBox:~$ docker container exec -it elite_rabbit bash
root@my_rabbit:/# rabbitmq-plugins enable rabbitmq_mqtt
Enabling plugins on node rabbit@my_rabbit:
rabbitmq_mqtt
The following plugins have been configured:
rabbitmq_management
rabbitmq_management_agent
rabbitmq_mqtt
rabbitmq_prometheus
rabbitmq_web_dispatch
Applying plugin configuration to rabbit@my_rabbit...
The following plugins have been enabled:
rabbitmq_mqtt
started 1 plugins.
root@my_rabbit:/#
```
https://github.com/rabbitmq/rabbitmq-mqtt
### Getting Started
This is an MQTT plugin for RabbitMQ.
The plugin is included in the RabbitMQ distribution. To enable it, use rabbitmq-plugins:
```
rabbitmq-plugins enable rabbitmq_mqtt
```
Default port used by the plugin is ``1883``.
---
# google search "rabbitmq docker-compose postgresql"
https://github.com/dukerspace/docker-postgres-rabbitmq-redis/blob/master/docker-compose.yml
https://github.com/Senzing/docker-compose-demo/blob/master/resources/postgresql/docker-compose-rabbitmq-postgresql.yaml
https://stackoverflow.com/questions/72629386/how-to-docker-compose-thingsboard-rabbitmq
https://stackoverflow.com/questions/74221823/connect-postgresql-to-rabbitmq
https://tejasmandre.vercel.app/read/use-docker-with-django-celery-rabbitmq-nginx-postgresql-simplest-explanation
https://x-team.com/blog/set-up-rabbitmq-with-docker-compose/
https://geshan.com.np/blog/2021/07/rabbitmq-docker-nodejs/
https://hub.docker.com/r/fgribreau/postgresql-to-amqp