Skip to main content

EMQX MQTT Broker with Docker

Guangzhou, China

EMQX is an open-source (opens new window), highly scalable, and feature-rich MQTT broker designed for IoT and real-time messaging applications. It supports up to 100 million concurrent IoT device connections per cluster while maintaining a throughput of 1 million messages per second and a sub-millisecond latency.

EMQX supports various protocols, including MQTT (3.1, 3.1.1, and 5.0), HTTP, QUIC, and WebSocket. It also provides secure bi-directional communication with MQTT over TLS/SSL and various authentication mechanisms, ensuring reliable and efficient communication infrastructure for IoT devices and applications.

Deploy with Docker

Prepare a directory to persist data:

sudo mkdir -p /opt/emqx/data
sudo chmod -R 777 /opt/emqx

Pull the latest Docker image:

docker pull emqx/emqx:latest
docker run -d -v /opt/emqx/data:/opt/emqx/data --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx:latest

User Interface

http://127.0.0.1:18083/

EMQX MQTT Broker with Docker

EMQX MQTT Broker with Docker

EMQX MQTT Broker with Docker

User Authentication

EMQX supports the simplest and most popular password authentication, which requires the client to provide credentials that can indicate identities, such as username, client ID, and the corresponding password. EMQX will save the client credentials in its built-in database (based on Mnesia) and manages data via REST API and Dashboard.

On EMQX Dashboard, click Access Control -> Authentication on the left navigation tree to enter the Authentication page. Click Create at the top right corner, then click to select Password-Based as Mechanism, and Built-in Database as Backend, this will lead us to the Configuration tab:

EMQX MQTT Broker with Docker

UserID Type: Specify the fields for client ID authentication; Options: username, clientid(corresponding to the Username or Client Identifier fields in the CONNECT message sent by the MQTT client). I will choose username to be able to assign a group username and password to connecting clients - instead of having to handle separate logins for every client ID. Once the database is created click on Users to add logins for your MQTT clients:

EMQX MQTT Broker with Docker

EMQX MQTT Broker with Docker

First, I will add my INSTAR MQTT cameras using the cameras user and a password that fulfills the password requirements of those cameras:

EMQX MQTT Broker with Docker

Authorization

Now we need to switch to the Authorization page in Dashboard and click on Create Authorization based on the Build-in Database. Once created click the Permissions button in the Actions column of the Built-in Database backend:

EMQX MQTT Broker with Docker

Create an Authorization for the created cameras user and add the rights to subscribe and/or publish MQTT topics needed by this client. Since all my MQTT cameras publish to the MQTT prefix cameras followed by the MQTT client ID I need a wildcard subscription to cameras/${clientid}/#:

EMQX MQTT Broker with Docker

And connect your clients using the login:

EMQX MQTT Broker with Docker

Cluster Deployment with Docker-Compose

Besides working with a single EMQX node, EMQX also provides the cluster feature for high availability, better scalability, data security, and centralized management, which is why clustering is recommended for larger or mission-critical applications.

docker-compose.yml

version: '3'

services:
emqx1:
image: emqx:5.1.0
container_name: emqx1
environment:
- "EMQX_NODE_NAME=emqx@node1.emqx.io"
- "EMQX_CLUSTER__DISCOVERY_STRATEGY=static"
- "EMQX_CLUSTER__STATIC__SEEDS=[emqx@node1.emqx.io,emqx@node2.emqx.io]"
healthcheck:
test: ["CMD", "/opt/emqx/bin/emqx", "ctl", "status"]
interval: 5s
timeout: 25s
retries: 5
networks:
emqx-bridge:
aliases:
- node1.emqx.io
ports:
- 1883:1883
- 8083:8083
- 8084:8084
- 8883:8883
- 18083:18083
# volumes:
# - $PWD/emqx1_data:/opt/emqx/data

emqx2:
image: emqx:5.1.0
container_name: emqx2
environment:
- "EMQX_NODE_NAME=emqx@node2.emqx.io"
- "EMQX_CLUSTER__DISCOVERY_STRATEGY=static"
- "EMQX_CLUSTER__STATIC__SEEDS=[emqx@node1.emqx.io,emqx@node2.emqx.io]"
healthcheck:
test: ["CMD", "/opt/emqx/bin/emqx", "ctl", "status"]
interval: 5s
timeout: 25s
retries: 5
networks:
emqx-bridge:
aliases:
- node2.emqx.io
# volumes:
# - $PWD/emqx2_data:/opt/emqx/data

networks:
emqx-bridge:
driver: bridge
docker-compose up -d
docker exec -it emqx1 sh -c "emqx ctl cluster status"