☰
Docker 部署 Zabbix 实战:从 compose 编排到避坑指南
2026/10/14 8:07:25 网站建设 项目流程

简介:这份资源面向需要在Linux服务器上快速搭建监控平台的运维人员与开发者,提供两种基于Docker部署Zabbix的完整代码方案。一种通过docker-compose.yml一键编排Zabbix服务器、MySQL数据库与前端服务,另一种借助宝塔面板已有数据库创建Zabbix容器,读者可按现有环境灵活选择。压缩包共5个文件,约11KB,包含yml编排文件、html页面、gitignore配置、inscode项目描述及README说明文档,结构精简,便于直接复用与二次修改。资源重点解决环境变量配置、端口映射与容器启动等部署难点,帮助读者省去手动安装依赖的繁琐过程,快速获得可运行的Zabbix监控环境,并在此基础上理解容器化监控系统的组织方式。目前已有46人学习,适合具备基础Docker与Linux操作经验、希望提升运维效率的技术人员参考。

1. Docker 装 Zabbix:为什么我劝你别再手动编译了

如果你还在用源码编译的方式部署 Zabbix,大概率经历过这样的夜晚:PHP 版本不对、MySQL 字符集报错、前端白屏、agent 连不上 server,折腾到凌晨三点还没看到登录页。Docker 安装 Zabbix 这件事,本质上不是“图省事”,而是把一套由 Web 前端、Server、数据库、Agent 四个组件构成的监控系统,用容器编排的方式一次性拉起来,让版本依赖和配置漂移这两个最大的坑从根上消失。

这套方案适合三类人:一是手里只有一两台测试机、想快速验证 Zabbix 能力的中小团队运维;二是需要给客户做监控演示、不想在环境上浪费时间的集成工程师;三是已经用过 Zabbix 但被升级和迁移折磨过、想换一种更可控部署方式的老手。读完你能拿到一套可直接复现的 compose 编排、关键参数怎么调、以及我踩过的五个真实坑。下面从选型开始讲。

2. 镜像选型与 compose 编排:四个容器怎么摆

2.1 为什么是 zabbix-server-mysql + mysql + zabbix-web-nginx + agent

Zabbix 官方在 Docker Hub 上维护了一整套镜像,命名规则是zabbix/zabbix-server-mysql、zabbix/zabbix-web-nginx-mysql、zabbix/zabbix-agent这种“组件+数据库+Web服务器”的组合形式。选型时最容易纠结的是 Web 前端用 nginx 还是 apache,我的建议是 nginx 版本,镜像体积更小,静态资源响应更快,而且配置环境变量的方式和 apache 版本完全一致,迁移没有额外成本。

数据库这块,虽然官方也提供 PostgreSQL 版本,但绝大多数存量 Zabbix 用户用的是 MySQL,社区资料和排错经验也最丰富,所以本文以 MySQL 为主线。Server 和 Web 必须用同一个大版本号,比如都用 6.4 或都用 6.0,混用会出现数据库 schema 不匹配,前端直接报“数据库版本不兼容”。Agent 版本可以略低于 Server,但不要跨大版本。

四个容器的职责要分清:MySQL 存配置和历史数据,Server 做数据采集和触发器计算,Web 提供前端界面,Agent 负责被监控主机上的指标采集。很多人第一次部署时把 Agent 也塞进同一台机器,这没问题,但要记得 Agent 默认是被动模式,Server 要能反向连到 Agent 的 10050 端口。

2.2 一份可直接跑的 docker-compose.yml

下面这份编排我用了很多次,改一下密码和时区就能跑。注意所有服务在同一个自定义网络里,用服务名互相访问,不要用 localhost。

version: '3.8' services: mysql-server: image: mysql:8.0 container_name: zabbix-mysql restart: unless-stopped environment: MYSQL_DATABASE: zabbix MYSQL_USER: zabbix MYSQL_PASSWORD: zabbix_pwd_2024 MYSQL_ROOT_PASSWORD: root_pwd_2024 TZ: Asia/Shanghai command: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_bin - --default-authentication-plugin=mysql_native_password volumes: - ./mysql-data:/var/lib/mysql networks: - zbx-net zabbix-server: image: zabbix/zabbix-server-mysql:alpine-6.4-latest container_name: zabbix-server restart: unless-stopped environment: DB_SERVER_HOST: mysql-server MYSQL_DATABASE: zabbix MYSQL_USER: zabbix MYSQL_PASSWORD: zabbix_pwd_2024 TZ: Asia/Shanghai ports: - "10051:10051" depends_on: - mysql-server networks: - zbx-net zabbix-web: image: zabbix/zabbix-web-nginx-mysql:alpine-6.4-latest container_name: zabbix-web restart: unless-stopped environment: ZBX_SERVER_HOST: zabbix-server DB_SERVER_HOST: mysql-server MYSQL_DATABASE: zabbix MYSQL_USER: zabbix MYSQL_PASSWORD: zabbix_pwd_2024 PHP_TZ: Asia/Shanghai TZ: Asia/Shanghai ports: - "8080:8080" depends_on: - mysql-server - zabbix-server networks: - zbx-net zabbix-agent: image: zabbix/zabbix-agent:alpine-6.4-latest container_name: zabbix-agent restart: unless-stopped environment: ZBX_HOSTNAME: docker-agent-01 ZBX_SERVER_HOST: zabbix-server ZBX_SERVER_PORT: 10051 TZ: Asia/Shanghai ports: - "10050:10050" depends_on: - zabbix-server networks: - zbx-net networks: zbx-net: driver: bridge

这份文件里几个关键点值得展开。command里的utf8mb4_bin排序规则是 Zabbix 官方要求的,用默认的utf8mb4_general_ci会在导入初始 schema 时报错。default-authentication-plugin=mysql_native_password是为了兼容老版本客户端,MySQL 8 默认的 caching_sha2_password 在某些 Zabbix 镜像里会握手失败。depends_on只保证启动顺序,不保证 MySQL 已经初始化完成,所以第一次启动时 Server 可能因为连不上数据库而重启一两次,这是正常的,等 MySQL 初始化完就会稳定。

2.3 启动顺序与初始化验证

编排文件写好后,不要直接docker-compose up -d就完事,第一次启动建议分两步走,方便观察日志。

# 第一步:只启动数据库,等它初始化完成 docker-compose up -d mysql-server # 观察日志,看到 "ready for connections" 再继续 docker-compose logs -f mysql-server # 第二步:启动其余三个服务 docker-compose up -d zabbix-server zabbix-web zabbix-agent # 查看整体状态 docker-compose ps

启动完成后,用浏览器访问http://你的主机IP:8080,默认账号是Admin,密码是zabbix。第一次登录后立刻改密码,这是基本安全习惯。如果页面打不开,先看docker-compose logs zabbix-web,八成是数据库还没就绪或者密码配错了。

验证 Server 是否正常,可以看它的日志里有没有server #0 started [main process]和database is up to date这两行。Agent 是否被监控到,去前端“数据采集 → 主机”里看,默认会有一个Zabbix server主机,如果它的可用性图标是绿色的 ZB 和 Z,说明 Server 自监控已经通了。

3. 关键参数怎么调:数据库、时区、资源限制

3.1 MySQL 参数:字符集、连接数、缓冲池

Zabbix 对数据库的写入压力不小,尤其是开启了大量监控项之后。MySQL 8 的默认配置在小规模场景够用,但有几个参数必须显式设置。

字符集和排序规则前面已经提过,utf8mb4+utf8mb4_bin是硬性要求。连接数方面,Zabbix Server 默认会开几十个到上百个连接,max_connections建议不低于 200。缓冲池innodb_buffer_pool_size如果机器内存有 8G,可以给到 2G 到 4G,这个参数对历史数据查询速度影响最大。

# 在 mysql-server 的 command 里追加 command: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_bin - --default-authentication-plugin=mysql_native_password - --max_connections=300 - --innodb_buffer_pool_size=2G - --innodb_log_file_size=512M

innodb_log_file_size调大能减少 checkpoint 频率,对写入密集的监控场景有好处,但改这个参数需要重建数据目录,第一次部署时就设好,别等跑了一段时间再改。

3.2 时区一致性:一个被低估的翻车点

Zabbix 前端显示的时间、触发器计算的时间、数据库存储的时间,三者必须一致。容器默认是 UTC,如果不设TZ和PHP_TZ,你会看到前端时间比实际时间少 8 小时,触发器在凌晨误报。

三个地方都要设:MySQL 容器的TZ、Server 容器的TZ、Web 容器的TZ和PHP_TZ。PHP_TZ是 Web 镜像特有的,它控制 PHP 的date.timezone,不设的话前端时间还是不对。Agent 容器也建议设TZ,否则 agent 采集到的时间戳会有偏差。

提示:改完时区后,已经写入的历史数据不会自动修正,测试环境可以直接清库重来,生产环境要谨慎。

3.3 资源限制与重启策略

四个容器里,MySQL 和 Server 是内存大户。用deploy.resources或者mem_limit限制一下,避免某个容器把宿主机内存吃光。我一般给 MySQL 2G、Server 1G、Web 512M、Agent 256M,具体看监控规模。

重启策略统一用unless-stopped,这样宿主机重启后容器会自动起来,但手动docker-compose stop的容器不会自己启动,符合运维直觉。不要用always,否则你调试时停掉的容器会被意外拉起,干扰排查。

# 以 zabbix-server 为例 deploy: resources: limits: memory: 1G restart: unless-stopped

4. 避坑与排查:五个让我加班到深夜的问题

4.1 前端报“Database error: Access denied”

现象是 Web 页面能打开,但登录后提示数据库访问被拒绝。原因通常是 MySQL 用户权限没配对,或者密码里有特殊字符被 compose 文件解析错了。Zabbix 的 MySQL 用户需要对zabbix库有全部权限,而且 host 要允许从容器网络访问。

解决方法是进 MySQL 容器手动检查:

docker exec -it zabbix-mysql mysql -uroot -p # 输入 root 密码后执行 SHOW GRANTS FOR 'zabbix'@'%';

如果看到的是'zabbix'@'localhost'而不是'zabbix'@'%',说明用户只允许本地连接。删掉重建,或者手动授权GRANT ALL ON zabbix.* TO 'zabbix'@'%';。密码里如果有$或#,在 compose 文件里要用单引号包起来,否则会被 shell 展开。

4.2 Server 启动后反复重启,日志显示“connection refused”

这是depends_on的经典陷阱。MySQL 容器虽然启动了,但初始化数据库需要几十秒,这期间 Server 连不上就退出,restart: unless-stopped又把它拉起来,循环几次后才稳定。如果一直循环,说明 MySQL 根本没起来,去看 MySQL 日志。

另一个可能是网络问题。四个容器必须在同一个自定义网络里,如果你用了默认的 bridge 网络,容器之间只能用 IP 互访,服务名解析不了。检查docker network inspect确认容器都在zbx-net里。

4.3 Agent 显示为红色,提示“Get value from agent failed”

Agent 容器起来了,但 Server 采集不到数据。先确认 Agent 的ZBX_SERVER_HOST填的是zabbix-server这个服务名,不是 IP。然后确认 Server 能解析到这个服务名,进 Server 容器ping zabbix-server试试。

如果网络通,检查 Agent 的ZBX_HOSTNAME和前端主机配置里的“主机名称”是否完全一致,包括大小写。Zabbix 靠主机名匹配,不一致就会拒绝数据。最后看 Agent 日志有没有listening on 0.0.0.0:10050,如果只监听 127.0.0.1,说明配置没生效。

4.4 历史数据暴涨,磁盘几天就满了

Zabbix 默认保留历史数据 90 天、趋势数据 365 天,监控项一多,MySQL 数据目录迅速膨胀。现象是df -h看到磁盘使用率飙升,MySQL 写入变慢。

解决分两步:短期在前端“管理 → 一般 → 管家”里调小保留天数,长期要配置数据库分区或者用 TimescaleDB。Docker 部署下,最直接的办法是给 MySQL 数据目录挂一块大磁盘,并且开启 binlog 过期清理。另外,history和trends表的清理是管家进程定时做的,如果管家进程没启动,数据永远不会删。

4.5 升级镜像后前端白屏或报 500

把镜像 tag 从 6.4 改成 6.5 后,前端直接 500。原因是数据库 schema 没升级。Zabbix 的 Server 启动时会自动执行数据库升级脚本,但如果 Web 先于 Server 启动,或者 Server 升级失败,前端就会因为表结构不匹配而报错。

正确做法是先停 Web 和 Agent,只启动 MySQL 和新版 Server,等 Server 日志出现database is up to date后再启动 Web。升级前务必备份数据库,docker exec zabbix-mysql mysqldump -uzabbix -p zabbix > backup.sql,这条命令能救命。

5. 进阶技巧:用环境变量做多环境配置与健康检查

5.1 用 .env 文件隔离环境差异

把密码、端口、时区这些会变的东西抽到.env文件里,compose 文件用${变量名}引用。这样测试环境和生产环境共用一份编排,只换.env就行。

# .env 文件内容 MYSQL_ROOT_PASSWORD=root_pwd_2024 MYSQL_ZABBIX_PASSWORD=zabbix_pwd_2024 WEB_PORT=8080 TZ=Asia/Shanghai

compose 里对应改成MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}、ports: - "${WEB_PORT}:8080"。注意.env文件不要提交到代码仓库,加进.gitignore。

5.2 给 Server 加健康检查,避免假死

Zabbix Server 偶尔会因为数据库连接池耗尽而假死,进程还在但不再采集数据。用healthcheck定期探测 10051 端口,配合restart策略能自动恢复。

healthcheck: test: ["CMD", "nc", "-z", "localhost", "10051"] interval: 30s timeout: 5s retries: 3 start_period: 60s

start_period给 60 秒,让 Server 有足够时间完成初始化,否则刚启动就被判定为不健康,会触发不必要的重启。nc命令在 alpine 镜像里默认有,如果用的是其他基础镜像,换成curl或wget也行。

5.3 验证监控链路是否真正打通

部署完不要只看容器状态是 Up 就以为完事了。真正的验证是:在前端创建一个测试主机,指向 Agent 容器,添加一个agent.ping监控项,看最新数据里有没有值。有值说明 Server 到 Agent 的采集链路通了。

再进一步,创建一个触发器,比如agent.ping最近 60 秒没有数据就告警,然后手动停掉 Agent 容器,看前端有没有产生告警。这一步能验证触发器计算和告警链路。我见过太多环境“看起来正常”,实际触发器根本没在工作,等真出故障时才发现监控是哑的。

最后说个我自己的习惯:每次部署完 Zabbix,我都会把docker-compose logs里所有 ERROR 和 WARN 级别的日志过一遍,哪怕服务看起来正常。有一次就是靠这个发现 Agent 的 DNS 解析偶尔超时,虽然没影响当前采集,但高峰期一定会出问题。提前修掉,比事后救火便宜得多。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询