Docker Compose 部署 Mosquitto MQTT Broker 完整实战指南

在物联网(IoT)开发中,Mosquitto 凭借其轻量、开源的特性,成为了最受欢迎的 MQTT 消息代理之一。这篇博文使用 Docker Compose 快速部署一个生产级的 Mosquitto 服务,开启账号密码认证,并打通 MQTT TCP 与 Websocket 双端口。

提示 :Mosquitto 官方 Docker 镜像内部以 mosquitto 用户(UID=1883)运行。在宿主机挂载目录时,文件权限是最容易踩坑的地方,本文已提供最优解。

一、环境准备与目录规划

首先,拉取官方最新镜像:

bash 复制代码
docker pull eclipse-mosquitto

若拉取镜像失败,可参考Debian11上无法拉取docker镜像问题的解决方案

为了便于统一管理配置、持久化数据和日志,我们在宿主机创建专属的项目目录:

bash 复制代码
mkdir -p /mosquitto/{config,data,log}
cd /mosquitto

最终目录结构如下:

text 复制代码
/mosquitto/
├── config/        # 存放 mosquitto.conf 和 pwfile
├── data/          # 持久化消息数据库
├── log/           # 运行日志
└── docker-compose.yml

二、编写核心配置文件

1. 创建 docker-compose.yml

在项目根目录创建 docker-compose.yml,填入以下配置(新版 Compose 已移除 version 字段):

yaml 复制代码
services:
  mosquitto:
    image: eclipse-mosquitto
    container_name: mosquitto
    restart: always
    ports:
      - "1883:1883"   # MQTT TCP 协议端口
      - "9001:9001"   # MQTT over Websocket 端口
    volumes:
      - ./config:/mosquitto/config
      - ./data:/mosquitto/data
      - ./log:/mosquitto/log

2. 编写 mosquitto.conf

./config/ 目录下创建 mosquitto.conf

ini 复制代码
# 开启消息持久化,重启不丢消息
persistence true
persistence_location /mosquitto/data/

# 日志输出配置:同时输出到文件和控制台,方便 docker logs 查看
log_dest file /mosquitto/log/mosquitto.log
log_dest stdout

# 监听 MQTT TCP 端口
listener 1883
# 监听 Websocket 端口,供前端网页客户端使用
listener 9001
protocol websockets

# 生产环境安全配置:关闭匿名访问
allow_anonymous false
# 指定账号密码文件路径
password_file /mosquitto/config/pwfile

三、权限修正与账号初始化

1. 预创建密码文件并修正权限

为了避免容器启动时因权限不足报错,我们需要提前创建密码文件,并将整个目录授权给容器内的 mosquitto 用户(UID=1883):

bash 复制代码
# 创建空的密码文件
touch ./config/pwfile

# 将目录归属修改为 1883:1883
chown -R 1883:1883 /mosquitto

2. 启动容器

/mosquitto 目录下执行:

bash 复制代码
docker compose up -d

3. 创建 MQTT 登录账号

进入容器 Shell 添加用户。注意:-c 参数仅用于首次创建文件,文件已存在时切勿使用,否则会清空已有账号!

bash 复制代码
# 进入容器
docker exec -it mosquitto sh

# 添加 admin 用户,注意 不加 -c
mosquitto_passwd /mosquitto/config/pwfile admin

按提示输入两次密码后,退出容器(exit)。

补充 :如果后续需要重置密码文件,可以先在宿主机执行 rm ./config/pwfile,再进容器使用 mosquitto_passwd -c ... 重新创建。

4. 重启服务使配置生效

修改密码文件后,必须重启 Mosquitto 才能加载:

bash 复制代码
docker compose restart

四、通信验证测试

新开两个终端窗口,分别测试订阅和发布:

终端 A(订阅端):

bash 复制代码
docker exec -it mosquitto mosquitto_sub -h localhost -t test -u admin -P 你的密码

终端 B(发布端):

bash 复制代码
docker exec -it mosquitto mosquitto_pub -h localhost -t test -m "Hello MQTT Docker Compose" -u admin -P 你的密码

当终端 A 成功收到 "Hello MQTT Docker Compose" 消息时,代表 Broker 已经部署成功!

或者直接用MQTTX连接到broker 发布和订阅消息测试

五、日常运维速查

以下命令均需在 docker-compose.yml 所在目录执行:

bash 复制代码
# 后台启动服务
docker compose up -d

# 停止并删除容器(保留 config/data/log 数据)
docker compose down

# 停止并删除容器 + 清空数据卷(!!! 慎用,会丢失持久化消息)
docker compose down -v

# 实时查看运行日志
docker compose logs -f

# 重启 Mosquitto
docker compose restart

六、生产环境安全建议

  1. 严禁匿名访问 :公网暴露必须设置 allow_anonymous false,并配置强密码。如有更高安全需求,建议配置 TLS 证书并使用 8883 加密端口。
  2. 防火墙放行 :云服务器需在控制台安全组放行 18839001 端口;本地服务器需配置 iptables/ufw 放行。
  3. 最小权限原则 :不要图省事使用 chmod 777 授权目录,坚持使用 chown 1883:1883 属主方式。
  4. 定期备份 :定期备份 /mosquitto/config 目录,妥善保存密码文件与核心配置。

七、常见报错排错指南

报错现象 原因分析 解决方案
容器状态 Restarting(13) 挂载目录权限不对,mosquitto 用户无法读写日志或密码文件 执行 chown -R 1883:1883 /mosquitto
Error: Unable to open pwfile pwfile 文件不存在,或文件属主不是 1883 提前创建空 pwfile,并修改属主为 1883:1883
File exists (添加用户时) 密码文件已存在,但错误地使用了 -c 参数 去掉 -c 参数直接添加;若需重建,先删除 pwfile
WARN: attribute version is obsolete 新版 Docker Compose V2 不再需要 version 字段 删除 docker-compose.yml 首行的 version: "3.8" 即可,不影响运行
Conflict. The container name "/mosquitto" is already in use 之前用 docker run 创建的同名容器残留 执行 docker rm -f mosquitto 强制删除旧容器,再重新 docker compose up -d
相关推荐
Larru-Sun1 小时前
Nginx + Vue Router 基础:SPA History 部署、反向代理与请求分流
运维·vue.js·nginx
考虑考虑9 小时前
cmd局部设置java变量
运维·后端·自动化运维
生活爱好者!10 小时前
哇!影视新玩法!docker部署NEOWATCH NAS
运维·docker·容器
一技安身10 小时前
【信创】银河麒麟V10、统信UOS解压7Z文件
linux·运维·服务器
迷途呀11 小时前
CI/CD 自动化部署实践:让代码提交后自动上线
linux·运维·nginx·ci/cd·自动化
闲云自留地11 小时前
动手玩 Nova:Hypervisor、主机聚合、可用分区、虚拟机生命周期实操
运维·架构·openstack
binqian12 小时前
【linux】OpenSSH升级文档
linux·运维·网络
吴声子夜歌12 小时前
Shell编程——if条件语句
linux·运维·shell
和裕12 小时前
蜂窝板 vs 七层瓦楞重型纸箱:大件工业设备运输性能与成本全对比
大数据·运维·网络·人工智能·算法