资讯动态

Docker 部署 Zabbix 实战:从 compose 编排到避坑指南

发布时间:2026/10/15 12:49:22 来源:尧图企业网站定制
简介这份资源面向需要在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 agentZabbix 官方在 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-serverutf8mb4 - --collation-serverutf8mb4_bin - --default-authentication-pluginmysql_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-pluginmysql_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 的默认配置在小规模场景够用但有几个参数必须显式设置。字符集和排序规则前面已经提过utf8mb4utf8mb4_bin是硬性要求。连接数方面Zabbix Server 默认会开几十个到上百个连接max_connections建议不低于 200。缓冲池innodb_buffer_pool_size如果机器内存有 8G可以给到 2G 到 4G这个参数对历史数据查询速度影响最大。# 在 mysql-server 的 command 里追加 command: - --character-set-serverutf8mb4 - --collation-serverutf8mb4_bin - --default-authentication-pluginmysql_native_password - --max_connections300 - --innodb_buffer_pool_size2G - --innodb_log_file_size512Minnodb_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-stopped4. 避坑与排查五个让我加班到深夜的问题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%;如果看到的是zabbixlocalhost而不是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_PASSWORDroot_pwd_2024 MYSQL_ZABBIX_PASSWORDzabbix_pwd_2024 WEB_PORT8080 TZAsia/Shanghaicompose 里对应改成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: 60sstart_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 解析偶尔超时虽然没影响当前采集但高峰期一定会出问题。提前修掉比事后救火便宜得多。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑