Webfunny_Monitor Docker 容器化部署指南:镜像构建、端口映射与健康检查实战
Webfunny_Monitor Docker 容器化部署指南:镜像构建、端口映射与健康检查实战
本指南以仓库内 DES_DOCKER.md 为核心,完整讲解 Webfunny 监控系统在完成正常部署之后,如何通过项目自带 Dockerfile 构建镜像、生成容器并对外发布的全过程。读完本文,你将掌握 docker image build / docker container run 的具体用法、8010/8011 双端口背后的真实职责划分、域名 + /server/health 心跳检测的实现位置,以及容器内 createTable.sh、restart.sh 脚本的授权必要性。
1. 前置条件:必须先完成正常部署
Docker 部署并不是独立流程,它建立在正常部署成功的基础之上。只有先完成 DES.md 中描述的标准部署,系统才会生成完整的运行环境与配置,此后才能把整个系统打成镜像文件。
正常部署的核心步骤(详见 DES.md)包括:
- 安装 Node.js(版本号 10.6.0 及以上);
- 克隆代码后,在项目根目录执行
npm install && npm run bootstrap完成初始化与依赖安装,并确认pm2 -v可用(若未安装,执行npm install pm2 -g); - 配置 MySQL 数据库连接(创建
webfunny_db数据库,字符集 utf8 / 排序规则 utf8_bin,并在bin/mysqlConfig.js中填写连接信息); - 执行
npm run prd启动服务(重启使用npm run restart),浏览器访问http://localhost:8010/webfunny/register.html?type=1初始化管理员账号; - 生产环境还需配置
bin/domain.js中的 IP 或域名,保证日志上报域名(8011)与前端页面域名(8010)均可访问。
从当前仓库的 package.json 可以看到,prd 命令的实际动作是:先执行 node ./webfunny_init/initResource.js 初始化资源,再通过 pm2 start webfunny_cluster.js 启动主进程并 pm2 save。这解释了为什么 Dockerfile 中 CMD npm run prd 一行即可拉起整个系统——容器启动后由 pm2 守护服务进程。
2. 镜像构建:从正常部署的工程到 Docker 镜像
完成正常部署后,就可以将整个系统作为镜像文件打包。仓库根目录下已提供现成的 Dockerfile,无需从零编写。先看它的完整内容,理解构建过程:
FROM node:16.20.2-slim
RUN echo "deb [check-valid-until=no] http://archive.debian.org/debian buster main" > /etc/apt/sources.list \
&& apt-get update && apt-get install -y --no-install-recommends \
iputils-ping \
curl \
telnet \
lsof \
net-tools \
vim \
&& rm -rf /var/lib/apt/lists/*
RUN npm install pm2 -g
COPY . /app
WORKDIR /app
RUN npm install
RUN npm run bootstrap
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' >/etc/timezone
EXPOSE 9010
EXPOSE 9011
CMD npm run prd
构建要点可拆解如下:
| Dockerfile 指令 | 作用 | 与部署流程的对应关系 |
|---|---|---|
FROM node:16.20.2-slim |
使用 Node 16 精简版基础镜像 | 满足 DES.md 中“Node 10.6.0 及以上”的版本要求 |
apt-get install |
预装 ping、curl、telnet、lsof、net-tools、vim 等诊断工具 | 便于容器内排查网络与端口问题 |
RUN npm install pm2 -g |
全局安装进程守护工具 | 对应正常部署中对 pm2 的要求 |
COPY . /app + WORKDIR /app |
将整个项目拷入容器并设为工作目录 | 等价于正常部署的克隆代码步骤 |
RUN npm install + RUN npm run bootstrap |
安装依赖并执行初始化 | 等价于正常部署第 1 步的初始化命令 |
| 时区设置 | 软链 Asia/Shanghai 时区文件并写入 /etc/timezone |
保证日志时间与国内业务时间一致 |
CMD npm run prd |
容器启动时以生产模式拉起服务 | 由 pm2 启动 webfunny_cluster.js |
随后执行镜像构建命令:
docker image build -t webfunny_monitor --platform linux/amd64 .
-t webfunny_monitor:为镜像指定名称与标签(等价写法webfunny_monitor:latest);--platform linux/amd64:显式指定目标平台。如果你的构建机器是 ARM 架构(如 Apple Silicon),这个参数能强制产出 x86_64 平台镜像,避免部署到云服务器(通常为 amd64)时出现平台不匹配;.:构建上下文为当前目录,Docker 会把该目录内容发送给守护进程用于构建。
小提示:需要拉取构建日志或进入容器排查时,可使用
docker image ls查看镜像是否生成成功。
3. 生成容器与端口映射:8010 / 8011 两个端口的分工
镜像构建完成后,使用以下命令生成并运行容器:
docker container run -p 8010:8010 -p 8011:8011 -it webfunny_monitor
监控系统会使用两个端口号:8010、8011,因此必须全部映射出来。 缺一个都会导致页面或日志上报不可用。端口分工可以从源码中得到印证:
- webfunny_cluster.js 从
webfunny.config的domainConfig.port中读取be(后端服务端口)与fe(前端静态资源端口),后端 HTTP 服务app.listen(port),静态文件服务器appStatic.listen(fe); - servers/monitor/config/monitor_cluster.js 与 servers/monitor/config/AccountConfig.js 进一步说明:
localServerPort(8011)承载监控系统后端服务(日志上报等接口),localAssetsPort(8010)承载数据可视化页面。
也就是说:
- 8010 = 前端页面端口:浏览器访问数据展示、控制台界面;
- 8011 = 日志上报端口:探针 SDK 通过该端口上报日志与行为数据。
一个常见疑问是:仓库 Dockerfile 中写的是 EXPOSE 9010 / EXPOSE 9011,而文档与部署流程用的是 8010 / 8011。需要说明的是:EXPOSE 仅是声明性信息,真正生效的端口取决于运行时配置(webfunny.config 中的 domainConfig.port)。因此实际映射仍以 DES_DOCKER.md 与 DES.md 中的 8010 / 8011 为准;-p 8010:8010 -p 8011:8011 是文档验证过的标准用法。
关于 -it:交互模式便于在容器前台观察 pm2 启动日志;若希望容器后台运行,可改为 docker container run -d -p 8010:8010 -p 8011:8011 webfunny_monitor。
4. 镜像发布:上传云镜像仓库再部署到目标服务器
容器验证通过后,你可以将镜像发布到自己的云镜像仓库(如云厂商的镜像服务),再在任何目标机器上拉取使用。发布流程一般分三步:
# 1. 为本地镜像打上远程仓库地址的标签
docker tag webfunny_monitor <your-registry>/webfunny_monitor:latest
# 2. 登录镜像仓库
docker login <your-registry>
# 3. 推送镜像
docker push <your-registry>/webfunny_monitor:latest
目标服务器上执行:
docker pull <your-registry>/webfunny_monitor:latest
docker container run -p 8010:8010 -p 8011:8011 -d <your-registry>/webfunny_monitor:latest
镜像打包后,MySQL、配置文件(webfunny.config 目录等)以构建时 COPY . /app 的方式固化进镜像,因此发布前务必保证正常部署阶段的数据库连接与域名配置已完成并验证通过,否则镜像在目标环境启动后同样无法读写数据。
5. 心跳检测:域名 + /server/health
部署完成后,通过心跳检测地址确认服务健康状态:
域名 + /server/health
例如本地验证为 http://localhost:8011/server/health,生产环境则为 http://www.example.com:8011/server/health。从源码看,该路由在监控服务中真实存在:
- servers/monitor/router/routes/common.js 定义了
router.get('/health', Common.dockerHealth); - servers/monitor/router/routesFail.js 在降级路由中也注册了同样的
/health接口,保证极端情况下心跳依然可探; - middlreware/ignorePathRes.js 将
/health加入免鉴权白名单,因此心跳探测不需要登录态; - config/tracingConfig.js 也将
/health排除在链路追踪之外,避免健康检查请求污染监控数据。
说明:原文档写的是“域名 + /server/health”。结合路由注册在 monitor 服务(8011 端口)的事实,可推断完整地址形如
http://<域名>:8011/server/health(若通过反向代理把/server转发到该服务,也可直接用裸域名)。负载均衡器、云健康检查或运维脚本均可定期探测该地址来判断容器存活。
6. 容器内脚本执行权限:createTable.sh 与 restart.sh(重要)
文档特别强调:
容器配置要给项目根目录下 createTable.sh、restart.sh 脚本文件执行权限。
chmod 755 restart.sh,chmod 755 createTable.sh
如果不授权,系统可能无法自动创建每天的数据库表(DES.md 中同样有此警示)。原因是正常部署时这两个脚本缺少执行权限,需手动授权:
chmod 755 restart.sh
chmod 755 createTable.sh
在构建镜像时,由于 COPY . /app 会保留文件的原始权限位,若宿主机上脚本没有 x 权限,容器内同样不可执行。因此建议在镜像构建前先在项目根目录完成授权,或者挂载卷后在容器内执行上述命令。
需要说明的是:在当前仓库结构中,这两个脚本位于 servers/event/createTable.sh 与 servers/event/restart.sh(原始文档写作“项目根目录”是早期版本的路径描述)。restart.sh 用于重建容器内的服务进程,createTable.sh 负责按天预建数据库表;Docker 镜像中应确保对应的脚本文件具备 755 执行权限。
7. 常见问题与运维建议
结合 Dockerfile 与启动脚本,给出以下容器化运维注意事项:
- 时区已内置:Dockerfile 中已固定
Asia/Shanghai,容器内日志时间默认即东八区,无需额外-e TZ=Asia/Shanghai(除非你的业务使用其他时区)。 - 数据持久化:
docker container run默认不持久化任何数据。MySQL 数据存储在宿主机数据库(正常部署阶段已配置),容器重启不会丢失;但若把配置目录或日志目录挂载出来(-v),请确认挂载内容与镜像内路径一致,避免覆盖初始化产物。 - 重启策略:生产环境建议增加
--restart unless-stopped,配合 pm2 的双重守护提高可用性。 - 健康检查结合自监控:仓库在 webfunny_init/selfMonitor.init.js 的自监控配置中也将
/health、/ping等 URL 加入忽略列表,说明/health是系统约定的“纯净”探活路径,适合作为容器健康检查(HEALTHCHECK)或云平台探针目标。 - 端口一致性:域名与端口的对应关系在
webfunny.config(由正常部署阶段初始化生成)中定义,容器映射的 8010/8011 必须与配置文件保持一致,否则探针上报与页面访问会失败。
8. 延伸学习
Docker 构建、容器运行、镜像标签与推送、数据卷、网络模式等更多基础操作,可参考 Docker 官方文档与阮一峰的《Docker 入门教程》系列文章;本仓库中的 DES.md 则覆盖了从零开始的非容器化完整部署流程,是理解镜像内各组件关系的最佳入口。
适用前提说明:本文所有命令与配置均以当前仓库(含 DES_DOCKER.md 与 Dockerfile)为准。Docker 版本、宿主机平台架构、云镜像仓库差异可能导致命令细节略有出入,实际部署时请以你的 Docker 环境输出为准。