Apache Storm 2.8.9 Docker Compose 部署指南
使用 Docker Compose 一键编排 Apache Storm 2.8.9 伪集群(ZooKeeper 3.9.3 + nimbus/supervisor/ui/logviewer),自建 storm:2.8.9 镜像、挂载 storm.yaml、JVM 堆 256-512MB、端口映射与数据卷持久化,含等价 docker run 与常见故障,命令与回显均实测
Apache Storm 2.8.9 Docker Compose 部署指南
目标:使用 Docker Compose 编排一套 Apache Storm 2.8.9 伪集群——ZooKeeper 3.9.3 与 Nimbus、Supervisor、UI、Logviewer 四守护进程各占一个服务,通过自建
storm:2.8.9镜像与挂载storm.yaml完成部署,JVM 堆限定 256-512MB,UI 映射到宿主机端口。命令与回显均为实际执行结果。
一、环境信息
- Docker:24+ / Docker Compose v2(
docker compose子命令) - 宿主机:Ubuntu 22.04(x86_64)
- Storm 镜像:自建
storm:2.8.9(基于eclipse-temurin:17-jre-jammy,内含 Storm 2.8.9 + python3) - ZooKeeper 镜像:
zookeeper:3.9.3(官方镜像) - 服务:zookeeper、nimbus、supervisor、ui、logviewer
- 映射端口:6627(nimbus)、6700/6701(worker slots)、18080→8080(ui)、8081(logviewer)、2181(zookeeper)
- 配置挂载:
./conf/storm.yaml→/opt/storm/conf/storm.yaml - 数据卷:
nimbus-data、supervisor-data、worker-logs
二、镜像选型说明
| 镜像 | 说明 |
|---|---|
storm:2.8.9(自建) | 本指南采用。Docker Hub 无 Apache 官方 Storm 镜像,基于 eclipse-temurin:17-jre-jammy + 发行版 tar.gz 构建,各守护进程共用一个镜像、以 command 切换角色 |
zookeeper:3.9.3 | 官方 ZooKeeper 镜像,开箱即用;Storm 2.8.9 兼容 ZooKeeper 3.8/3.9 |
💡 Storm 2.8.9 运行必须 Java 17+,基础镜像选
eclipse-temurin:17-jre-jammy(JRE 即可,运行无需 JDK);镜像内需补装python3,否则/opt/storm/bin/storm命令行与守护进程包装脚本无法执行。
三、前置条件
- 已安装 Docker 与 Docker Compose v2 的宿主机,root 权限。
- 准备好 Storm 2.8.9 发行包
apache-storm-2.8.9.tar.gz(372,775,041 字节,sha512:f545c00e84136fd929b84673e15999bf9c31993d78dc6d06aa49f9cf41dfe45786d5564fb5dc2e70b8098b190dcf53092cd53503963d75b3b6384ba8a431a165,来源 https://archive.apache.org/dist/storm/apache-storm-2.8.9/apache-storm-2.8.9.tar.gz 或华为云镜像同名路径)。 - 宿主机端口未被占用:6627、6700、6701、8081、2181、18080(UI 映射端口,宿主机 8080 常被其他服务占用,故映射到 18080,实测见 FAQ)。
四、部署步骤
4.1 创建目录结构并准备发行包
mkdir -p storm-compose/conf
cd storm-compose
cp /path/to/apache-storm-2.8.9.tar.gz .
4.2 编写 Dockerfile(自建 storm:2.8.9)
cat > Dockerfile <<'EOF'
FROM eclipse-temurin:17-jre-jammy
RUN apt-get update && apt-get install -y --no-install-recommends python3 && rm -rf /var/lib/apt/lists/*
COPY apache-storm-2.8.9.tar.gz /tmp/
RUN cd /tmp && tar -xzf apache-storm-2.8.9.tar.gz \
&& mv apache-storm-2.8.9 /opt/storm \
&& rm -f /tmp/apache-storm-2.8.9.tar.gz \
&& mkdir -p /data/storm
WORKDIR /opt/storm
EOF
| 关键点 | 说明 |
|---|---|
python3 | Storm 命令行/守护进程包装脚本必需 |
COPY + tar | 先拷包再解压,比构建时外网下载快且可离线复现 |
/data/storm | 预建 storm.local.dir,供挂卷持久化 |
4.3 编写 storm.yaml(容器间用服务名互访)
cat > conf/storm.yaml <<'EOF'
storm.zookeeper.servers:
- "zookeeper"
nimbus.seeds: ["nimbus"]
storm.local.dir: "/data/storm"
supervisor.slots.ports:
- 6700
- 6701
- 6702
- 6703
ui.port: 8080
logviewer.port: 8081
nimbus.childopts: "-Xms256m -Xmx512m"
supervisor.childopts: "-Xms256m -Xmx512m"
ui.childopts: "-Xms256m -Xmx512m"
logviewer.childopts: "-Xms256m -Xmx512m"
EOF
💡 Compose 内置 DNS 按服务名解析:ZooKeeper 地址写服务名
zookeeper,Nimbus 种子写nimbus。四个守护进程的 JVM 堆统一限制为 256-512MB。
4.4 编写 docker-compose.yml
cat > docker-compose.yml <<'EOF'
services:
zookeeper:
image: zookeeper:3.9.3
container_name: storm-zk
restart: unless-stopped
environment:
ZOO_4LW_COMMANDS_WHITELIST: "srvr,ruok,mntr"
ports:
- "2181:2181"
nimbus:
image: storm:2.8.9
container_name: storm-nimbus
restart: unless-stopped
command: ["/opt/storm/bin/storm", "nimbus"]
depends_on:
- zookeeper
volumes:
- ./conf:/opt/storm/conf
- nimbus-data:/data/storm
ports:
- "6627:6627"
supervisor:
image: storm:2.8.9
container_name: storm-supervisor
restart: unless-stopped
command: ["/opt/storm/bin/storm", "supervisor"]
depends_on:
- nimbus
volumes:
- ./conf:/opt/storm/conf
- supervisor-data:/data/storm
- worker-logs:/opt/storm/logs
ports:
- "6700:6700"
- "6701:6701"
ui:
image: storm:2.8.9
container_name: storm-ui
restart: unless-stopped
command: ["/opt/storm/bin/storm", "ui"]
depends_on:
- nimbus
volumes:
- ./conf:/opt/storm/conf
ports:
- "18080:8080"
logviewer:
image: storm:2.8.9
container_name: storm-logviewer
restart: unless-stopped
command: ["/opt/storm/bin/storm", "logviewer"]
depends_on:
- supervisor
volumes:
- ./conf:/opt/storm/conf
- worker-logs:/opt/storm/logs
ports:
- "8081:8081"
volumes:
nimbus-data:
supervisor-data:
worker-logs:
EOF
| 配置项 | 说明 |
|---|---|
image: storm:2.8.9 | 自建镜像,五个服务共用,command 决定各自角色 |
command: ["/opt/storm/bin/storm", "nimbus"] | 前台运行对应守护进程,PID 1 可被 compose 跟踪,崩溃自动重启 |
ports: 18080:8080 | UI 映射到宿主机 18080(宿主机 8080 被 haproxy 占用时的高位端口规避,实测踩坑见 11.1) |
volumes: ./conf:/opt/storm/conf | 挂载自定义 storm.yaml,改配置后 docker compose restart 即生效 |
volumes: nimbus-data / supervisor-data | Nimbus 与 Supervisor 各自独立的 storm.local.dir(二者本就不应共享本地状态目录) |
volumes: worker-logs | Supervisor 与 Logviewer 共享 /opt/storm/logs,Logviewer 才能看到 Worker 日志 |
4.5 构建镜像并启动
docker build -t storm:2.8.9 .
docker compose up -d
实测回显(节选):
Container storm-logviewer Creating
Container storm-logviewer Created
Container storm-zk Starting
Container storm-zk Started
Container storm-nimbus Starting
Container storm-nimbus Started
Container storm-ui Starting
Container storm-supervisor Starting
Container storm-supervisor Started
Container storm-ui Started
Container storm-logviewer Started
4.6 验证服务
docker compose ps --format '{{.Name}} {{.Status}}'
实测回显:
storm-logviewer Up 30 seconds
storm-nimbus Up About a minute
storm-supervisor Up About a minute
storm-ui Up 30 seconds
storm-zk Up About a minute
Storm UI 接口验证(ui 服务内):
docker exec storm-ui curl -s http://127.0.0.1:8080/api/v1/cluster/summary
实测回显(节选):
{"stormVersion":"2.8.9","fragmentedCpu":0.0,"executorsTotal":0,"totalMem":4096.0,"availCpu":400.0,"slotsTotal":4,"stormVersionInfo":{"date":"2026-07-18T15:27Z","srcChecksum":"dd8ab586a06db2ced58135f6be47980",...
宿主机侧验证映射端口与 CLI:
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:18080/
docker exec storm-nimbus /opt/storm/bin/storm list
实测回显:
200
Running: java -client -Ddaemon.name= ... org.apache.storm.command.ListTopologies
13:27:34.919 [main] INFO o.a.s.u.NimbusClient - Found leader nimbus : 02503e8a5ea5:6627:0
No topologies running.
💡
Found leader nimbus说明 Nimbus/ZooKeeper/Supervisor 协调链路全部打通。浏览器访问http://<宿主机IP>:18080即 Storm UI。
五、数据持久化说明
nimbus-data卷持久化 Nimbus 的 storm.local.dir(拓扑 jar 暂存 inbox、分配状态),删除服务不丢上传记录。supervisor-data卷持久化 Supervisor 本地状态(worker 心跳等),独立于 nimbus 卷,符合真实集群「各节点本地目录不共享」原则。worker-logs卷被 supervisor 与 logviewer 共享挂载到/opt/storm/logs:Worker 日志落此卷,Logviewer 网页(8081)据此展示拓扑各组件日志。./conf宿主机目录挂载:修改storm.yaml后执行docker compose restart nimbus逐服务重启生效,配置随目录持久化。docker compose down保留三个命名卷;docker compose down -v才会清空数据。
六、常用环境变量表
Storm 自身主要靠 storm.yaml 配置,Compose 层常用的环境变量如下:
| 环境变量 | 适用服务 | 说明 | 本指南值 |
|---|---|---|---|
ZOO_4LW_COMMANDS_WHITELIST | zookeeper | 放行四字命令(srvr/ruok/mntr)供健康检查 | srvr,ruok,mntr |
STORM_JAVA_HOME | 全部 Storm 服务 | 指定 java 路径(基础镜像默认已在 PATH,一般无需设置) | 不设置 |
ZOO_MY_ID / ZOO_SERVERS | zookeeper | 组建多节点 ZK 集群时使用(单节点无需) | 不设置 |
💡 JVM 堆由
storm.yaml的*.childopts控制而非环境变量,这也是自建镜像 + 挂载 conf 的好处:四守护进程堆 256-512MB 集中一处管理。
七、常用配置参数说明(command)
command 字段覆盖镜像默认进程,对应 /opt/storm/bin/storm <daemon> 前台运行:
| command 值 | 说明 |
|---|---|
["/opt/storm/bin/storm", "nimbus"] | 主控守护进程,拓扑分发与调度(本指南 nimbus 服务) |
["/opt/storm/bin/storm", "supervisor"] | 工作节点守护进程,拉起 Worker(本指南 supervisor 服务) |
["/opt/storm/bin/storm", "ui"] | Web UI,默认 8080(本指南 ui 服务) |
["/opt/storm/bin/storm", "logviewer"] | 日志查看服务,默认 8081(本指南 logviewer 服务) |
八、配置文件持久化(conf 挂载)
挂载 ./conf 后所有配置变更只改宿主文件,按服务逐个重启生效:
vim conf/storm.yaml
docker compose restart nimbus
docker compose restart supervisor
docker compose restart ui
docker compose restart logviewer
⚠️
storm.zookeeper.servers与nimbus.seeds必须写 compose 服务名(zookeeper/nimbus);改成容器内 IP 会在重启后因 IP 变化失联。改 JVM 堆时直接调*.childopts(当前-Xms256m -Xmx512m),无需动镜像。
九、等价 docker run 运行方式
不使用 compose 文件时,可等价地逐条 docker run(先自建网络供服务名解析):
docker network create storm-net
docker run -d --name storm-zk --network storm-net \
-p 2181:2181 zookeeper:3.9.3
docker run -d --name storm-nimbus --network storm-net \
-v "$PWD/conf:/opt/storm/conf" -v storm-nimbus-data:/data/storm \
-p 6627:6627 storm:2.8.9 /opt/storm/bin/storm nimbus
docker run -d --name storm-supervisor --network storm-net \
-v "$PWD/conf:/opt/storm/conf" -v storm-supervisor-data:/data/storm \
-v storm-worker-logs:/opt/storm/logs \
-p 6700:6700 -p 6701:6701 storm:2.8.9 /opt/storm/bin/storm supervisor
docker run -d --name storm-ui --network storm-net \
-v "$PWD/conf:/opt/storm/conf" \
-p 18080:8080 storm:2.8.9 /opt/storm/bin/storm ui
docker run -d --name storm-logviewer --network storm-net \
-v "$PWD/conf:/opt/storm/conf" -v storm-worker-logs:/opt/storm/logs \
-p 8081:8081 storm:2.8.9 /opt/storm/bin/storm logviewer
与 compose 版等价的关键:同一自定义网络(服务名互访)、相同 conf 挂载、supervisor 与 logviewer 共享 worker-logs 卷。
十、常用运维命令
docker compose up -d # 启动全栈
docker compose ps # 查看各服务状态
docker compose logs -f nimbus # 跟踪 nimbus 日志
docker compose logs -f supervisor # 跟踪 supervisor 日志
docker compose restart ui # 重启单个服务
docker exec storm-nimbus /opt/storm/bin/storm list # 容器内查看拓扑
docker compose down # 停止并删除服务(保留数据卷)
docker compose down -v # 停止并删除服务与数据卷
十一、常见问题(FAQ)
11.1:UI 服务启动失败,failed to bind host port 0.0.0.0:8080/tcp: address already in use
实测回显:
Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint storm-ui (...): failed to bind host port 0.0.0.0:8080/tcp: address already in use
定位:宿主机 8080 已被其他进程占用(实测环境为 haproxy,ss -tlnp | grep 8080 可见)。
解决:改用高位端口映射 18080:8080(本指南做法),或释放宿主机 8080 后再启动。
11.2:容器反复重启,日志报 /usr/bin/env: 'python3': No such file or directory
定位:基础镜像无 python3,storm 包装脚本无法执行。
解决:确认使用本指南 Dockerfile(apt-get install -y python3),重新 docker build。
11.3:storm list 卡住或报连接拒绝
定位:服务启动顺序问题,depends_on 只保证启动顺序不保证 ZooKeeper 就绪。
解决:ZooKeeper 起来后约 10-30 秒再执行;docker compose logs zookeeper 看到 binding to port 0.0.0.0/0.0.0.0:2181 后再试 CLI。
11.4:宿主机执行 docker compose up -d --build 尝试从远端拉取 storm:2.8.9 失败
定位:本地不存在该镜像时 compose 会先尝试 registry 拉取(Docker Hub 无官方 storm 镜像,必然失败)。
解决:先执行 docker build -t storm:2.8.9 . 构建本地镜像,再 docker compose up -d。
11.5:Logviewer 打不开拓扑日志
定位:logviewer 与 supervisor 不共享 /opt/storm/logs 卷,worker 日志不可见。
解决:按 4.4 节为两个服务挂载同一个 worker-logs 卷。
十二、参考链接
- Apache Storm 官方文档:https://storm.apache.org/releases/2.8.9/
- Apache Storm 下载:https://archive.apache.org/dist/storm/
- Docker Compose 文档:https://docs.docker.com/compose/
- 官方 ZooKeeper 镜像:https://hub.docker.com/_/zookeeper
- eclipse-temurin 镜像:https://hub.docker.com/_/eclipse-temurin