
简介这份资源面向需要在Linux服务器上快速搭建监控平台的运维人员与开发者提供基于Docker部署Zabbix的完整代码包解决传统安装方式依赖多、配置繁琐的问题。压缩包共5个文件约11KB以docker-compose.yml为核心编排文件配合README.md说明文档、index.html页面及.gitignore、.inscode等辅助配置覆盖容器定义、环境变量与端口映射等关键内容结构精简便于直接复用。资源同时给出两种部署思路一是通过Compose文件一键启动Zabbix服务器、MySQL数据库与前端服务二是借助宝塔面板已有数据库创建Zabbix容器适合不同服务器管理习惯的用户。目前已有45人学习下载。读者可据此快速完成Zabbix监控系统的容器化落地掌握服务编排、数据库对接与端口配置的实践方法为后续监控CPU、内存、磁盘及网络流量等指标打下基础。1. Docker 装 Zabbix为什么这套组合成了中小团队监控的默认答案一台 2 核 4G 的云主机装完系统只剩 20G 磁盘却要同时跑监控服务端、数据库和 Web 前端。传统源码编译 Zabbix 的路子光 PHP 扩展和 MySQL 版本兼容就能耗掉一整个下午换台机器还得重来一遍。Docker 安装 Zabbix 解决的正是这个场景把 zabbix-server、zabbix-web、MySQL 和 zabbix-agent 拆成四个容器用一份 compose 文件描述依赖关系换机器时复制文件、改几个环境变量就能拉起整套监控。它适合运维人手有限、需要快速上线主机与网络监控的团队也适合想在本机复现一套 Zabbix 环境做实验的工程师。这篇笔记按「镜像怎么选、compose 怎么写、参数怎么调、坑在哪」的顺序讲读完你能拿到一套可直接改用的部署方案也能判断自己的场景该不该上容器化。2. 镜像选型与 compose 编排把四个容器拼成一套监控2.1 官方镜像的三种角色与版本对齐Zabbix 官方在 Docker Hub 上维护了zabbix/zabbix-server-mysql、zabbix/zabbix-web-nginx-mysql、zabbix/zabbix-agent三个核心镜像分别对应服务端、Web 前端和客户端。选型时最容易翻车的地方是版本号服务端和 Web 前端的镜像 tag 必须一致比如都用alpine-6.4-latest或都用ubuntu-6.0-latest混用会出现 Web 端连不上服务端、API 报版本不匹配的问题。数据库这边官方镜像支持 MySQL 8.0 和 PostgreSQL中小规模监控用 MySQL 8.0 足够注意 MySQL 8.0 默认的caching_sha2_password认证插件在部分旧客户端下会报错compose 里加--default-authentication-pluginmysql_native_password启动参数能绕开。镜像 tag 的命名规则是「基础系统-版本号-构建类型」alpine体积小但部分调试工具缺失ubuntu体积大但排错方便。生产环境我一般选alpine实验环境选ubuntu因为出问题时能直接进容器用apt装工具抓包。2.2 一份可直接改用的 docker-compose.yml下面这份 compose 文件把四个服务串起来网络用自定义 bridge数据用命名卷持久化。注意MYSQL_USER不能填rootZabbix 服务端不允许用 root 连库。version: 3.8 services: mysql-server: image: mysql:8.0 container_name: zabbix-mysql command: - --default-authentication-pluginmysql_native_password - --character-set-serverutf8mb4 - --collation-serverutf8mb4_bin environment: MYSQL_DATABASE: zabbix MYSQL_USER: zabbix MYSQL_PASSWORD: zabbix_pwd_2024 MYSQL_ROOT_PASSWORD: root_pwd_2024 volumes: - mysql-data:/var/lib/mysql networks: - zabbix-net restart: unless-stopped zabbix-server: image: zabbix/zabbix-server-mysql:alpine-6.4-latest container_name: zabbix-server environment: DB_SERVER_HOST: mysql-server MYSQL_DATABASE: zabbix MYSQL_USER: zabbix MYSQL_PASSWORD: zabbix_pwd_2024 ZBX_CACHESIZE: 64M ZBX_STARTPOLLERS: 10 ports: - 10051:10051 volumes: - server-data:/var/lib/zabbix networks: - zabbix-net depends_on: - mysql-server restart: unless-stopped zabbix-web: image: zabbix/zabbix-web-nginx-mysql:alpine-6.4-latest container_name: zabbix-web 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 ports: - 8080:8080 networks: - zabbix-net depends_on: - mysql-server - zabbix-server restart: unless-stopped zabbix-agent: image: zabbix/zabbix-agent:alpine-6.4-latest container_name: zabbix-agent environment: ZBX_HOSTNAME: docker-host-01 ZBX_SERVER_HOST: zabbix-server ZBX_SERVER_PORT: 10051 ports: - 10050:10050 networks: - zabbix-net restart: unless-stopped volumes: mysql-data: server-data: networks: zabbix-net: driver: bridge这份文件里几个关键点depends_on只保证启动顺序不保证 MySQL 已经初始化完成所以第一次docker compose up -d后 Zabbix 服务端可能因为连不上库而重启几次等 MySQL 初始化完它会自己恢复。ZBX_CACHESIZE默认 8M监控 50 台以上主机建议调到 64M 或 128M否则会出现「历史数据写入延迟」的告警。PHP_TZ必须设成Asia/Shanghai不然 Web 界面时间比实际时间差 8 小时看图表时容易误判。2.3 启动顺序与初始化验证启动命令很简单但验证步骤不能省# 后台启动全部服务 docker compose up -d # 查看容器状态确认四个都是 Up docker compose ps # 跟踪 zabbix-server 日志看到 server #0 started 才算就绪 docker compose logs -f zabbix-server # 检查 MySQL 里 zabbix 库的表数量正常在 170 张左右 docker exec -it zabbix-mysql mysql -uzabbix -pzabbix_pwd_2024 \ -e SELECT COUNT(*) FROM information_schema.tables WHERE table_schemazabbix;如果docker compose ps里 zabbix-server 反复重启先看日志里是不是Access denied for user zabbix那说明 MySQL 还没初始化完或者密码对不上。表数量少于 100 说明初始化脚本没跑完等两分钟再查。Web 端访问http://主机IP:8080默认账号Admin密码zabbix登录后第一件事是改密码第二件事是去「管理 → 一般 → 自动注册」里关掉自动注册避免陌生 agent 自己连上来。3. 参数调优与监控接入让容器里的 Zabbix 真正干活3.1 服务端关键参数怎么改Zabbix 服务端的性能瓶颈通常不在 CPU而在数据库写入和缓存。容器化部署时参数通过环境变量注入改完docker compose up -d重建容器即可。下面几个参数是实际调优时最常动的环境变量默认值建议值作用ZBX_CACHESIZE8M64M256M配置缓存主机多时必调ZBX_STARTPOLLERS51020轮询进程数影响采集并发ZBX_STARTPOLLERSUNREACHABLE125不可达主机轮询进程ZBX_STARTTRAPPERS1510接收 agent 主动上报的进程数ZBX_STARTDISCOVERERS125自动发现进程数ZBX_HOUSEKEEPINGFREQUENCY11清理频率单位小时调ZBX_STARTPOLLERS时注意别超过 CPU 核数的 4 倍否则进程切换开销反而拖慢采集。ZBX_CACHESIZE的估算方法是「主机数 × 每主机监控项数 × 2KB」100 台主机、每台 50 个监控项大约需要 10M留一倍余量设 64M 比较稳。3.2 用 API 批量接入主机而不是手点Web 界面一台台加主机加到第 20 台就会开始怀疑人生。Zabbix 提供了完整的 API用 Python 脚本批量创建主机、绑定模板、加监控项效率高得多。下面这段脚本演示用 API 创建一台主机并关联 Linux by Zabbix agent 模板import requests import json ZABBIX_URL http://127.0.0.1:8080/api_jsonrpc.php HEADERS {Content-Type: application/json-rpc} # 第一步登录拿 token def login(user, password): payload { jsonrpc: 2.0, method: user.login, params: {username: user, password: password}, id: 1 } resp requests.post(ZABBIX_URL, headersHEADERS, datajson.dumps(payload)) return resp.json()[result] # 第二步创建主机interfaces 里填 agent 的 IP 和端口 def create_host(token, hostname, ip, template_id, group_id): payload { jsonrpc: 2.0, method: host.create, params: { host: hostname, interfaces: [{ type: 1, # 1 表示 Zabbix agent main: 1, useip: 1, ip: ip, dns: , port: 10050 }], groups: [{groupid: group_id}], templates: [{templateid: template_id}] }, auth: token, id: 2 } resp requests.post(ZABBIX_URL, headersHEADERS, datajson.dumps(payload)) return resp.json() if __name__ __main__: token login(Admin, zabbix) # 模板 ID 和主机组 ID 需要先在 Web 界面查或用 hostgroup.get / template.get 接口拿 result create_host(token, web-server-01, 192.168.1.100, 10001, 2) print(json.dumps(result, indent2, ensure_asciiFalse))脚本里type: 1对应 Zabbix agent 接口如果监控的是 SNMP 设备改成type: 2端口改成 161。templateid和groupid不要硬编码先用template.get和hostgroup.get接口查出来再传否则换一套 Zabbix 环境脚本就废了。批量场景下把主机列表写成 CSV循环调用create_host每台之间 sleep 0.2 秒避免 API 限流。3.3 容器内 agent 监控宿主机的正确姿势zabbix-agent 跑在容器里默认只能看到容器自己的资源看不到宿主机。要监控宿主机需要把宿主机的/proc、/sys、/etc挂进容器并且用ZBX_HOSTNAME区分。compose 里 agent 服务改成zabbix-agent: image: zabbix/zabbix-agent:alpine-6.4-latest container_name: zabbix-agent environment: ZBX_HOSTNAME: host-node-01 ZBX_SERVER_HOST: zabbix-server ZBX_SERVER_PORT: 10051 ZBX_ACTIVE_ALLOW: true volumes: - /proc:/host/proc:ro - /sys:/host/sys:ro - /etc:/host/etc:ro pid: host privileged: true networks: - zabbix-net restart: unless-stoppedpid: host让容器共享宿主机 PID 命名空间agent 才能读到宿主机所有进程。privileged: true是为了让 agent 能读一些需要权限的指标如果安全要求高可以去掉改用cap_add单独加SYS_ADMIN。挂载/proc后agent 内置的system.cpu.util等键值默认还是读容器自己的需要在模板里把键值改成system.cpu.util[/host/proc/stat]这种带路径的形式或者用 UserParameter 自定义。这一步是容器化 Zabbix 监控宿主机时最容易漏的漏了就会出现「CPU 使用率永远是 0.1%」的假数据。4. 避坑与排查容器化 Zabbix 最常见的五类翻车4.1 Web 界面报「Zabbix server is not running」现象是登录后首页顶部红色横幅提示服务端未运行但docker compose ps里 zabbix-server 明明是 Up。原因通常是 Web 容器里的ZBX_SERVER_HOST填的是localhost或127.0.0.1而 Web 和服务端是两个容器localhost 指向的是 Web 容器自己。解决方法是把ZBX_SERVER_HOST改成服务端的容器名zabbix-server并且确认两个容器在同一个自定义网络里用docker exec zabbix-web ping zabbix-server能通。4.2 MySQL 容器启动后 Zabbix 服务端反复重启现象是docker compose logs zabbix-server里刷Connection refused或Access denied。原因是 MySQL 8.0 首次启动要初始化数据目录耗时可能 30 秒以上而depends_on不等健康检查。解决办法是在 compose 里给 MySQL 加healthcheck服务端用depends_on的condition: service_healthy等它真正就绪mysql-server: # ... 其他配置不变 healthcheck: test: [CMD, mysqladmin, ping, -h, localhost, -uroot, -proot_pwd_2024] interval: 10s timeout: 5s retries: 10 start_period: 30s zabbix-server: # ... 其他配置不变 depends_on: mysql-server: condition: service_healthy4.3 监控项采集不到数据日志报「ZBX_NOTSUPPORTED」现象是主机绿了但监控项全是红色agent 日志里ZBX_NOTSUPPORTED: Unsupported item key。原因是模板里的键值和 agent 实际支持的键值不匹配常见于 agent 版本和服务端版本不一致或者容器内 agent 缺少某些插件。解决方法是先docker exec zabbix-agent zabbix_agentd -p | grep 键值名看 agent 支不支持这个键不支持就换模板或升级 agent 镜像 tag 到和服务端一致。4.4 历史数据暴涨把磁盘写满现象是运行一两周后宿主机磁盘告警du -sh /var/lib/docker/volumes/发现 mysql-data 卷几十个 G。原因是 Zabbix 默认保留历史数据 90 天、趋势数据 365 天监控项多的时候每天写入量很大。解决办法是在 Web 界面「管理 → 一般 → 管家」里把历史数据保留天数改成 30 天、趋势数据改成 180 天同时确认ZBX_HOUSEKEEPINGFREQUENCY是 1 小时。另外 MySQL 的innodb_buffer_pool_size在容器里默认只有 128M数据量大时建议通过command加到 1G 以上。4.5 容器时区不对导致图表时间错乱现象是 Web 界面显示的时间和宿主机差 8 小时告警触发时间对不上日志。原因是容器默认 UTC 时区而 Zabbix 的PHP_TZ和 MySQL 的time_zone没设。解决办法是 Web 容器加PHP_TZ: Asia/ShanghaiMySQL 容器加TZ: Asia/Shanghai环境变量服务端容器也加TZ。三个都设完再重建容器图表时间才会和本地一致。5. 进阶用 compose 做多环境隔离与升级回滚一套 compose 文件跑生产另一套跑测试最容易出的问题是端口冲突和数据串库。我的习惯是用.env文件把端口、密码、镜像 tag 抽出来生产用docker compose -f docker-compose.yml --env-file .env.prod up -d测试用.env.test两套环境的容器名和卷名都带环境前缀互不干扰。升级 Zabbix 版本时先把 MySQL 数据卷用docker run --rm -v zabbix_mysql-data:/data -v $(pwd):/backup alpine tar czf /backup/mysql-$(date %F).tar.gz -C /data .备份出来再改镜像 tag 重建。Zabbix 大版本升级比如 6.0 到 6.4需要先停服务端让数据库 schema 升级完再启 Web顺序反了会出现 Web 端报数据库版本不匹配。回滚就是把镜像 tag 改回去、数据卷解压覆盖五分钟内能恢复。这套流程我用了两年唯一一次翻车是忘了备份就直接改 tag结果 schema 升级到一半失败只能从更早的备份恢复丢了一天的历史数据。从那以后我养成了改任何 tag 之前先跑备份脚本的习惯希望帮到你。本文还有配套的精品资源点击获取