用Docker部署CoolMonitor:轻量级监控平台从零到一实战指南 前阵子朋友塞给我一台2C4G的小机器说让我帮忙“盯起来”。开始我没当回事结果真要装监控的时候才发现Prometheus全家桶装完内存先干掉一大半用Zabbix又嫌太重配置起来没有一两个晚上下不来。翻了一圈最后落在CoolMonitor上——一个用Docker就能跑起来的轻量级监控平台服务端加Agent半小时能把一台服务器管起来CPU、内存、磁盘、网络这些基础指标全都有还支持钉钉、邮件、Webhook告警。这篇文章就把我从零到一部署CoolMonitor的完整过程捋一遍从Docker环境准备、镜像加速、Compose编排到服务端启动、Agent接入、告警配置最后是几个常见的坑。手上有Linux服务器、又不想被Prometheus和Grafana折腾的小团队和个人开发者可以直接照着抄。1. 为什么选CoolMonitor轻量级监控平台的选型思路1.1 主流监控方案为什么不适合小机器先聊聊选型。很多人一说到监控脑子里蹦出来的就是Prometheus加Grafana这套方案确实是主流功能强、生态大但代价也不小。Prometheus本身要占一块资源各种exporter要一个个装Grafana面板虽然好看配置告警规则还得学PromQL。一台2G内存的小服务器光跑这套东西就够呛。Zabbix是老牌的重量级选手功能扎实但它的Agent配置、模板关联、权限体系对个人和小团队来说明显偏重。云厂商自带的监控倒是省事但要么绑定了自家云主机要么按量计费长期算下来成本不低而且跨云场景就抓瞎了。所以我的需求其实很简单能装在一台小机器上看到所有服务器的核心指标异常的时候能第一时间通知我不需要那么多花哨的功能。CoolMonitor就是冲着这个定位来的。它本身就是一个开源项目GitHub上直接能搜到部署方式非常灵活尤其对Docker支持得很好不需要在宿主机装一堆依赖这也是我最后选它的原因。1.2 CoolMonitor的架构与“轻”在哪里CoolMonitor的架构很直观就两个角色服务端server和客户端agent。服务端负责三件事展示监控数据、存储历史记录、触发告警通知。它自带一个Web控制台界面是中文的功能布局很清晰不需要额外搭建前端。客户端也就是Agent装在每台被监控的机器上负责采集CPU使用率、内存占用、磁盘空间、网络流量、系统负载、TCP连接数这些基础指标然后定时上报给服务端。数据存储用的是MySQL部署的时候我们直接把MySQL也容器化省掉宿主机装数据库的麻烦。这个设计比较务实MySQL大家都很熟遇到问题好排查不像某些监控系统一上来就要求ClickHouse或者专门的时序数据库对小项目来说完全是负担。“轻”体现在几个地方部署轻、资源占用轻、配置成本轻。我自己实测服务端加MySQL两个容器跑在2C4G的小机器上日常内存占用在700MB左右剩下的资源该干嘛干嘛。配置上也不需要理解一堆概念装好Agent就能看到数据整个过程没有太多弯弯绕。1.3 为什么非要用Docker部署直接裸装CoolMonitor其实也行但要自己装JDK、装MySQL、配环境变量、管理服务一台机器折腾半小时起步换台机器再折腾一遍。用Docker部署的核心好处是环境隔离和一键拉起所有依赖打进镜像里宿主机只要有一个Docker引擎就够了。而且Compose文件本身就是最好的部署文档。我在这台机器上排好的服务编排复制到另一台机器改几个IP就能跑起来。后面升级版本拉新镜像重新up一下就完事不用关心底层依赖的变动。打个比方裸装监控像自己买地盖房地基、管道、水电全得自己操心Docker部署像拎包入住钥匙一插就能住。对于“自己手上几台服务器想快速搞定监控”这种场景后者明显更划算。2. 部署前夜Docker环境与依赖准备2.1 跨平台Docker安装与权限踩坑不管什么方案第一步都是把Docker装好。如果你用的是Linux服务器Ubuntu和Debian系可以直接用官方安装脚本curl -fsSL https://get.docker.com | bashCentOS/RHEL系需要先配置Docker的yum源然后yum install -y docker-ce再执行systemctl enable --now docker启动服务。装完之后用docker --version验证一下能输出版本号就说明装好了。这里有个高频坑装完Docker之后执行docker ps结果报permission denied这是因为当前用户不在docker组里。解决办法是把用户加进docker组sudo usermod -aG docker $USER然后重新登录终端再次执行docker ps就正常了。说真的这个权限问题我见人踩过无数次每次都以为是Docker装坏了其实就是少了一步加组。Windows和macOS用户就用Docker Desktop。安装本身不复杂但有一个前置条件必须在BIOS里开启CPU虚拟化并且系统已经启用WSL2否则启动时会直接报Virtualization support not detectedDocker Desktop根本起不来。另外启动时如果遇到failed to connect to the docker api at npipe:////./pipe/dockerDesktopLinuxEngine这类报错大概率是Docker引擎还在初始化等一会儿或者右下角图标右键Restart一下就好。2.2 镜像加速先把“拉不下来”的坑填了Docker装好之后紧接着要面对的一个问题就是镜像下载慢。尤其在国内网络环境下从Docker Hub直接拉镜像经常卡在等待层下载一个大镜像能拉半小时。这个问题的解决方案是配置镜像加速源。编辑Docker的配置文件/etc/docker/daemon.json没有就新建一个填入镜像加速地址{ registry-mirrors: [ https://docker.mirrors.ustc.edu.cn, https://hub-mirror.c.163.com ] }配置完重启Dockersudo systemctl restart docker验证是否生效用docker info查看在输出里能看到Registry Mirrors列表。建议多配两三个源有些加速源偶尔不稳定多配几个能在拉取失败时自动切换。后面部署CoolMonitor要拉MySQL、服务端镜像先把这步做好能省下不少等待时间。2.3 Docker Compose多容器编排的“配方表”CoolMonitor部署涉及两个容器MySQL数据库和服务端。如果手动一个一个docker run要写两长串命令还要额外创建自定义网络让它们互通麻烦不说换个环境全部重来。这时候就需要Docker Compose出场。Compose用一份YAML文件定义所有服务、网络、数据卷一条docker compose up -d全部拉起一条docker compose down全部清理。它做的事情本质上就是把容器的启动参数写进配置、管理起来对于“一个项目多个容器互相协作”的场景非常合适。新版Docker包括Docker Desktop已经内置了docker compose命令不需要单独安装。老版本的Docker可能需要单独装docker-compose。先跑一下docker compose version能输出版本就是现成的。写Compose文件的时候它会自动帮我们创建一个默认网络所有服务通过服务名就能互相访问这就避免了手动配置--link或者自定义bridge网络的麻烦。很多人遇到的“容器之间网络不通”本质上就是没接入同一个网络Compose从设计上就把这个问题解决了。3. 服务端部署3条命令拉起CoolMonitor控制台3.1 目录规划与docker-compose.yml详解准备工作做完开始正式部署。先在服务器上规划一个部署目录我习惯放在/opt/coolmonitor下面mkdir -p /opt/coolmonitor/server/logs mkdir -p /opt/coolmonitor/mysql-data cd /opt/coolmonitorserver/logs放服务端运行日志mysql-data放MySQL数据文件。为什么要单独挂出来因为容器本身是“一次性”的删掉重建数据就没了把数据目录挂载到宿主机万一容器出问题数据还在换个镜像重新启动就能恢复。然后编写Compose文件vim docker-compose.yml3.2 MySQL 8.0容器与服务端的连接配置下面是我实际使用的Compose配置里面加了注释说明每个部分的作用services: mysql: image: mysql:8.0 container_name: coolmonitor-mysql restart: always environment: MYSQL_ROOT_PASSWORD: root123456 MYSQL_DATABASE: coolmonitor MYSQL_USER: coolmonitor MYSQL_PASSWORD: coolmonitor123 command: - --character-set-serverutf8mb4 - --collation-serverutf8mb4_unicode_ci volumes: - /opt/coolmonitor/mysql-data:/var/lib/mysql networks: - coolmonitor-net server: image: coolmonitor/server:latest container_name: coolmonitor-server restart: always depends_on: - mysql environment: DB_HOST: mysql DB_PORT: 3306 DB_NAME: coolmonitor DB_USER: coolmonitor DB_PASSWORD: coolmonitor123 TZ: Asia/Shanghai ports: - 8080:8080 volumes: - /opt/coolmonitor/server/logs:/app/logs networks: - coolmonitor-net networks: coolmonitor-net: driver: bridge这里有几个细节值得说明。MySQL容器里我用的是mysql:8.0镜像这也是现在主流的版本初始化时会自动创建coolmonitor这个数据库和对应的业务账号。root密码设置了一个比较随意的值主要用于应急管理实际业务连接用的是专门的coolmonitor用户权限被限定在单库内不会出现业务账号误删其他库的问题。command里加了--character-set-serverutf8mb4和--collation-serverutf8mb4_unicode_ci这是为了让数据库默认使用utf8mb4字符集。如果不设置MySQL默认的latin1字符集存中文标签和主机名时会出现乱码监控页面上一堆问号排查起来很头疼。服务端的DB_HOST: mysql是Compose网络里的服务名。在同一网络内容器之间直接用服务名解析IP不需要知道MySQL容器的具体IP地址。这也是我把MySQL的3306端口只暴露在容器网络内部、不映射到宿主机的根本原因——服务端能连上就行宿主机和其他机器没必要访问MySQL端口减少了暴露面。需要提醒一点depends_on只保证MySQL容器先启动但不保证MySQL已经完成初始化、可以接受连接。服务端第一次启动时如果MySQL还没准备好可能会连库失败。不过restart: always会在容器退出后自动拉起多尝试几次等到MySQL初始化完成就能连上。如果自己部署时遇到server容器反复重启先别慌看日志确认是不是数据库没就绪多半等一两分钟就自己好了。不同版本的CoolMonitor server镜像环境变量名可能会有些细微差异。我写的是当前稳定版的情况如果你下载的镜像版本较新建议先看一眼镜像仓库里的README确认一下变量名思路都是相通的。3.3 启动验证与Web初始化Compose文件写好后启动就三行命令docker compose up -d docker compose ps docker compose logs -f serverdocker compose up -d以后台方式启动所有服务docker compose ps能看到两个容器的运行状态正常情况下都应该是Up。docker compose logs -f server用来实时跟踪服务端日志看到类似“启动成功”或者“数据库连接成功”的字样就说明服务端已经正常起来了。接着在浏览器里访问http://服务器IP:8080。第一次访问会进入初始化页面按照提示创建管理员账号填好基本信息后就进入了CoolMonitor的主控制台。到这里服务端就部署完了整个过程确实只需要几分钟。如果页面打不开优先检查两件事一是8080端口有没有被防火墙拦截二是服务端容器是不是真的起来了。执行docker compose logs server看日志比盲目重启靠谱得多。4. Agent接入让第一台服务器“开口说话”4.1 后台添加主机与采集模式选择服务端跑起来只是第一步没接监控对象的时候控制台就是一空壳。进入后台后左侧菜单找到“主机管理”点击“添加主机”。填写主机名比如web-01然后选择采集方式为Agent方式。提交之后页面会生成这条主机对应的接入信息核心是一串Token这个Token相当于Agent的“入场券”用来标识并认证Agent身份Agent上报数据时必须携带它不能泄露。这里要注意一个点CoolMonitor支持不同的采集模式如果你的服务端和被监控机器在同一个内网服务端可以直接访问Agent用被动拉取模式就行如果被监控机器在公网或者两台机器之间有防火墙隔离建议用主动上报模式让Agent主动连服务端省去服务端去访问目标机器的麻烦。我自己的服务器分布比较散统一用主动上报模式少了一堆网络策略的烦恼。4.2 一条Docker命令部署Agent在目标机器上执行docker run命令就能把Agent拉起来同样需要目标机器先装好Docker命令模板如下docker run -d \ --name coolmonitor-agent \ --restartalways \ --networkhost \ -e TOKEN后台生成的Token \ -e SERVER_HOST服务端IP或域名 \ -e SERVER_PORT8080 \ coolmonitor/agent:latest解释一下几个参数--restartalways保证Agent随Docker自启、挂了会自动拉起监控Agent本身可不能掉链子--networkhost直接让Agent使用宿主机网络栈这样它能拿到宿主机真实的网络流量数据也避免了端口映射的麻烦。不过要注意如果你用的是Windows或macOS上的Docker Desktop--networkhost是不支持的这时去掉这个参数、用默认的bridge模式也行只要Agent能访问到服务端的IP和端口就可以。想在Docker容器里拿到宿主机准确的磁盘和完整系统指标通常还需要把宿主机的根目录挂载进容器给Agent读取docker run -d \ --name coolmonitor-agent \ --restartalways \ --networkhost \ -v /:/hostfs:ro \ -e TOKEN后台生成的Token \ -e SERVER_HOST服务端IP或域名 \ -e SERVER_PORT8080 \ coolmonitor/agent:latest这个挂载目录里的hostfs这个名字不同版本可能有差异具体看镜像文档。它的作用相当于让容器里的Agent能“看到”宿主机全貌。不挂载也能采集到CPU内存这类基础指标但如果你想看准确的主机磁盘分区和网络流量挂载会更完整。4.3 验证监控数据与告警规则配置Agent起来之后回到CoolMonitor后台等上一两个采集周期一般30秒到1分钟主机状态会从“离线”变成“在线”点击主机名进去就能看到CPU、内存、磁盘、网络这些指标的实时曲线。如果主机状态一直是灰色或者所有数据都是0不急着猜先到Agent容器里看日志docker logs -f coolmonitor-agent日志里一般会直接写着上报成功还是连接失败。连接失败的原因无非就那几类服务端地址填错、8080端口不通、Token不对按顺序排查就行。数据通了之后就可以配置告警了。在后台找到“告警通知”选择钉钉、企业微信、邮件或者自定义Webhook。以钉钉为例在自己钉钉群里添加一个机器人拿到Webhook地址填到告警通知配置里保存后点“测试”钉钉群能收到一条测试消息就说明通道是通的。然后配置告警规则比如CPU使用率超过80%、磁盘剩余空间低于10GB、内存使用率超过90%、Agent离线超过5分钟这些都是很实用的规则。规则配好之后平台会在触发条件时自动把告警消息推送到通知渠道。5. 部署避坑手册Docker与监控平台的疑难杂症5.1 Agent掉线、端口不通、网络策略排查整个部署流程走下来Agent掉线是最常见的问题没有之一。我自己的排查顺序固定是这样先用docker ps确认Agent容器还在不在容器都没了那肯定掉线看docker logs找原因。容器正常的情况下再确认Agent能不能访问到服务端的8080端口可以在目标机器上执行telnet 服务端IP 8080通不通一目了然。网络不通的时候要注意是服务端主动访问Agent还是Agent主动访问服务端。使用主动上报模式时只要Agent到服务端的端口通就行反向不需要。如果你用的是被动拉取模式就要保证服务端能访问到Agent的采集端口防火墙规则也要对方向开放。很多刚开始接触的朋友在这里栽跟头就是因为只放行了一个方向。还有一个小细节容易被忽略时间不同步。如果Agent所在机器和服务端系统时间相差太大上报的数据会出现时间戳错乱监控图上可能出现数据不刷新或者曲线时间对不上的情况。所以被监控机器的date命令看一眼时间偏差大就用NTP同步一下。5.2 Docker服务本身启不动的场景还有一类问题出在Docker本身而不是CoolMonitor。很多人刚接触Docker就是在Windows上Docker Desktop启动时报Virtualization support not detected这个几乎都是BIOS虚拟化没开。进BIOS找到Intel Virtualization Technology或者AMD SVM选项改成Enabled重启电脑问题就解了。在Windows上装了Docker Desktop也开了虚拟化结果启动又报failed to connect to the docker api at npipe:////./pipe/dockerDesktopLinuxEngine这个通常是Docker引擎还没完全起来或者WSL2组件状态异常。最省事的做法是等几秒再点一次启动不行就右键Docker Desktop图标选Restart还不行就到“Windows功能”里把“适用于Linux的Windows子系统”关掉再开一次。这几个操作覆盖了绝大多数启动异常的场景。Linux服务器上Docker起不来的情况常见的是配置了daemon.json后语法错误导致Docker服务启动失败执行systemctl status docker能看到详细的报错信息。我的经验是改完JSON文件一定先python3 -m json.tool /etc/docker/daemon.json验证一下语法再重启服务能省掉很多低级错误。5.3 数据库初始化失败与容器反复重启MySQL容器起不来先看数据目录的权限。MySQL镜像内的mysql用户UID是999如果宿主机挂载目录权限不对容器会没有写权限直接启动失败。简单粗暴的解决办法chown -R 999:999 /opt/coolmonitor/mysql-data然后重启容器。这个坑在Linux服务器上非常高频挂载目录到MySQL容器前先把权限调整好就少一次折腾。服务端容器反复重启日志里一般会写连接数据库失败。原因不外乎三个MySQL还没准备好、数据库账号密码不对、服务端环境变量配置错误。前面两个等一会儿或者核对Compose文件里的密码就能解决第三个就需要对着README仔细确认环境变量名了。另外一个问题是磁盘空间。CoolMonitor的监控数据存在MySQL里运行时间长了数据文件会慢慢变大。如果宿主机磁盘本身就不宽裕可能跑到几个月后突然发现整个Docker起不来查看磁盘才发现100%占满。建议在部署时就设置好MySQL的历史数据清理策略或者定期手动清理CoolMonitor里的旧监控记录别等问题发生再处理。6. 跑起来之后把平台用得更顺手的几个习惯6.1 告警阈值设置技巧很多人部署完监控平台第一件事就是把告警规则全部配满恨不得任何指标波动都收到通知。我劝你冷静告警规则刚上线时不该追求“全”而该追求“准”。我的做法是先让服务器裸跑一天看看正常状态下的基线数据——CPU一般多少、内存占用多少、磁盘每天涨多少。然后在这个基线上设置告警阈值比如正常CPU在20%到30%摆动阈值就设在80%。这样既不会错过真实异常也不会因为稍微一分钟的波动把自己吓醒。告警频率也要设置好一般5分钟起步。如果一条告警触发后Agent连续上报都满足条件平台会持续推送设置合理的重复通知间隔能有效避免“你的手机被同一台服务器的同一条告警轰炸到没电”。凌晨的告警确实没人看有条件的话加一个静默时段把凌晨2点到7点的告警先收住早上再统一查看。6.2 日常维护与升级小建议最后聊几个日常维护习惯。第一个是定期看数据。监控平台跑起来不代表万事大吉跟着主动看一眼趋势图比如每天早上去看一眼磁盘空间曲线很多隐患都是在数据曲线里提前发现的。第二个是镜像升级。CoolMonitor项目迭代不算很快但偶尔会有更新。升级前先备份Compose文件和MySQL数据目录然后拉取新镜像重新执行docker compose up -d。建议在夜间或者影响面小的时间段操作升级完第一时间看日志确认服务正常。第三个就是前面提过的历史数据清理。给MySQL数据目录预留充足空间或者定期进后台删除几个月前的历史记录让监控平台本身不成为新的风险点。我自己在部署的目录里放了一个简单的备份脚本每周把mysql-data目录压缩备份一次至少不会在出问题的时候发现备份都没有。这套方案跑下来我个人最大的感受是CoolMonitor作为轻量级监控平台确实称职Docker部署方式把门槛压得非常低一个下午从零到全部服务器上线是完全可行的。如果你也在找一套不占资源、够用就好的监控方案照着这个流程操作一遍大概率不会让你失望。