Technical Article

Create Your Own IIoT Tech Stack Project | Part 3: Commissioning MQTT Broker

October 17, 2023 by Michael Levanduski

Learn to develop an actual IoT solution end to end. Create a Mosquitto MQTT broker for the Raspberry Pi client in order to connect and publish Sense HAT sensor data.

In the previous article in this IIoT project series, we published a sample data payload and verified proper transmission. Now it’s time to send the data to an actual industrial MQTT broker.

Buckle up, this one gets technical!

 

Challenges with Local Broker Software

The mission statement for this step of the project is to establish a local Mosquitto broker so that the Raspberry Pi can publish sensor data. Where do we start?

The easiest and most logical starting point would be to download the Mosquitto broker installer for Windows or Mac from the official Eclipse foundation link here. However, as an author, how would I ensure that the audience would have identical, consistent experiences installing the software? The short answer is that it’s simply impossible. Every machine and environment is different.

Downloading software consistently across teams in the industry is a challenge and consumes valuable development time. Hence, the phrase “It works on my machine” echoes this pain point. Enough griping; there is a solution out there. The answer is Docker.

 

High-Level Overview of Docker

You might be wondering what a whale with shipping containers strapped to its back has to do with software installation. While I can’t give a thorough, detailed overview of Docker in this article, I can describe the base of what it does and why it is useful for a use case just like this.

 

The Docker whale logo

Figure 1. The docker logo. Image used courtesy of Docker

 

Docker is a containerization platform. It bundles an application’s code and required dependencies into an image that can then be run as a container on a host machine. In a way, you can think of Docker as a digital parasite. It consumes the resources of the local machine to run containers (apps), but each container is, in essence, its own separate program.

Docker containers are not the same as virtual machines, as the Docker platform is running on an actual Linux-based system. A key concept to understand is that containers are ephemeral, meaning that once they are stopped, data does not persist by default.

 

The concept of 'containerization'

Figure 2. Docker containerization at a high level. Image used courtesy of Docker

 

Docker Desktop Install

Given that the Docker platform is Linux-based, we will unfortunately need a single install for Docker to run on a Windows or Mac machine. The installation is straightforward, and you may follow along with the provided documentation. If you are on a Windows machine, an install of Windows subsystem for Linux will be required. Once installed, boot up the application so that the docker engine runs on your machine. The startup window should look similar to Figure 3 below.

 

Desktop user interface for docker

Figure 3. Docker Desktop user interface. Image used courtesy of the author

 

Docker Compose

With the installation process now out of the way, we will provision a container using the mosquitto broker image in the Docker Registry. The provisioning process can be accomplished by using Docker Compose.

There are two methods of provisioning containers, with ‘Docker Compose’ being the preferred method for local development. In an integrated design editor, create a project directory and define a docker-compose.yaml file. Within that file, enter the following:

version: '3.8'
services:
  mosquitto:
    image: eclipse-mosquitto
    container_name: mosquitto
    volumes:
      - ./mosquitto/config:/mosquitto/config
      - ./mosquitto/data:/mosquitto/data
      - ./mosquitto/log:/mosquitto/log
    ports:
      - 1883:1883
      - 9001:9001  
   networks:
      - local_iot_network

networks:
  local_iot_network:
    driver: bridge

 

The “mosquitto” service is a friendly name for the mosquitto broker container that will be provisioned. The service pulls the latest image of the eclipse-mosquitto MQTT broker from Docker Hub, which is a cloud-based registry similar to GitHub.

Remember how data does not persist by default in Docker containers (there’s that word ephemeral again)? A convenient solution is to use volumes to persist data. In this example, we are using host-mounted volumes to persist container data in directories on the host machine. The host machine directory is to the left of the colon, and the docker container directory is to the right of the colon as shown in the code below.

    volumes:
      - HOST:CONTAINER

 

The host directory to the left is “mounted” to the directory in the container. The eclipse-mosquitto image documentation specifies these directories exist for persistent storage, logs, and configuration settings.

We’ll cover port binding and the private network later, when we discuss the integration with the Raspberry Pi environment.

 

Host mosquitto.conf File

One of the use cases for host-mounted volumes, a form of bind mounting, is the hand-off of a configuration file from the host machine to the container. The eclipse-mosquitto image documentation specifies that a custom host configuration file can be passed to the broker. This is accomplished by adding a mosquitto.conf file to the hosts ./mosquitto/config directory as such /mosquitto/config/mosquitto.conf

In the same IDE, add the mosquitto.conf file below:

persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
listener 1883 0.0.0.0

## Authentication ##
allow_anonymous true

 

For simplicity, we will not enable username and password authentication. In the real world, you absolutely would want to enable authentication and also encrypt traffic on port 9001.

A quick visual of the folder tree created in the IDE thus far is given below:

 

File system tree for the current IIoT project

Figure 4. IIoT project folder tree. Image used courtesy of the author

 

Provision the Container

The beauty of using Docker Compose is that starting containers is simple and declarative. To run containers in the background, or detached mode, simply enter the docker compose up -d command into a terminal within the project directory:

mlevanduski@Michaels-MacBook-Air IoTProject % pwd
/Users/mlevanduski/Documents/repos/IoTProject
mlevanduski@Michaels-MacBook-Air IoTProject % docker compose up -d
[+] Running 2/2
 ✔ Network iotproject_local_iot_network  Created                                                                                                  0.0s 
 ✔ Container mosquitto                   Started  

 

The terminal output is consistent with the Docker Desktop UI:

 

Graphical user interface (UI) for Docker

Figure 5. Docker Desktop user interface. Image used courtesy of the author

 

Next Steps: Integrating Docker With the Client

In this section, we’ve provisioned the MQTT broker. But how are we going to integrate the Raspberry Pi into the overall project? We’ll cover the integration steps as well as some further Docker concepts in the next article in this series, Part 4.