2025-02-27
单片机
00

目录

使用Docker快速搭建Mosquitto MQTT代理服务器(支持SSL加密)
一、环境准备
适用系统
二、安装Docker引擎
三、项目目录结构
四、Mosquitto配置
1. 创建配置文件 config/mosquitto.conf
2. 创建密码文件
五、Docker部署
基础版docker-compose.yml
启动服务
六、用户管理
七、进阶配置:SSL加密(Caddy Server)
1. 准备目录
2. DNS配置
3. Caddyfile配置
增强版docker-compose.yml
八、测试验证
订阅消息
发布消息
URL格式测试
九、可视化客户端推荐
1. MQTTX桌面客户端
2. Web客户端部署
3. Python
常见问题解答

使用Docker快速搭建Mosquitto MQTT代理服务器(支持SSL加密)

MQTT协议示意图

本教程将指导您通过Docker容器快速部署支持WebSocket和SSL加密的Mosquitto MQTT代理服务器,适用于物联网项目、智能家居等场景。


一、环境准备

适用系统

  • Ubuntu/Debian
  • Raspberry Pi OS
  • WSL2(Windows子系统)
  • 其他基于Debian的Linux发行版

💡 非Debian系系统需调整安装命令


二、安装Docker引擎

bash
# 使用官方脚本安装 curl -fsSL https://get.docker.com | sh # 验证安装 sudo docker run hello-world

最新安装指南


三、项目目录结构

bash
mkdir -p mqtt5/{config,data,log} && cd mqtt5
mqtt5/ ├── config/ # 配置文件 ├── data/ # 持久化数据 └── log/ # 运行日志

四、Mosquitto配置

1. 创建配置文件 config/mosquitto.conf

ini
allow_anonymous true listener 1883 listener 9001 protocol websockets persistence true password_file /mosquitto/config/pwfile persistence_file mosquitto.db persistence_location /mosquitto/data/

​1883 端口:适用于传统的 MQTT 客户端,使用标准的 MQTT 协议。

​9001 端口:适用于 WebSocket 客户端,使用 MQTT over WebSocket 协议。

2. 创建密码文件

bash
touch config/pwfile

五、Docker部署

基础版docker-compose.yml

yaml
version: "3.7" services: # mqtt5 eclipse-mosquitto mqtt5: image: eclipse-mosquitto container_name: mqtt5 ports: - "9000:1883" #default mqtt port - "9001:9001" #default mqtt port for websockets volumes: - ./config:/mosquitto/config:rw - ./data:/mosquitto/data:rw - ./log:/mosquitto/log:rw restart: unless-stopped # volumes for mapping data,config and log volumes: config: data: log: networks: default: name: mqtt5-network

启动服务

bash
sudo docker-compose -p mqtt5 up -d

六、用户管理

bash
# 进入容器 sudo docker exec -it mqtt5 sh # 创建用户(首次添加使用-c参数) mosquitto_passwd -c /mosquitto/config/pwfile user1 # 添加更多用户 mosquitto_passwd /mosquitto/config/pwfile user2 # 删除用户 mosquitto_passwd -D /mosquitto/config/pwfile user2

下面是指令含义:

mosquitto_passwd is a tool for managing password files for mosquitto. Usage: mosquitto_passwd [-H sha512 | -H sha512-pbkdf2] [-c | -D] passwordfile username mosquitto_passwd [-H sha512 | -H sha512-pbkdf2] [-c] -b passwordfile username password mosquitto_passwd -U passwordfile -b : run in batch mode to allow passing passwords on the command line. -c : create a new password file. This will overwrite existing files. -D : delete the username rather than adding/updating its password. -H : specify the hashing algorithm. Defaults to sha512-pbkdf2, which is recommended. Mosquitto 1.6 and earlier defaulted to sha512. -U : update a plain text password file to use hashed passwords

重启docker容器让设置的用户生效:

sudo docker restart mqtt5

七、进阶配置:SSL加密(Caddy Server)

1. 准备目录

bash
mkdir {caddy_data,caddy_config}

2. DNS配置

bash
# 创建A记录指向服务器IP mqtt.yourdomain.com A 123.45.67.89

在cf上这样:

image.png

3. Caddyfile配置

vim Caddyfile

mqtt.dong-play.fun { reverse_proxy /ws/* http://mqtt5:9001 { # 确保 WebSocket 连接被正确处理 header_up X-Forwarded-Proto "https" header_up Host {host} header_up X-Real-IP {remote} header_up X-Forwarded-For {remote} } }

Caddy 被用作 Mosquitto Websocket 的反向代理,并自动为 mqtt.dong-play.fun 生成 SSL/TLS 证书。

增强版docker-compose.yml

yaml
version: "3.7" services: # mqtt5 eclipse-mosquitto mqtt5: image: eclipse-mosquitto container_name: mqtt5 ports: - "9000:1883" # default mqtt port - "9001:9001" # default mqtt port for websockets volumes: - ./config:/mosquitto/config:rw - ./data:/mosquitto/data:rw - ./log:/mosquitto/log:rw networks: - caddy-mqtt restart: unless-stopped # caddy for HTTPS and reverse-proxy caddy: image: caddy:latest container_name: caddy restart: unless-stopped ports: - "80:80" - "443:443" - "443:443/udp" volumes: - ./Caddyfile:/etc/caddy/Caddyfile - ./caddy_data:/data - ./caddy_config:/config networks: - caddy-mqtt # volumes for mapping data,config and log volumes: config: data: log: caddy_data: caddy_config: networks: caddy-mqtt: name: caddy-mqtt
# MQTT Connection URL would be # WSS => Websocket Secure with SSL wss://mqtt.dong-play.fun:443

八、测试验证

安装客户端:

sudo apt install mosquitto-clients -y

订阅消息

bash
# Without authentication 匿名访问,执行下面这句后会一直等待消息 mosquitto_sub -v -t 'hello/topic' -h localhost -p 9000 # With authentication mosquitto_sub -v -t 'hello/topic' -u user1 -P <password> -h localhost -p 9000 # Alternate way in url format # Format => mqtt(s)://[username[:password]@]host[:port]/topic mosquitto_sub -v -L mqtt://user1:abc123@localhost/test/topic

发布消息

bash
# Without authentication匿名访问,执行下面这句后就是发布了消息,在订阅哪里会收到消息 mosquitto_pub -t 'hello/topic' -m 'hello MQTT' -h localhost -p 9000 # 用IP访问,在主题上发布消息 mosquitto_pub -t 'hello/topic' -m 'hello MQTT' -h 198.12.95.182 -p 9000 # 用域名访问,在主题上发布消息 # With authentication mosquitto_pub -t 'hello/topic' -m 'hello MQTT' -u user1 -P <password> # Alternate way in url format # Format => mqtt(s)://[username[:password]@]host[:port]/topic mosquitto_pub -L mqtt://user1:abc123@localhost/test/topic -m 'hello MQTT'

URL格式测试

bash
mosquitto_sub -L mqtts://user1:[email protected]/test/topic

九、可视化客户端推荐

1. MQTTX桌面客户端

官网下载

2. Web客户端部署

bash
sudo docker run -d --name mqttx-web -p 8080:80 emqx/mqttx-web

访问 http://localhost:8080

3. Python

pip install paho-mqtt

ws服务:

import time import paho.mqtt.client as mqtt # 定义回调函数,当连接成功时调用 def on_connect(client, userdata, flags, rc): if rc == 0: print("连接成功!") # 订阅主题 client.subscribe("test/topic") else: print(f"连接失败,错误码:{rc}") # 定义回调函数,当收到消息时调用 def on_message(client, userdata, msg): print(f"收到消息: {msg.payload.decode()} 来自主题: {msg.topic}") # 创建 MQTT 客户端实例 client = mqtt.Client(transport="websockets") # 使用 WebSocket 传输 # 设置回调函数 client.on_connect = on_connect client.on_message = on_message # 连接到 Mosquitto 服务器 client.connect("198.12.95.182", 9001, 60) # 9001 是 WebSocket 端口 # 启动循环以保持连接 client.loop_start() # 发布消息 try: while True: client.publish("hello/topic", "Hello from Python over WebSocket!") print("消息已发布") time.sleep(2) # 每 2 秒发布一次消息 except KeyboardInterrupt: print("程序已停止") # 停止循环并断开连接 client.loop_stop() client.disconnect()

常见问题解答

Q:为什么需要设置allow_anonymous为false?
A:出于安全考虑禁用匿名访问,必须通过用户名/密码认证

Q:如何查看容器日志?

bash
sudo docker logs mqtt5 --tail 100

Q:SSL证书自动续期如何实现?
Caddy Server会自动处理Let's Encrypt证书的获取和续期


如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:Dong

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!