How to Configure Mosquitto MQTT Broker in Docker
An MQTT broker is an intermediary between MQTT clients that publish messages and subscribers that receive them. Before getting to the subscribers, all published messages first go to the broker. It receives messages, filters them by topics, and distributes them among subscribers.
MQTT brokers are widely used in IoT (Internet of Things), smart home automation systems, cloud platforms, mobile Internet, Internet of Vehicles, energy, and other areas.
In this article, we will tell you how to install and configure the Mosquitto MQTT broker Docker container on Windows, Linux, and macOS operating systems and how to test it.
How to install and configure Mosquitto MQTT broker in Docker from scratch
In this article we will use the open-source message broker Eclipse Mosquitto which implements MQTT version 5, 3.1.1, and 3.1. Mosquitto MQTT broker is available for Windows 10 and 11, Linux, and macOS.
For the installation process, we will use the official eclipse-mosquitto image. Alternatively, you can use cedalo/installer, which also allows you to install not only Mosquitto but other relevant software like Mosquitto Management Center and a data processing solution called Pro Streamsheets.
The process of installing and configuring the Mosquitto Docker container is practically the same for different operating systems. Prerequisites: you must have Docker installed (Windows users have to install Docker Desktop).
Mosquitto Docker installation on Windows, Linux, or macOS
In order to install the broker, run the following command:
docker run -it -d --name mos1 -p 1883:1883 -p 9001:9001 -v /mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf eclipse-mosquitto
The specified commands has several options:
- -it is used to be able to attach a console to the container.
- –name is used to assign a name to the Docker container. You can use a specified name (in our case mos1) to access the container.
- -p 1883:1883 maps a port on your local machine (Docker host) to a container port. If port 1883 on the Docker host is busy, you can use another port, for example -p 18883:1883. Port 1883 is used for MQTT and port 9001 for Websocket.
- -v is used to mount volumes. It links (maps) local files/folders to the container’s files/folders. You can also chain multiple -v flags to create multiple volumes
- -d is used to run the container as a daemon (in the background)
eclipse-mosquitto is the name of the image that will be used as the container’s blueprint.
Command -v /mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf
maps a mosquitto.conf configuration file from your local machine to the container. Basically, your local machine and the docker container will share this file, which means that any changes you perform on this file locally will also be made to that same file inside of the container.
Path /mosquitto/mosquitto.conf is used as an example. You can change it, but make sure it exists (together with the mosquitto.conf file). The path in the container (i. e. /mosquitto/config/mosquitto.conf path) should stay the same.
Note:
- For windows, change the path to windows format like: “C:\mosquitto\mosquitto.conf”
- For macOS and Linux, you don’t have to change anything.
After you have installed and started the Mosquitto Docker container, the broker will be listening at the following address: mqtt://localhost:1883.
By default, Mosquitto is configured not to accept any external connections, so it will only be available inside the container. You can change this if you add some configuration to the mosquitto.conf file that you mapped. We explore how the file can be configured in the sections below. But the simplest and the least secure configuration is just adding ‘allow_anonymous true’ to the config file.
In case you want to attach, i. e. enter the filesystem of the created Mosquitto container, run the following command:
docker exec -it mos1 sh
To exit from the container, enter ‘exit’.
Useful Docker commands
To verify that the container is running use the command:
docker ps -a
Find your Mosquitto container by its name or id.
If the container is not running, you can find the reasons in the Docker logs:
docker logs <container name or id> // in our case container name is mos1
For, example:
docker logs mos1
You can stop the Mosquitto MQTT Docker container using the following command:
docker stop <container name or id>
To start the container, use the following command:
docker start <container name or id>
To restart the container, use the following command:
docker restart <container name or id>
To delete the container, run:
docker rm <container name or id>
To delete the downloaded image, run:
docker rmi <image name or id>
For, example:
docker rmi eclipse-mosquitto
Mosquitto MQTT Docker authentication settings
You can keep your MQTT broker open. This means that any device on your network can reach your Mosquitto server and post messages and subscribe to topics.
To allow external anonymous connections (i.e. without using a Mosquitto user), you can add the following to the configuration file:
allow_anonymous true
listener 1883 0.0.0.0
In order for the config file changes to take effect, the container with the broker must be restarted. This can be done by issuing the ‘docker restart mos1’ command.
Be very careful with anonymous connections though. If you want to achieve higher security, do not allow this setting and connect only using authentication. In this case, in order to write or read messages from the broker, clients will need to enter the correct username and password.
To set up authentication, first, attach to the container with ‘docker exec -it mos1 sh’ and create a password file. Run the following command to create and add a user to this file (note that /mosquitto/passwd_file can be changed to a different path. You can also create this file inside a volume if you need to).
mosquitto_passwd -c /mosquitto/passwd_file user_name
After that, you will be asked to enter the password for the created user and confirm it. When you enter the password, for security reasons, it will not be displayed. Basically, you won’t see what you are entering. But don’t worry, after pressing enter your password will be set.
If you want to add more users to the password file, use the ‘mosquitto_passwd -b /mosquitto/passwd_file user_name password’ command.
Add the following settings to the mosquitto.conf configuration file:
password_file /mosquitto/passwd_file
allow_anonymous false
The parameter ‘allow_anonymous false’ is used to prevent unauthenticated clients from connecting to the broker. This parameter is set to false by default but it’s always a good idea to mention it explicitly.
How to set up persistent storage for Mosquitto Docker Container
There are three directories inside of the container that are used for configuration, permanent storage of data, and logging:
/mosquitto/config
/mosquitto/data
/mosquitto/log
If you want to have persistent storage and logging for your Mosquitto, add the following lines to the configuration file mosquitto.conf in /mosquitto/config that you have mounted when creating the container.
persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
Logs will be stored in /mosquitto/log/mosquitto.log and all the broker data to /mosquitto/data/ directory.
You might want to make volumes for the data and the logs. To do this, when running the ‘docker run’ command, add two -v flags with <host machine path to data directory>:/mosquitto/data/ and <host machine path to log file>:/mosquitto/log/mosquitto.log.
You can find a complete list of configuration options for the mosquitto.conf file here.
How to use Mosquitto docker-compose set-up
If you don’t want to enter a long ‘docker run’ command every time you need to start a container, you can use a docker-compose file. It allows you to define the services you need to run as docker containers and then use a simple ‘docker-compose up’ command to start everything up.
You have to install docker-compose (for windows it is typically installed with Docker Desktop by default). Then create a docker-compose.yml file with the following content:
version: '3.8'
services:
mosquitto:
image: eclipse-mosquitto:2
ports:
- 1883:1883
- 8883:8883
- 9001:9001
volumes:
- ./mosquitto/config:/mosquitto/config
- ./mosquitto/data:/mosquitto/data
networks:
- mosquitto
networks:
mosquitto:
name: mosquitto
driver: bridge
Save your mosquitto.conf file in the mosquitto/config directory or choose a different path.
Remember that paths before the “:” in the “volumes” section of the file are the paths of your local machine. You can adjust them as needed.
Then run the following command to start Mosquitto in the detached mode (in the background):
docker-compose up -d
The name of the container will be the same as the name of the service, i.e. “mosquitto”.
To shut down the container and delete it, execute the following command from the directory with the docker-compse.yml file:
docker-compose down
You can add more services to the docker-compose file. And also add or remove volumes. For example, if you would like to configure Mosquitto logs, you will probably want to add ‘<host machine path to the log file>:/mosquitto/log/mosquitto.log’ to the volumes section of the file above.
How to test the Mosquitto docker configuration
To test the correct operation of the broker, you can use any MQTT client. In our example, we will use the Paho Python Client which provides a client class with all the necessary functionality for publishing messages and subscribing to topics.
You can also use a UI tool called MQTT Explorer to connect to your broker and test it. Alternatively, you can also use mosquitto_pub and mosquitto_sub commands. Some simple usage examples can be found here.
First, have Python and Pip installed. Then, install the Paho Python Client using the following command:
pip install paho-mqtt
Publish
Import the Paho Python Client and time libraries.
import paho.mqtt.client as mqtt
import time
Then add on_connect callback to check if you are connected to the broker or not.
def on_connect(client, userdata, flags, return_code):
if return_code == 0:
print("connected")
else:
print("could not connect, return code:", return_code)
Then you need to connect to the broker. To do this, specify its hostname and port and create a client. The client must have a unique identifier (in our example it is Client1).
This example can be used with the “anonymous connections” setting both enabled and disabled. If you are using the username-password approach, uncomment the line with ‘client.username_pw_set’ that you can see in the code snippets below.
For proper and faster communication with the broker add loop_start.
broker_hostname = "localhost"
port = 1883
client = mqtt.Client("Client1")
# client.username_pw_set(username="user_name", password="password") # uncomment if you use password auth
client.on_connect=on_connect
client.connect(broker_hostname, port)
client.loop_start()
To publish messages, we will create a while loop, in which we will publish a new message every second. Then, we check whether the message was published successfully and display the corresponding message on the screen. Also, add a try-finally block to call loop_stop at the end to clean up the thread where the Paho client’s network loop lives.
topic = "Test"
msg_count = 0
try:
while msg_count < 100:
time.sleep(1)
msg_count += 1
result = client.publish(topic, msg_count)
status = result[0]
if status == 0:
print("Message "+ str(msg_count) + " is published to topic " + topic)
else:
print("Failed to send message to topic " + topic)
finally:
client.loop_stop()
A complete code example for posting messages is as follows:
import paho.mqtt.client as mqtt
import time
broker_hostname = "localhost"
port = 1883
def on_connect(client, userdata, flags, return_code):
if return_code == 0:
print("connected")
else:
print("could not connect, return code:", return_code)
client = mqtt.Client("Client1")
# client.username_pw_set(username="user_name", password="password") # uncomment if you use password auth
client.on_connect=on_connect
client.connect(broker_hostname, port)
client.loop_start()
topic = "Test"
msg_count = 0
try:
while msg_count < 100:
time.sleep(1)
msg_count += 1
result = client.publish(topic, msg_count)
status = result[0]
if status == 0:
print("Message "+ str(msg_count) + " is published to topic " + topic)
else:
print("Failed to send message to topic " + topic)
finally:
client.loop_stop()
Now we can run the script. The output in the console looks like this:
Message 1 is published to topic Test
Message 2 is published to topic Test
Message 3 is published to topic Test
Message 4 is published to topic Test
Message 5 is published to topic Test
Subscribe
Now let’s create a subscriber. As in the previous example, we should import the Paho Python Client and the auxiliary standard library “time”.
import paho.mqtt.client as mqtt
import time
Add on_connect callback to check if the connection is established or not. To subscribe to a topic, add the subscribe(topic_name) command to this callback to ensure that we subscribe only when the connection is established.
def on_connect(client, userdata, flags, return_code):
if return_code == 0:
print("connected")
client.subscribe("Test")
else:
print("could not connect, return code:", return_code)
Whenever the client receives a message from the broker, it invokes the on_message callback. So, in order to be able to view these messages, we need to define the on_message callback function and run it in a loop.
def on_message(client, userdata, message):
print("Received message: ", str(message.payload.decode("utf-8")))
Then, similar to the previous example, create a new client and connect to a broker.
broker_hostname ="localhost"
port = 1883
client = mqtt.Client("Client2")
client.connect(broker_hostname)
# client.username_pw_set(username="user_name", password="password") # uncomment if you use password auth
client.on_connect=on_connect
client.loop_start()
Add try-finally block to call loop_stop in the end which does some cleanup.
try:
time.sleep(10)
finally:
client.loop_stop()
Below is the complete code for creating a client that subscribes to messages in a topic.
import paho.mqtt.client as mqtt
import time
def on_connect(client, userdata, flags, return_code):
if return_code == 0:
print("connected")
client.subscribe("Test")
else:
print("could not connect, return code:", return_code)
def on_message(client, userdata, message):
print("Received message: " ,str(message.payload.decode("utf-8")))
broker_hostname ="localhost"
port = 1883
client = mqtt.Client("Client2")
# client.username_pw_set(username="user_name", password="password") # uncomment if you use password auth
client.on_connect=on_connect
client.on_message=on_message
client.connect(broker_hostname, port)
client.loop_start()
try:
time.sleep(10)
finally:
client.loop_stop()
Below is the output of the script.
Received message: 1
Received message: 2
Received message: 3
Received message: 4
Received message: 5
Advantages of Pro edition for Eclipse Mosquitto broker
In addition to the open-source version, a Pro Edition for Eclipse Mosquitto is also available. Compared to the open-source version, the Pro version has a number of advantages:
- Cloud hosting is available.
- Reliable support, as well as SLA and professional services (which means the product can be customized according to your needs).
- High availability.
- Offers a REST API that allows us to integrate Pro Mosquitto features into the software infrastructure for our customers’ systems.
- Support for advanced user management and permission control, use of client certificates and special certificate authorities, application tokens, etc. to ensure data security.
- The presence of deep inspection features provides a list of connected clients on a node, as well as detailed information about each MQTT client (status, protocol information, IP address, TLS encryption information, last-will messages, topics you subscribe to, and more).
- LMDB (Lightning Memory-Mapped Database) persistence feature.
Sign up for a free 14-day trial Pro Edition for Eclipse Mosquitto broker and evaluate its benefits.
Troubleshooting Mosquitto MQTT Broker Docker container
During the installation and configuration of the broker some errors may occur. Let’s deal with the most common of them.
Address not available
After installing the Mosquitto MQTT docker image and starting the container, an error “Address not available” error may occur.
Possible solutions:
- If you want to allow clients to connect to the broker without authorization, add the following settings to the configuration file:
allow_anonymous true
listener 1883
2. If you want to prevent unauthorized clients from connecting to the broker, then create a file that will contain the username and password and add the following lines to the configuration file:
password_file /mosquitto/passwd_file
allow_anonymous false
After that, restart the Docker container.
Address already in use
This error may mean that the specified port is already taken or that Mosquitto is already running.
Possible solutions:
- Try uninstalling all previously running versions of Mosquitto.
- Use a different port for the broker.
The client does not receive the expected messages
Possible reasons:
- Unstarted network loop loop_start().
- The callback function was not created.
- The client is not subscribed to the correct topics or an error occurred while creating the subscription.
- Access restrictions apply.
Volumes don’t work for Windows
Basically on windows users can experience problems with docker volumes. Volumes might not mount at all.
Possible solutions:
- Use cmd or PowerShell, and make sure that the paths are correct and are defined in the windows format.
- Make sure that you have shared drives enabled in your docker desktop settings (however, this setting might not be available in all the docker desktop installations).
- You can try installing docker directly onto the WSL without Docker Desktop and using it from the WSL (though this approach is more complicated).
Summary
In this article, we explained how to install and configure the free version of Eclipse Mosquitto broker on Windows 10 and 11, Linux, and macOS operating systems. We also learned how to subscribe to topics and publish messages using the Mosquitto MQTT broker.
Let’s recap the most important points:
- The installation process of the Mosquitto broker is practically the same for all the operating systems.
- To install the Mosquitto broker we need to use the “eclipse-mosquitto” image and run it either with a ‘docker run’ command:
docker run -it -d --name mos1 -p 1883:1883 -p 9001:9001 -v /mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf eclipse-mosquitto
or using the ‘docker-compose up’ and the provided docker-compose.yml file.
- In order to configure Mosquitto to the user’s needs, the user will have to mount a volume with a mosquitto.conf configuration.
- Users can test if their Mosquitto configuration worked using Paho Python Client or other means like MQTT Explorer, mosquitto_pub, and mosquitto_sub commands.
If you like the open-source version of Mosquitto and consider deploying it for commercial use but are cautious of any potential problems that you may encounter in production, we have open-source Mosquitto support that allows you to be absolutely confident in the stability and security of your system.