Build Your Own MQTT Broker with EMQX and Docker – Step‑by‑Step Guide

This tutorial walks through installing EMQX as an MQTT broker using Docker, configuring the server, and creating PHP publisher and subscriber clients with the Workerman MQTT library, plus WebSocket and MQTT.js examples for full end‑to‑end IoT communication.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
Build Your Own MQTT Broker with EMQX and Docker – Step‑by‑Step Guide

Overview

MQTT (Message Queuing Telemetry Transport) is a lightweight publish/subscribe protocol built on TCP/IP. It is widely used in IoT because it requires minimal code and bandwidth while providing reliable real‑time messaging. EMQX is an open‑source MQTT broker that can be self‑hosted to gain full control over scalability and flexibility.

Deploy EMQX Broker with Docker

Pull the Docker image

docker pull emqx/emqx

Run the container

docker run -d --name emqx \
  -p 1883:1883 \
  -p 8083:8083 \
  -p 8084:8084 \
  -p 8883:8883 \
  -p 18083:18083 \
  emqx/emqx:latest

Access the management dashboard

Open http://localhost:18083 in a browser. The default credentials are admin / public. The dashboard shows client connections, broker status, and topic statistics.

PHP MQTT client using Workerman

Install the library

composer require workerman/mqtt

Subscriber script (subscribe.php)

Run the script with php subscribe.php start. It connects to the broker, subscribes to the resty topic, and prints received messages.

<?php
declare(strict_types=1);
require __DIR__ . '/../vendor/autoload.php';
use Workerman\Worker;
$worker = new Worker();
$worker->onWorkerStart = function () {
    $options = ['username' => 'Tinywan', 'password' => '123456'];
    $mqtt = new Workerman\Mqtt\Client('mqtt://192.168.13.168:1883', $options);
    $mqtt->onConnect = function ($mqtt) {
        $mqtt->subscribe('resty');
    };
    $mqtt->onMessage = function ($topic, $content) {
        echo "[Subscriber][Topic]: $topic" . PHP_EOL;
        echo "[Subscriber][Content]: $content" . PHP_EOL;
    };
    $mqtt->connect();
};
Worker::runAll();
?>

Publisher script (publish.php)

Run the script with php publish.php start. It publishes the payload Hello Tinywan mqtt to the same resty topic.

<?php
declare(strict_types=1);
require __DIR__ . '/../vendor/autoload.php';
use Workerman\Worker;
$worker = new Worker();
$worker->onWorkerStart = function () {
    $mqtt = new Workerman\Mqtt\Client('mqtt://192.168.13.168:1883');
    $mqtt->onConnect = function ($mqtt) {
        $mqtt->publish('resty', 'Hello Tinywan mqtt');
    };
    $mqtt->connect();
};
Worker::runAll();
?>

WebSocket client with MQTT.js

Include the MQTT.js library in an HTML page and connect to EMQX via the WebSocket endpoint ws://localhost:8083/mqtt. The example below provides a minimal UI to publish arbitrary messages and display received messages.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>MQTT Demo</title>
</head>
<body>
    <h3>MQTT WebSocket Demo</h3>
    <label>Topic:<input id="targetTopicInput" type="text"></label><br>
    <label>Message:<input id="messageInput" type="text"></label><br>
    <button onclick="sendMessage()">Send</button>
    <button onclick="clearMessage()">Clear</button>
    <div id="messageDiv"></div>
    <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
    <script>
        const url = 'ws://localhost:8083/mqtt';
        const topic = 'resty';
        const client = mqtt.connect(url);
        client.on('connect', () => client.subscribe(topic));
        client.on('message', (t, msg) => showMessage('[Subscriber] ' + msg.toString()));
        function sendMessage() {
            const t = document.getElementById('targetTopicInput').value;
            const m = document.getElementById('messageInput').value;
            client.publish(t, m);
            showMessage('[Sent] ' + t + ': ' + m);
        }
        function clearMessage() { document.getElementById('messageDiv').innerHTML = ''; }
        function showMessage(msg) {
            const d = document.getElementById('messageDiv');
            const e = document.createElement('div');
            e.innerText = msg;
            d.appendChild(e);
        }
    </script>
</body>
</html>

Key concepts

Publisher : sends messages to a topic.

Subscriber : receives messages from topics it has subscribed to.

Broker : mediates between publishers and subscribers.

Topic : routing key used for message distribution.

Payload : the actual message content.

QoS levels :

QoS 0 – at most once (no guarantee).

QoS 1 – at least once (possible duplicates).

QoS 2 – exactly once (no duplicates).

Summary

This guide demonstrates how to:

Deploy an EMQX MQTT broker using Docker.

Interact with the broker from PHP using the asynchronous workerman/mqtt library (subscriber and publisher examples).

Use a WebSocket client built with MQTT.js to publish and receive messages from a browser.

Understanding the publish/subscribe flow, QoS options, and the available client libraries enables reliable messaging for IoT applications across industrial control, smart homes, and smart city scenarios.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

DockerPHPIoTMQTTEMQXWorkerman
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.