Setting up a local Mosquitto server using Docker for MQTT Communication

Mosquitto (or MQTT) is an open source message broker you can use to enable communication between devices, enabling your smart home to communicate with a wider range of devices.

Having devices in your home communicate with each other enables you to create a smarter home. The more information you can feed your smart home controller or software, like Home Assistant the better. MQTT offers a light weight and fast way to send information between devices.

 

How It Works

You first need to setup a MQTT Server, or “broker”. Each device will publish or subscribe to a topic on the broker. The topics can be anything, such as the state of a door lock (locked or unlocked), the current temperature etc.

When a new message is published, the MQTT broker will send that message to devices that have subscribed to that topic instantly. This is very similar to the way PubNub works for commercial applications.

 

What You Can Do With MQTT

There’s a whole range of applications you can use MQTT for. Infact, Home Assistant comes with support for many uses for MQTT, including:

ALARM PANELS

Use MQTT to update the state of an alarm panels armed state, or get notified when your alarm panel is armed/disarmed. This allows you to do some automations such as sound an alarm if the alarm panel is armed, and motion is detected. Or, turn everything off when the alarm panel is armed.

PLANT SENSORS

Use a sensor to measure things like temperature, light levels, soil moisture and have the current values sent to your home automation software via MQTT. I personally prefer to use these Bluetooth flower/plant sensors, which also integrate nicely into Home Assistant.

LIGHTS

Turn lights on and off by publishing an on/off command to a topic in MQTT.

PRESENCE DETECTION

Use the OwnTracks app for iOS or Android to tell your Home Automation system where in the world you are. You can then use zones to let your house know when your phone is at home, at school or work.

 

Benefits of a Local MQTT Broker

There may be situations where you need to publish updates to your MQTT Broker from outside your local network. If you use the OwnTracks app, you’ll need to have constant access to your MQTT broker to publish your location.

If you don’t have a static IP address, or feel uneasy about poking a hole through your Firewall and exposing an MQTT Broker, you might be better off using a cloud based MQTT Broker like CloudMQTT.

Of course, that’s only if you need to publish or receive messages outside of your home network. Using a hosted MQTT Broker outside of your network has some concerns.

  • Internet Connection Required – If your internet connection drops out, you’ll lose your connection to the MQTT Broker. This means your lights, alarm panels and anything else you have talking with MQTT will stop talking to each other. You don’t want to come home during a storm to internet lines down, and not able to disarm your alarm or turn on the lights because the internet is out.
  • Latency – It can take a few seconds longer for your MQTT messages to be received when using a hosted MQTT Broker. Imaging pressing a switch to turn the lights on, but having to wait two seconds before the lights turned on. Possibly longer if someone is streaming Netflix and slowing down your internet connection.

For those reasons, I think it’s always better to run a local MQTT Broker. If the internet drops out, as long as my internal home network is up, everything is still in business.

 

The Latest In Your Inbox

Enter your email address below to receive my latest blog posts and videos about Home Automation in your Inbox

 

Enter Docker

I’m a huge fan of Docker, and Dockerizing all my things. I’ve got Home Assistant setup on my Synology Diskstation NAS thanks to Docker, as well as a whole bunch of other micro services to compliment my smart home.

Using Docker, we don’t have to worry about installing software package x to get y working. Docker installs everything it needs for the service (in this case MQTT) inside its container.

The great thing about Docker is you can run it on a variety of platforms, such as a Raspberry Pi, a windows PC (sort of) and of course like me, a linux based NAS such as a Synology Diskstation.

 

Installing MQTT with Docker Commands

Depending on your machine you may have an interface for you to add Docker containers. Synology has one, and the official Docker for Windows has one too. I prefer to setup Docker containers using the command line. The commands below should work on any system where you’ve already installed Docker.

For Synology users, there’s also one big advantage to using the command line. You can add some options to your Docker containers which the Synology Docker Package doesn’t allow, including automatic restarting of your MQTT broker if it goes down. Which can come in quite handy.

Setup your Synology NAS for Docker

Before you can run any Docker commands on your Synology NAS, you’ll need to have SSH configured, and root access (if you’re on DSM5). I cover this in my Home Assistant setup post, so be sure to check that out first if you haven’t already.

Read More

Let’s go ahead and paste this command into our terminal. I’ll break each option down.

If you’re running using a Synology NAS on DSM6, be sure to prefix that command with sudo.

docker run tells Docker to run a container with the parameters we’re parsing.

--name mqtt The name flag will allow us to easily identify which container is running MQTT. This is useful if we need to do some commands against the container (like starting, stopping etc) later.

--restart=always This is a powerful and handy flag to set. This will tell Docker to keep trying to re-start the MQTT Broker if it crashes, or on boot of the system. (This is one of the flags you can’t set when using the Synology Docker DSM Interface).

--net=host Another important and powerful flag. This gives your MQTT Broker full network access. This allows you to use 127.0.0.1 as the IP address of your MQTT Broker in Home Assistant, if you followed my setup guide. (This is one of the flags you can’t set when using the Synology Docker DSM Interface).

-itd This is actually three commands in the one. The important one is d. This tells Docker to run in detached mode. Once Docker runs the container, our SSH session is returned to us. If we don’t specify this, we’ll see the output from the MQTT Broker in our SSH console. Also import is the t, which tells Docker to tag the container for future use.

-v /volume1/docker/mqtt/config:/mqtt/config:ro Here we’re creating some mount volumes with the various -v flags. This will allow configuration to persist across reboots, as well as data. So, if your MQTT Broker goes down, any persistent messages you may have sent over the Broker should come back up. You can place it in any folder you like. Whatever you choose to use, the folder must exist before you will be able to start the MQTT Broker. If you want to use the same folder as I did above, you can create it by running mkdir -p /volume1/docker/mqtt/config

toke/mosquitto Finally this tells Docker which container to lookup on DockerHub. I’ve been using this image from Toke without issue for many months now.

 

Testing MQTT

So we’ve got our Docker container up and running, but how do we know its working? There’s a handy free program called MQTT.fx which is available for Mac, Windows and Linux. Or if you’re using Chrome there’s a free Chrome Extension called MQTT Lense.

I’m going to use MQTT.fx, let’s try to connect to our MQTT server. My NAS’s IP address is 192.168.1.3. MQTT runs on the port 1883 by default.

In MQTT.fx, press the settings icon to setup a new connection. We’ll use the server address details above for this. Once we’ve setup our new connection, select it from the list and press the blue connect button.

Once you’ve connected to your MQTT server, we should first “subscribe” to a topic. Let’s move to the subscribe tab, and enter a topic to subscribe to. For now, let’s choose the topic home/garden/fountain which is the default for MQTT fx.

Now that we’ve subscribed to our topic, let’s move back to the Publish tab, and now we’ll send a message on the home/garden/fountain topic. In the message body, let’s type “hello world!” and then press the blue Publish button.

If we switch back to the Subscribe tab, we should now see our home/garden/fountain topic has a message with hello world!

Wrapping Up

We’ve now got an MQTT server running on our Synology NAS. We can now use it to communicate securely and quickly through our local network.

You’ll most likely want to use this in combination with OwnTracks to have your phones GPS location sent to your Home Automation software, like Home Assistant. Using your own MQTT server, your privacy is more secured than using a public MQTT server. Before you can send messages to your MQTT server outside your local network though, you’ll need to expose your MQTT server port (1883 by default) to the world through your router, and use your IP address or a service like duckdns.org if your IP address changes.

In the future I’ll be doing some writeups about how I use my local MQTT server for various things around my smart home.

Recommended Posts
  • Bree Lindsay-Stewart

    Phil,
    I think you will find the docker image has change it’s name to toke/mosquitto đŸ™‚

    • Ugh yes you’re right! I had the right one in the video, but forgot to update the post with the right one!

      Thanks!

      • Bree Lindsay-Stewart

        Thanks for the great insights Phil, just found your site the other day and considering I’m using the same products as yourself (Home Assistant/Synology NAS) it’s been a great help đŸ™‚

  • Tijmen Schoemaker

    Hey Phil, excelent tutorial again! Maybe add some info on how to use this with Home Assistant?

  • Nicklaus Craig

    Phil, thanks for the great video! I followed your video to the letter (I am running DSM 6 so i added sudo to the beginning of the commands). I can’t figure out how to create a password file and username for the mqtt login?

    • So this one is a bit tricky. We’ll need to setup a password file to work with MQTT.

      The easiest option is to do the following.

      1. Access bash by running the following command from the Synology SSH

      2. Once you have bash access to the container, we’ll be running a command to generate the password file.

      You’ll be prompted to enter your password twice.

      3. The password file should now exist as passwd_file. You should be able to see this in the Synology filemanager now as well. We now need to tell MQTT to use this password file for authentication. Open /volume1/docker/mqtt/config/mosquitto.conf and add the following to the file

      Then exit out of the bash, and restart the MQTT container. That should require you to enter a username and password to use the MQTT broker now.

      Cheers

      • Nicklaus Craig

        Worked like a charm!! Thank you.

      • Pete

        Hi Phil,

        When I try and add a username and password, it asks me for the password twice then says this:
        Error: Unable to open file passwd_file for writing. Read-only file system.

        How to I fix that? I did chmod 0777 on all three folder locations and the MQTT broker is running.

        • Hey Pete,

          I think it might be a user issue. The container is trying to write to a dir which is owned by a different user. Can you try running the container with the –privileged flag to give it higher access to write to the filesystem?

          • Juan Perez

            Phil, can you please provide the command for running with privileged flag?
            I have tried numerous combinations with no luck

          • Hey Juan, based on my example it should just be something like this

            Cheers

          • Juan Perez

            Phil, thank you very much for your help.

  • Jokerigno

    Hi Phil!

    Thank you for the tutorial!

    There’s a way to use mosquitto with HTTPS?

    Right now I’ve installed HA in my DSM and I’m using synology for generation ad updation certifcates. It works like a charme for HA but I can’t figure it out how to set it up for mosquitto.

    Thank you in advance!

    • Hey!

      Yes, MQTT has an option for SSL/HTTPS. You should be able to point your certificates at it.

      You’ll need to edit the mosquitto.conf file to enable SSL. If you’re using docker, you’ll most likely want to mount the volume where your SSL certs are generated into. Once you’ve got that, just update the mosquitto.conf with the location of your certs and it should work.

      Unfortunately I haven’t got this working myself. I keep everything firewalled off, so only internal things can access my MQTT, which seems overkill to use SSL just on an internal network. However if you’re using your own MQTT broker for things like OwnTracks when you’re out of the house, SSL would probably be a good idea.

  • AndrĂ© van Stijn

    Hey Phil,

    Another nice tut from your site, I just tried to setup mosquitto (as root) your way but it failed to start. I made the directory’s myself and runned your command with a differend path. However I receive the following error’s when I try to run it. Hope you can help me, I think it’s a permission issue?

    https://uploads.disquscdn.com/images/3e03324106247214dfc19b55ebd37fa301ac03e88284fa19695a4b553540dac1.png
    https://uploads.disquscdn.com/images/60b44d6937a501b1b15b02ded79140487139205e9dd126cd0d3d5ea52feac21b.png

    The conf files are not in this directory.

    • Thanks AndrĂ©!

      Yep, think this is a permission issue with ownership, Think you need to add –privileged to the docker run command so that the container has permission to write to the hosts files.

      • AndrĂ© van Stijn

        Sorry for being a noob but it is still not running:

        docker run –name mqtt –restart=always –net=host –privileged -tid -v /volume1/shared/docker/mqtt/config:/mqtt/config:ro -v /volume1/shared/docker/mqtt/log:/mqtt/log -v /volume1/shared/docker/mqtt/data/:/mqtt/data/ toke/mosquitto

        https://uploads.disquscdn.com/images/b72c69a8e48dc0c718bf265fcc3a8a6c0dc4ef918c6a75de0e22b2234af7ce75.png

        I tried the –privileged on other places as well but can’t get it running

        • AndrĂ© van Stijn
          • Also, if you’re on DSM6, another user Ced has found they needed to use a different flag instead of -v (which wouldn’t work on DSM6 for some reason)

            So you could instead try this instead of your -v flag

        • This seems to be getting closer though. Looks like it is a different error message now.

          Can you try running

          It seems to be complaining that directory doesn’t exist for some reason.

          • AndrĂ© van Stijn

            I get an successfull install right now but it is not restarting, the log file is there “mosquitto.log” but I get the message “1519800972: Error: Unable to open log file /mqtt/log/mosquitto.log for writing.” Who needs to be the owner, now it is root, I also tried http but that isn’t working as well

          • You might need to chmod the directory on the NAS to allow others to write to it

          • AndrĂ© van Stijn

            Made the 3 directory’s chmod 777 and now it’s running, I cannot reach the webinterface because of tis error though “Socket error on client , disconnecting.”

          • Wonder if there’s a port that can’t be opened. Are you using –net=host ?

          • AndrĂ© van Stijn

            Yes I used that, the log gives me this reply now “Socket error on client , disconnecting”

            I cannot reach it locally 192.168.1.15:1883 but it is running in a docker.

          • Strange.

            I am indeed using the host flag. Incase it helps, here is my Docker run command I am using on DSM5

            I am specifying the –net=host and also -p flags, but the -p flags will be ignored.

            I have Home Assitant running on the NAS, and it connects with the following YAML

Start typing and press Enter to search