Running the eclipse-mosquitto MQTT Broker in a docker container

I first wrote about MQTT and IoT back in 2012, when I developed a simple C based library to publish and subscribe Quality of Service (QoS) level 0 MQTT messages.

Subsequently, MQTT has grown to be one of the most widely used IoT connectivity protocols with direct support from service such as AWS. Back in 2010, the first open-source MQTT Broker was Mosquitto. Mosquitto is now part of the Eclipse Foundation, and an iot.eclipse.org project, sponsored by cedalo.com.

Another area that has grown during the interim period is the use of container technology, such as Docker, for both testing and deployment. We have, also, extensively covered Docker in previous blog posts.

For another internal dogfood project, I wanted to run a local MQTT Broker rather than a web-based broker, such as https://mqtt.eclipse.org/. Mosquitto can be installed natively on Windows, Mac and Linux. Still, one of the significant benefits of Docker is not polluting your working machine with lots of different tools.

Running Mosquitto in a Docker container is, therefore, a perfect test environment. Rather than, as in the previous Docker blog articles, build our own Docker image containing Mosquitto, we can use the official Dockerhub image.

eclipse-mosquitto Docker image

Pull the latest image

I’m assuming you have Docker installed and configured for your local working environment.

First, pull the latest image from Dockerhub:

% docker pull eclipse-mosquitto

Note of caution: the instructions on the Dockerhub site are incorrect!

Run the docker image

Run the basic Docker image with default settings:

% docker run -it --name mosquitto -p 1883:1883 eclipse-mosquitto 
1582194844: mosquitto version 1.6.8 starting
1582194844: Config loaded from /mosquitto/config/mosquitto.conf.
1582194844: Opening ipv4 listen socket on port 1883.
1582194844: Opening ipv6 listen socket on port 1883.

The -p 1883:1883 argument maps the docker container’s default MQTT socket 1883 the localhost (127.0.0.1) port 1883. Alternatively, we could map that onto another localhost port if it clashed with a locally running MQTT broker, e.g. -p 11883:1883.

Using the --name directive also allows the container to be stopped and restarted, using:

% docker stop mosquitto

and

% docker start mosquitto

Testing the eclipse-mosquitto Docker container

To test the setup of the running Mosquitto container, I used my original software, still available on github. To build this, you’ll need a C compiler (ideally gcc or clang) and CMake.

Alternatively, any MQTT client should work for test purposes.

Subscribe

Next, we must subscribe to a topic. In a command window invoke the subscribe client to a topic, the default for our project being hello\world on port 127.0.0.1:1883, e.g.

% ./mqttsub
MQTT SUB Test Code
port:1883 
Connected to MQTT Server at 127.0.0.1:1883
Subscribed to MQTT Service hello/world with QoS 0

Publish

To test publishing, open another command window and invoke the publisher-client. The publisher-client, by default, publishes 10 messages to the topic hello\world and then closes the connection, e.g.

% ./mqttpub 
MQTT PUB Test Code
port:1883 
Connected to MQTT Server at 127.0.0.1:1883
Published to MQTT Service hello/world with QoS0
Sent 1 messages
Published to MQTT Service hello/world with QoS0
Sent 2 messages
Published to MQTT Service hello/world with QoS0
Sent 3 messages
Published to MQTT Service hello/world with QoS0
Sent 4 messages
Published to MQTT Service hello/world with QoS0
Sent 5 messages
Published to MQTT Service hello/world with QoS0
Sent 6 messages
Published to MQTT Service hello/world with QoS0
Sent 7 messages
Published to MQTT Service hello/world with QoS0
Sent 8 messages
Published to MQTT Service hello/world with QoS0
Sent 9 messages
Published to MQTT Service hello/world with QoS0
Sent 10 messages

Subscribe output

On returning to the subscriber window, we will see the received message displayed.

Message number 1
Message number 2
Message number 3
Message number 4
Message number 5
Message number 6
Message number 7
Message number 8
Message number 9
Message number 10

Mosquitto window output

Returning the window where the docker image was invoked, various log messages are shown:


1582194844: mosquitto version 1.6.8 starting
1582194844: Config loaded from /mosquitto/config/mosquitto.conf.
1582194844: Opening ipv4 listen socket on port 1883.
1582194844: Opening ipv6 listen socket on port 1883.
1582205221: New connection from 172.17.0.1 on port 1883.
1582205221: New client connected from 172.17.0.1 as default_sub (p1, c1, k30).
1582205225: New connection from 172.17.0.1 on port 1883.
1582205225: New client connected from 172.17.0.1 as default_pub (p1, c1, k30).
1582205235: Client default_pub disconnected.

Setting up persistent files

Mosquitto can be configured, for example, to change logging, password, listener-ports, etc. This is achieved using mosquitto.conf file.

To set up mosquitto.conf, first create a local working directory with a three sub-directories of config, data and log, e.g.


% cd
% mkdir docker-mosquitto
% cd docker-mosquitto
% mkdir mosquitto 
% mkdir mosquitto/config/ 
% mkdir mosquitto/data/
% mkdir mosquitto/log/

Create a config file

Next, create a test file called mosquitto.conf in the newly created subdirectory mosquitto/conf/:

% touch mosquitto/config/mosquitto.conf

Edit the config file

Using your favourite editor (okay vi isn’t my favourite, but it’s convenient):

% vi mosquitto/config/mosquitto.conf

And add the as a minimum set of conf directives.


# following two lines required for > v2.0
allow_anonymous true
listener 1883
persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log

The full list of configuration items can be found [here](https://mosquitto.org/man/mosquitto-conf-5.html].

Run the docker image with a mounted volume

Now, when invoking the docker image we use the -v flag mapping the local filesystem into the docker container. The running container will now pick up the locally defined mosquitto.conf. Invoke e.g:

% docker run -it --name mosquitto -p 1883:1883 -v $(pwd)/mosquitto:/mosquitto/ eclipse-mosquitto 

Closing

I hope this post gave you a useful overview of getting an MQTT Mosquitto Broker up and running using Docker.

Hopefully, in future posts, I will be able to share further details of the dogfood project.

 

Niall Cooling
Dislike (3)
Website | + posts

Co-Founder and Director of Feabhas since 1995.
Niall has been designing and programming embedded systems for over 30 years. He has worked in different sectors, including aerospace, telecomms, government and banking.
His current interest lie in IoT Security and Agile for Embedded Systems.

About Niall Cooling

Co-Founder and Director of Feabhas since 1995. Niall has been designing and programming embedded systems for over 30 years. He has worked in different sectors, including aerospace, telecomms, government and banking. His current interest lie in IoT Security and Agile for Embedded Systems.
This entry was posted in General and tagged , , . Bookmark the permalink.

27 Responses to Running the eclipse-mosquitto MQTT Broker in a docker container

  1. Viking says:

    Nice write up. Thanks. But when a new version of Mosquitto is released, what is the easiest way to update the current version already running stable in Docker?

    Like (2)
    Dislike (0)
  2. shraddha maurya says:

    Hello,

    Can you please guide me with how to test the mosquitto docker container?
    As you mentioned I built the github project using cmake. I got some visual studio files and other files in the build folder.
    But when I execute the ./mqttsub command, I get the following error:
    bash: ./mqttsub: No such file or directory

    Further, I tried executing this command: ./mqttsub.sln
    I get the following error:

    ./mqttsub.sln: line 1: Microsoft: command not found
    ./mqttsub.sln: line 3: syntax error near unexpected token `"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"'
    ./mqttsub.sln: line 3: `Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ALL_BUILD", "ALL_BUILD.vcxproj", "{D9D88EFE-37DE-3307-8C65-930977C84DCD}"'

    When I execute the ./mqttsub.sln command through docker in powershell, visual studio gets open.

    Can you please guide me how the ./mqttsub command works?

    Thank you

    Like (3)
    Dislike (0)
  3. Pingback: How can I write a Dockerfile to merge two or more docker images into one? – Windows Questions

  4. Steven Bense says:

    Thank you for this very useful article and well described steps. Do you perhaps have any experience deploying the same in Azure as a container instance? While easy to create and deploy in Azure, I have not been able to connect to the mosquitto instance from an MQTT client.

    Like (1)
    Dislike (0)
  5. Simply doing a docker pull again will get you the latest version.

    Like (1)
    Dislike (0)
  6. Sorry no, I haven't. I generally avoid Microsoft so have no real-world experience of using Azure

    Like (1)
    Dislike (0)
  7. Greg Bennett says:

    Thank you. I have read and tried several "how-to's" and this is the most straight-forward and complete. I finally have a working broker!

    Like (1)
    Dislike (0)
  8. Hi Greg,

    Great to hear, it’s also worth looking at the new developments in VSCode using Devcontainers.

    Regards

    Niall

    Like (0)
    Dislike (1)
  9. Wen says:

    I installed the docker image, and run the container, then this error happened:
    Did anyone see the same error?

    pi@RPi3-MQTT:~ $ docker run -it --name mosquitto -p 1883:1883 eclipse-mosquitto
    1614315343: mosquitto version 2.0.7 starting
    1614315343: Config loaded from /mosquitto/config/mosquitto.conf.
    1614315343: Starting in local only mode. Connections will only be possible from clients running on this machine.
    1614315343: Create a configuration file which defines a listener to allow remote access.
    1614315343: Opening ipv4 listen socket on port 1883.
    1614315343: Opening ipv6 listen socket on port 1883.
    1614315343: Error: Address not available
    1614315343: mosquitto version 2.0.7 running

    Like (4)
    Dislike (0)
  10. That indicates another process is already using port 1883 - possible another MQTT broker? Try mapping the internal 1883 to a different external port, e.g. 18883

    Like (0)
    Dislike (0)
  11. Mosquitto says:

    No, it is Version 2.0 needing a different configuration.
    listener 1883

    Like (3)
    Dislike (0)
  12. Thanks, updated to reflect changes required in conf file

    Like (0)
    Dislike (0)
  13. Snorre says:

    Excellent writeup. I used only the docker pull-command, then jumped to "Setting up persistent files" and followed the instructions from there. And it works! I tried other tutorials without success first. Thank you!

    Like (1)
    Dislike (0)
  14. Abdullah says:

    Excellent write up. I have the container running, Published Ports 1883, Connected networks: bridge, IP 172.17.0.4/16. Host is 10.10.1.128
    I tried to use windows based MQTT explorer to connect with no success. what is missing?

    Like (0)
    Dislike (0)
  15. C.T. says:

    Pretty much same experience here. I have tried to get the eclipse mosquitto docker running on a Synology NAS before, but no success. This article helped me with the persistent folder and with the fact that a basic conf file needs to be created before it works. In hindsight I guess the error in the log was pointing to that, I just did not make the link until this article.
    Thanks!

    Like (0)
    Dislike (0)
  16. Jace says:

    Great article. Im hitting a bit of a wall. Upon running the last command to mount to volume, I get an error that its unable to open the config file? Any thoughts? Thanks!

    Like (0)
    Dislike (0)
  17. Sorry no idea without seeing the actual error message

    Like (0)
    Dislike (0)
  18. Sorry no idea without seeing the actual error message

    Like (0)
    Dislike (0)
  19. That's not the executable - if you used cmake it will be under the build directory

    Like (0)
    Dislike (0)
  20. Rob says:

    One minor detail that caused me trouble was an error stating that the container run from the config could not start. I had to stop and prune the initial docker container opened at the beginning of your excellent tutorial.

    Like (0)
    Dislike (0)
  21. Roberto Gambardella says:

    Hi Niall, I'm at the beginning of my experience with docker and mosquitto, so my question is, how can I compile and build "submain" and "pubmain" in a way that I can have a different docker container for each of them?

    Like (0)
    Dislike (0)
  22. Hi,
    It's pretty straightforward to create separate containers for the two mains (they can use the same base image for building). Then use Docker compose to bring up all three containers and bind their virtual networks together.

    Like (1)
    Dislike (0)
  23. Forooz Saneii says:

    Great article. Very helpful and easy to follow. I got eclipse-mosquitto up and running on docker. Added the listener to mosquitto.conf to resolve "Error: Address not available" issue. But when I tired to run the ./mqttsub I get the client subscription error. On container log I see the the following error: Client default-sub disconnected due to malformed packet . Any ideas why I'm getting this error? I did not change any code except the ip_addr.

    Like (0)
    Dislike (0)
  24. HI,

    Sorry, no idea.

    The code is now 10 years old and I haven't been ensuring the original code is still valid with the latest eclipse/MQTT standard. But you should be able to use any MQTT test client

    Like (0)
    Dislike (0)
  25. Erik Anvik says:

    Try 'docker run -it --rm -p 1883:1883 eclipse-mosquitto:1.6.12 mosquitto' once up the pubsub test code works for me. I ran into similar issues with version 2.0 or greater of the eclipse-mosquito container.

    Like (3)
    Dislike (0)
  26. swenpSwne says:

    If you don't use the mosquitto.conf as described Mosquitto is per default only accepting connections from localhost, i.e. its own docker container.
    That's where the " Error: Address not available" comes from.
    Running the container with the flag "-c /mosquitto-no-auth.conf" will do the trick:
    docker run -it --name mybroker eclipse-mosquitto mosquitto -c /mosquitto-no-auth.conf

    Like (0)
    Dislike (0)
  27. Jackie Gleason says:

    I am trying to run into something similar and I see you show running it from the container but how do I get to it from the host's IP address?

    More info in this question (https://serverfault.com/questions/1127109/why-am-i-getting-error-address-not-available-on-mosquitto-when-i-add-docker-h)

    Like (0)
    Dislike (0)

Leave a Reply