Docker Compose部署EMQX集群详细教程(Ubuntu环境优化版)

EMQX是一款高性能、可扩展的开源MQTT消息服务器,广泛应用于物联网、微服务等场景。本文将基于Ubuntu系统,结合Docker Compose实现EMQX集群的快速部署,针对中国网络环境优化镜像拉取策略,同时覆盖集群配置、验证及常见问题排查,适合Java后端开发、DevOps工程师及物联网运维人员参考。

一、环境准备

1.1 系统要求

  • 操作系统:Ubuntu 22.04.5 LTS(64位)

  • Docker版本:Docker version 28.0.4

  • Docker Compose版本:v2.34.0

  • 硬件配置:最低2核4G内存(集群节点建议每节点2核4G及以上)

  • 网络要求:集群节点间网络互通(默认需开放1883、8083、8084、18083、4370、5369端口)

1.2 IP地址

  • 节点1:172.28.0.10
  • 节点2:172.28.0.11

1.3 Docker 和 Docker compose 安装

参考:Ubuntu22.04 安装 Docker 及 Docker Compose v2 详细教程

二、EMQX集群部署核心配置

EMQX集群支持多种发现方式,本文采用static静态发现(适合固定节点IP场景),同时配置持久化存储、自定义账号密码及网络优化。

2.1 创建部署目录结构

bash 复制代码
# 创建EMQX部署根目录
mkdir -p /opt/emqx-cluster
cd /opt/emqx-cluster

# 创建节点数据存储目录(每个节点独立目录,避免数据冲突)
mkdir -p data/node1 data/node2
sudo chmod 777 -R data/  # 赋予权限,避免容器读写权限问题

2.2 编写docker-compose.yml文件

创建docker-compose.yml文件,定义2个节点的EMQX集群(可根据需求扩展节点数量),使用EMQX官方镜像(国内可通过阿里云镜像仓库拉取)。

  • 节点1
yaml 复制代码
services:
  emqx:
	# 指定 EMQX 镜像版本
	image: emqx/emqx:5.6.1
	# 容器名称
    container_name: emqx_cluster
    environment:
      - EMQX_NODE_NAME=emqx@172.28.0.10  #节点名称,格式:emqx@服务器IP
      - EMQX_NODE__COOKIE=emqx_cluster_cookie_2026  # EMQX 节点通信密钥
      - EMQX_CLUSTER__DISCOVERY_STRATEGY=static  # 基于 static 节点列表自动集群
      - EMQX_CLUSTER__STATIC__SEEDS=[emqx@10.0.0.128,emqx@172.28.0.10]  # 集群所有节点列表
      - EMQX_DASHBOARD__DEFAULT_USERNAME=admin # 制台默认用户名
      - EMQX_DASHBOARD__DEFAULT_PASSWORD=emqx123456 # 制台默认密码
    ports:
      - 1883:1883     # TCP端口
      - 8083:8083     # WebSocket端口
      - 8084:8084     # 安全 WebSocket(WSS)端口
      - 8883:8883     # SSL端口
      - 18083:18083   # 控制台端口
      - 4370:4370     # Erlang 分布式传输端口
      - 5369:5369     # 集群 RPC 端口
    restart: always
    volumes:
      - ./data:/opt/emqx/data
      - ./log:/opt/emqx/log
  • 节点2
yaml 复制代码
services:
  emqx:
	# 指定 EMQX 镜像版本
	image: emqx/emqx:5.6.1
	# 容器名称
    container_name: emqx_cluster
    environment:
      - EMQX_NODE_NAME=emqx@172.28.0.11  #节点名称,格式:emqx@服务器IP
      - EMQX_NODE__COOKIE=emqx_cluster_cookie_2026  # EMQX 节点通信密钥
      - EMQX_CLUSTER__DISCOVERY_STRATEGY=static  # 基于 static 节点列表自动集群
      - EMQX_CLUSTER__STATIC__SEEDS=[emqx@10.0.0.128,emqx@172.28.0.11]  # 集群所有节点列表
      - EMQX_DASHBOARD__DEFAULT_USERNAME=admin # 制台默认用户名
      - EMQX_DASHBOARD__DEFAULT_PASSWORD=emqx123456 # 制台默认密码
    ports:
      - 1883:1883     # TCP端口
      - 8083:8083     # WebSocket端口
      - 8084:8084     # 安全 WebSocket(WSS)端口
      - 8883:8883     # SSL端口
      - 18083:18083   # 控制台端口
      - 4370:4370     # Erlang 分布式传输端口
      - 5369:5369     # 集群 RPC 端口
    restart: always
    volumes:
      - ./data:/opt/emqx/data
      - ./log:/opt/emqx/log

核心配置说明

  • 集群CookieEMQX_NODE_COOKIE是集群节点间通信的认证密钥,所有节点必须完全一致,否则无法加入集群。

  • 节点名称 :格式为节点名@IP,IP需使用集群内网固定IP,避免使用localhost或127.0.0.1。

  • 端口映射:多个节点映射到宿主机的端口需不同,避免端口冲突;核心端口功能:

    • 1883:MQTT协议默认TCP端口,用于设备连接。

    • 8083:MQTT WebSocket端口,用于浏览器端连接。

    • 18083:Web管理控制台端口,用于集群运维。

    • 4370/5369:集群内部通信端口

  • 持久化存储:通过挂载宿主机目录保存EMQX数据和日志,避免容器删除后数据丢失,适合生产环境。

三、启动EMQX集群

3.1 拉取镜像并启动集群

bash 复制代码
# 进入部署目录
cd /opt/emqx-cluster

# 拉取镜像并启动集群(-d参数后台运行)
docker-compose up -d

# 查看容器启动状态
docker-compose ps

# 查看集群启动日志(若启动失败,可通过日志排查问题)
docker-compose logs -f  # 实时查看所有节点日志
docker logs -f emqx1  # 单独查看节点1日志

3.2 启动成功验证

若启动成功,docker-compose ps命令输出中,两个节点的状态均为Up。此时可通过两种方式验证集群状态:

3.2.1 命令行验证集群状态

bash 复制代码
# 进入节点1服务器对应的emqx容器内部
docker exec -it emqx /bin/bash

# 查看集群状态
emqx_ctl cluster status

# 预期输出(表示两个节点已成功组成集群):
Cluster status: #{running_nodes => ['emqx@172.28.0.10','emqx@10.0.0.128'],
                  stopped_nodes => []}

3.2.2 Web控制台验证

  1. 打开浏览器,访问宿主机IP:18083(节点1控制台)或宿主机IP:18084(节点2控制台)。

  2. 使用配置文件中定义的账号(admin)和密码(emqx123456)登录。

  3. 登录后,点击左侧菜单栏「集群」,可查看集群节点列表、节点状态、负载情况等信息,确认两个节点均处于「运行中」状态。

四、集群核心功能配置(可选)

4.1 自定义MQTT监听端口

若需修改MQTT默认端口,可在environment中添加以下配置(以节点1为例):

yaml 复制代码
environment:
  - EMQX_LISTENER__TCP__DEFAULT__BIND=1885  # 将TCP端口改为1885
  - EMQX_LISTENER__WS__DEFAULT__BIND=8086  # 将WebSocket端口改为8086

修改后需重启集群:docker-compose down && docker-compose up -d

4.2 配置访问控制(ACL)

通过挂载ACL文件限制设备访问权限,在宿主机创建acl.conf文件:

bash 复制代码
# 创建ACL配置文件
touch /opt/emqx-cluster/acl.conf

# 编辑ACL规则(示例:允许admin用户订阅所有主题,禁止匿名用户发布消息)
cat &gt; /opt/emqx-cluster/acl.conf <<-'EOF'
## 允许admin用户订阅所有主题
{allow, {user, "admin"}, subscribe, ["#"]}.

## 禁止匿名用户发布消息
{deny, all, publish, ["#"]}.

## 允许所有用户订阅自己的主题
{allow, all, subscribe, ["${clientid}/#"]}.
EOF

docker-compose.yml中添加挂载配置(每个节点均需添加):

yaml 复制代码
volumes:
  - ./acl.conf:/opt/emqx/etc/acl.conf

重启集群使配置生效:docker-compose restart

4.3 配置数据持久化(进阶)

默认情况下,EMQX数据存储在宿主机挂载目录,若需更高可靠性,可结合NFS或分布式存储挂载,确保集群节点数据一致性。

五、常见问题排查(Ubuntu环境专属)

5.1 集群节点无法加入

问题现象emqx_ctl cluster status显示只有单个节点,另一个节点处于stopped状态。

解决方案

  1. 检查所有节点的EMQX_NODE_COOKIE是否完全一致,不一致会导致认证失败。

  2. 确认集群网络互通:进入容器内部ping其他节点IP(如ping 172.28.0.11),若无法ping通,检查宿主机防火墙是否放行172.28.0.0/16网段。
    # 开放集群网段防火墙规则 sudo ufw allow from 172.28.0.0/16 sudo ufw reload

  3. 手动将节点加入集群:

    `# 进入节点2容器

    docker exec -it emqx /bin/bash

手动加入emqx1节点

emqx_ctl cluster join emqx1@172.28.0.10

再次查看集群状态

emqx_ctl cluster status`

5.2 宿主机无法访问Web控制台

问题现象:浏览器访问宿主机IP:18083时无法打开页面。

解决方案

  1. 检查容器端口映射是否正确:docker-compose ps确认18083端口已映射到宿主机。

  2. 开放宿主机防火墙端口:
    sudo ufw allow 18083/tcp sudo ufw allow 18084/tcp sudo ufw reload

  3. 检查容器内部控制台是否正常运行:docker exec -it emqx1 emqx_ctl status # 确认EMQX服务正常运行 netstat -tnlp | grep 18083 # 确认容器内18083端口已监听

5.3 数据持久化失败

问题现象:容器重启后,之前创建的用户、规则等数据丢失。

解决方案

  1. 检查宿主机挂载目录权限:确保/opt/emqx-cluster/data目录权限为777(sudo chmod 777 -R /opt/emqx-cluster/data)。

  2. 确认挂载路径正确:docker-compose.yml中volumes配置的宿主机路径与容器路径对应无误。

  3. 查看容器日志排查权限问题:docker logs -f emqx1 | grep permission,根据日志提示调整权限。

六、集群运维与扩展

6.1 集群重启与停止

bash 复制代码
# 重启集群
docker-compose restart

# 停止集群(保留容器和数据)
docker-compose stop

# 停止并删除容器(数据仍保留在宿主机)
docker-compose down

# 停止并删除容器及镜像
docker-compose down --rmi all

6.2 节点扩容(新增节点3)

  1. 在docker-compose.yml中添加节点3配置,参考节点2的格式,修改IP(如172.28.0.12)、容器名、端口映射。

  2. 创建节点3数据目录:mkdir -p /opt/emqx-cluster/data/node3 && sudo chmod 777 -R data/node3

  3. 更新集群配置:所有节点的EMQX_CLUSTER__STATIC__SEEDS添加新节点(emqx3@172.28.0.12)。

  4. 启动新节点:docker-compose up -d emqx3

  5. 验证扩容结果:docker exec -it emqx1 emqx_ctl cluster status,确认新节点已加入集群。

6.3 日志分析与监控

EMQX日志默认存储在宿主机/opt/emqx-cluster/data/node1/lognode2/log目录,核心日志文件:

  • emqx.log:主日志文件,记录集群运行状态、错误信息等。

  • access.log:访问日志,记录设备连接、消息收发等请求。

生产环境可结合ELK、Prometheus+Grafana等工具实现日志集中管理和性能监控。

七、生产环境优化建议

  1. 网络优化:集群节点建议部署在同一局域网,避免跨网段通信导致延迟;开启MQTT over QUIC协议(8084端口),提升弱网环境下的连接稳定性。

  2. 资源限制:在docker-compose.yml中为每个节点添加资源限制,避免单个节点占用过多资源,示例:

yaml 复制代码
 deploy:
  resources:
    limits:
      cpus: '2'
      memory: 4G
    reservations:
      cpus: '1'
      memory: 2G`
  1. 高可用配置:结合Keepalived实现宿主机IP漂移,避免单节点故障导致服务中断;使用负载均衡器(如Nginx、HAProxy)分发MQTT连接请求到集群节点。

  2. 安全加固 :修改默认账号密码为复杂密码;关闭匿名访问(EMQX_ALLOW_ANONYMOUS=false);开启TLS/SSL加密(配置证书文件,启用8883端口)。

八、总结

本文基于Ubuntu环境,通过Docker Compose实现了EMQX集群的快速部署,覆盖了环境准备、配置编写、集群启动、验证运维及常见问题排查,同时针对中国网络环境优化了镜像拉取策略。EMQX集群可有效提升MQTT消息服务的并发处理能力和可用性,适合物联网大规模设备接入场景。后续可根据实际业务需求,扩展集群节点数量、优化访问控制策略及监控方案。

相关推荐
小康小小涵2 小时前
ROS2-Humble功能包插件推荐
ubuntu
Tao____2 小时前
适合中小企业的物联网平台
java·物联网·mqtt·低代码·开源
WilliamHu.2 小时前
Windows 环境下使用 Docker 成功部署 Dify(完整实战记录)
运维·docker·容器
叫致寒吧3 小时前
Kubernetes 安全机制
安全·容器·kubernetes
Cyber4K3 小时前
【Kubernetes专项】零故障升级之Pod健康探测
云原生·容器·kubernetes
能不能别报错3 小时前
企业级生产级K8s平台
云原生·容器·kubernetes
幼稚园的山代王4 小时前
从 0 到 1,读懂 Kubernetes 核心概念
云原生·容器·kubernetes
guangshui5164 小时前
2034.Advanced IP scanner软件扫描 ubuntu的ip地址
网络协议·tcp/ip·ubuntu
403240735 小时前
Ubuntu/Jetson 通用:NVMe 硬盘分区、挂载及开机自动挂载完整教程
linux·运维·ubuntu