diff --git a/apps/zabbix-xinchuang-edition/7.0.27/data.yml b/apps/zabbix-xinchuang-edition/7.0.27/data.yml new file mode 100644 index 000000000000..a23219f894d8 --- /dev/null +++ b/apps/zabbix-xinchuang-edition/7.0.27/data.yml @@ -0,0 +1,394 @@ +additionalProperties: + formFields: + # 数据库服务(通过 1Panel 一键安装 MySQL,选填) + - child: + default: "" + envKey: ZABBIX_DB_HOST + required: true + type: service + default: mysql + labelEn: Database Service + labelZh: 数据库服务(选填,1Panel 安装) + label: + en: Database Service (optional, 1Panel install) + es-es: Servicio de base de datos (opcional, instalación 1Panel) + ja: データベースサービス(オプション、1Panel インストール) + ko: 데이터베이스 서비스 (선택 사항, 1Panel 설치) + ms: Perkhidmatan Pangkalan Data (pilihan, pemasangan 1Panel) + pt-br: Serviço de Banco de Dados (opcional, instalação 1Panel) + ru: Сервис баз данных (опционально, установка 1Panel) + tr: Veritabanı Hizmeti (isteğe bağlı, 1Panel kurulumu) + zh: 数据库服务(选填,1Panel 安装) + zh-Hant: 資料庫服務(選填,1Panel 安裝) + required: false + type: apps + values: + - label: MySQL + value: mysql + # Root 密码(1Panel 自动安装 MySQL 时使用,选填) + - default: "" + envKey: PANEL_DB_ROOT_PASSWORD + labelEn: Root Password + labelZh: Root 密码(选填,1Panel 安装用) + label: + en: Root Password (optional, for 1Panel install) + es-es: Contraseña de root (opcional) + ja: ルートパスワード(オプション) + ko: 루트 비밀번호 (선택 사항) + ms: Kata Laluan Root (pilihan) + pt-br: Senha Root (opcional) + ru: Пароль root (опционально) + tr: Root Parolası (isteğe bağlı) + zh: Root 密码(选填,1Panel 安装用) + zh-Hant: Root 密碼(選填) + required: false + type: password + # 数据库地址 + - default: "" + edit: true + envKey: ZABBIX_DB_HOST + label: + en: Database Host + es-es: Host de la base de datos + ja: データベースホスト + ms: Hos Pangkalan Data + pt-br: Host do Banco de Dados + ru: Хост базы данных + ko: 데이터베이스 호스트 + tr: Veritabanı Ana Bilgisi + zh: 数据库地址 + zh-Hant: 資料庫主機 + required: true + type: text + # 数据库端口 + - default: 3306 + edit: true + envKey: ZABBIX_DB_PORT + label: + en: Database Port + es-es: Puerto de la base de datos + ja: データベースポート + ms: Port Pangkalan Data + pt-br: Porta do Banco de Dados + ru: Порт базы данных + ko: 데이터베이스 포트 + tr: Veritabanı Bağlantı Noktası + zh: 数据库端口 + zh-Hant: 資料庫埠 + required: true + rule: paramPort + type: number + # 数据库名 + - default: zabbix + envKey: ZABBIX_DB_NAME + label: + en: Database Name + es-es: Nombre de la base de datos + ja: データベース名 + ms: Nama Pangkalan Data + pt-br: Nome do Banco de Dados + ru: Имя базы данных + ko: 데이터베이스 이름 + tr: Veritabanı Adı + zh: 数据库名 + zh-Hant: 資料庫名稱 + random: true + required: true + rule: paramCommon + type: text + # 数据库用户 + - default: zabbix + envKey: ZABBIX_DB_USER + label: + en: Database User + es-es: Usuario de base de datos + ja: データベースユーザー + ms: Pengguna Pangkalan Data + pt-br: Usuário do Banco de Dados + ru: Пользователь базы данных + ko: 데이터베이스 사용자 + tr: Veritabanı Kullanıcısı + zh: 数据库用户 + zh-Hant: 資料庫使用者 + random: true + required: true + rule: paramCommon + type: text + # 数据库密码 + - default: "" + envKey: ZABBIX_DB_PASSWORD + label: + en: Database Password + es-es: Contraseña de la base de datos + ja: データベースパスワード + ms: Kata Laluan Pangkalan Data + pt-br: Senha do Banco de Dados + ru: Пароль базы данных + ko: 데이터베이스 비밀번호 + tr: Veritabanı Parolası + zh: 数据库密码 + zh-Hant: 資料庫密碼 + random: true + required: true + type: password + # 服务器名称 + - default: Zabbix + edit: true + envKey: ZABBIX_SERVER_NAME + label: + en: Server Name + es-es: Nombre del servidor + ja: サーバー名 + ms: Nama Pelayan + pt-br: Nome do Servidor + ru: Имя сервера + ko: 서버 이름 + tr: Sunucu Adı + zh: 服务器名称 + zh-Hant: 伺服器名稱 + required: true + type: text + # Web 界面端口(使用 PANEL_APP_PORT_HTTP 前缀,1Panel 自动校验端口占用) + - default: 8080 + edit: true + envKey: PANEL_APP_PORT_HTTP + label: + en: Web UI Port + es-es: Puerto de la interfaz web + ja: Web UI ポート + ms: Port UI Web + pt-br: Porta da UI Web + ru: Порт веб-интерфейса + ko: 웹 UI 포트 + tr: Web UI Bağlantı Noktası + zh: Web 界面端口 + zh-Hant: Web 介面埠 + required: true + rule: paramPort + type: number + # Agent 端口 + - default: 10051 + edit: true + envKey: ZABBIX_SERVER_PORT + label: + en: Server Port + es-es: Puerto del servidor (para Agent/Proxy) + ja: サーバーポート + ms: Port Pelayan + pt-br: Porta do Servidor + ru: Порт сервера + ko: 서버 포트 + tr: Sunucu Bağlantı Noktası (Agent/Proxy için) + zh: Server 端口(Agent/Proxy 连接用) + zh-Hant: Server 埠 + required: true + rule: paramPort + type: number + # 时区 + - default: Asia/Shanghai + edit: true + envKey: PHP_TZ + label: + en: Timezone + es-es: Zona horaria + ja: タイムゾーン + ms: Zon Waktu + pt-br: Fuso Horário + ru: Часовой пояс + ko: 시간대 + tr: Saat Dilimi + zh: 时区 + zh-Hant: 時區 + required: true + type: text + # ========== Zabbix Agent(可选) ========== + - default: "true" + envKey: ZABBIX_AGENT_ENABLED + label: + zh: 启用 Zabbix Agent + zh-Hant: 啟用 Zabbix Agent + en: Enable Zabbix Agent + es-es: Habilitar Zabbix Agent + ja: Zabbix Agent を有効にする + ms: Dayakan Zabbix Agent + pt-br: Ativar Zabbix Agent + ru: Включить Zabbix Agent + ko: Zabbix Agent 활성화 + tr: Zabbix Agent'i Etkinleştir + required: true + type: select + values: + - label: "关闭" + value: "false" + - label: "开启" + value: "true" + - default: "" + edit: true + envKey: ZABBIX_AGENT_EXTERNAL_SERVERS + label: + zh: 外部 Server 地址(逗号分隔,选填) + zh-Hant: 外部 Server 地址(逗號分隔,選填) + en: External Servers (comma separated, optional) + es-es: Servidores externos (separados por comas, opcional) + ja: 外部サーバーのアドレス(カンマ区切り、任意) + ms: Pelayan luaran (dipisahkan dengan koma, pilihan) + pt-br: Servidores externos (separados por vírgulas, opcional) + ru: Внешние серверы (через запятую, необязательно) + ko: 외부 서버 주소(쉼표로 구분, 선택 사항) + tr: Harici Sunucular (virgülle ayrılmış, isteğe bağlı) + required: false + type: text + - default: 10050 + edit: true + envKey: ZABBIX_AGENT_PORT + label: + zh: Agent 端口(启用后生效) + zh-Hant: Agent 端口(啟用後生效) + en: Agent Port (when enabled) + es-es: Puerto de Agent (cuando esté habilitado) + ja: Agent ポート(有効時) + ms: Port Agent (apabila diaktifkan) + pt-br: Porta do Agent (quando habilitado) + ru: Порт агента (при включении) + ko: Agent 포트(활성화 시) + tr: Agent Bağlantı Noktası (etkinleştirildiğinde) + required: true + rule: paramPort + type: number + # ========== Zabbix Proxy(可选) ========== + - default: "false" + envKey: ZABBIX_PROXY_ENABLED + label: + zh: 启用 Zabbix Proxy + zh-Hant: 啟用 Zabbix Proxy + en: Enable Zabbix Proxy + es-es: Habilitar Zabbix Proxy + ja: Zabbix Proxy を有効にする + ms: Dayakan Zabbix Proxy + pt-br: Ativar Zabbix Proxy + ru: Включить Zabbix Proxy + ko: Zabbix Proxy 활성화 + tr: Zabbix Proxy'yi Etkinleştir + required: true + type: select + values: + - label: "关闭" + value: "false" + - label: "开启" + value: "true" + - default: "0" + envKey: ZABBIX_PROXY_MODE + label: + zh: Proxy 模式 + zh-Hant: Proxy 模式 + en: Proxy Mode + es-es: Modo Proxy + ja: Proxy モード + ms: Mod Proksi + pt-br: Modo Proxy + ru: Режим Proxy + ko: Proxy 모드 + tr: Proxy Modu + required: true + type: select + values: + - label: Active(主动推送) + value: "0" + - label: Passive(被动等待) + value: "1" + - default: 10071 + edit: true + envKey: ZABBIX_PROXY_PORT + label: + zh: Proxy 端口(Passive 模式需要) + zh-Hant: Proxy 端口(Passive 模式需要) + en: Proxy Port (for passive mode) + es-es: Puerto Proxy (para modo pasivo) + ja: Proxy ポート(パッシブモード用) + ms: Port Proksi (untuk mod pasif) + pt-br: Porta Proxy (para modo passivo) + ru: Порт Proxy (для пассивного режима) + ko: Proxy 포트(패시브 모드용) + tr: Proxy Bağlantı Noktası (pasif mod için) + required: true + rule: paramPort + type: number + - default: "" + edit: true + envKey: ZABBIX_PROXY_DB_HOST + label: + zh: Proxy 数据库地址 + zh-Hant: Proxy 資料庫地址 + en: Proxy DB Host + es-es: Host DB Proxy + ja: Proxy DB ホスト + ms: Hos DB Proxy + pt-br: Host DB Proxy + ru: Хост БД Proxy + ko: Proxy DB 호스트 + tr: Proxy DB Ana Bilgisi + required: false + type: text + - default: 3306 + edit: true + envKey: ZABBIX_PROXY_DB_PORT + label: + zh: Proxy 数据库端口 + zh-Hant: Proxy 資料庫埠 + en: Proxy DB Port + es-es: Puerto DB Proxy + ja: Proxy DB ポート + ms: Port DB Proxy + pt-br: Porta DB Proxy + ru: Порт БД Proxy + ko: Proxy DB 포트 + tr: Proxy DB Bağlantı Noktası + required: false + rule: paramPort + type: number + - default: zabbix_proxy + envKey: ZABBIX_PROXY_DB_NAME + label: + zh: Proxy 数据库名 + zh-Hant: Proxy 資料庫名 + en: Proxy DB Name + es-es: Nombre DB Proxy + ja: Proxy DB 名 + ms: Nama DB Proxy + pt-br: Nome DB Proxy + ru: Имя БД Proxy + ko: Proxy DB 이름 + tr: Proxy DB Adı + required: false + type: text + - default: zabbix + envKey: ZABBIX_PROXY_DB_USER + label: + zh: Proxy 数据库用户 + zh-Hant: Proxy 資料庫使用者 + en: Proxy DB User + es-es: Usuario DB Proxy + ja: Proxy DB ユーザー + ms: Pengguna DB Proxy + pt-br: Usuário DB Proxy + ru: Пользователь БД Proxy + ko: Proxy DB 사용자 + tr: Proxy DB Kullanıcısı + required: false + type: text + - default: "" + envKey: ZABBIX_PROXY_DB_PASSWORD + label: + zh: Proxy 数据库密码 + zh-Hant: Proxy 資料庫密碼 + en: Proxy DB Password + es-es: Contraseña DB Proxy + ja: Proxy DB パスワード + ms: Kata Laluan DB Proxy + pt-br: Senha DB Proxy + ru: Пароль БД Proxy + ko: Proxy DB 비밀번호 + tr: Proxy DB Parolası + required: false + type: password + diff --git a/apps/zabbix-xinchuang-edition/7.0.27/docker-compose.yml b/apps/zabbix-xinchuang-edition/7.0.27/docker-compose.yml new file mode 100644 index 000000000000..72cdb977a140 --- /dev/null +++ b/apps/zabbix-xinchuang-edition/7.0.27/docker-compose.yml @@ -0,0 +1,297 @@ +# ============================================================================= +# Zabbix 7.0 信创版 +# ============================================================================= +# 镜像说明: +# - zabbix-server-mysql: Zabbix Server(镜像名含 mysql 表示编译了 MySQL 客户端) +# - zabbix-web-nginx-mysql: Zabbix Web 前端(Nginx + PHP + MySQL 客户端) +# - zabbix-agent: Zabbix Agent 守护进程 +# - zabbix-proxy-mysql: Zabbix Proxy(含 MySQL 客户端) +# 注意:本 compose 不包含数据库服务,需自行准备外部数据库 +# ============================================================================= + +services: + # --------------------------------------------------------------------------- + # HA 节点清理(每次部署执行,清理残留避免 Server 重启循环) + # --------------------------------------------------------------------------- + zabbix-ha-cleanup: + image: zabbix/zabbix-server-mysql:ubuntu-7.0.27 + pull_policy: missing + container_name: ${CONTAINER_NAME}-ha-cleanup + restart: "no" + entrypoint: ["/bin/bash", "-c"] + command: + - | + mysql -h"${ZABBIX_DB_HOST}" -P"${ZABBIX_DB_PORT:-3306}" \ + -u"${ZABBIX_DB_USER}" -p"$ZABBIX_DB_PASSWORD" \ + -e "DELETE FROM ha_node;" "${ZABBIX_DB_NAME}" 2>/dev/null && \ + echo "[HA Cleanup] ✓ ha_node 已清理" || \ + echo "[HA Cleanup] 跳过(首次安装无此表)" + exec tail -f /dev/null + environment: + DB_SERVER_HOST: ${ZABBIX_DB_HOST} + DB_SERVER_PORT: ${ZABBIX_DB_PORT:-3306} + MYSQL_DATABASE: ${ZABBIX_DB_NAME} + MYSQL_USER: ${ZABBIX_DB_USER} + MYSQL_PASSWORD: ${ZABBIX_DB_PASSWORD} + networks: + - 1panel-network + + # --------------------------------------------------------------------------- + # 数据库初始化(仅首次运行,创建 Zabbix 表结构后自动退出) + # --------------------------------------------------------------------------- + zabbix-db-init: + image: zabbix/zabbix-server-mysql:ubuntu-7.0.27 + pull_policy: missing + container_name: ${CONTAINER_NAME}-db-init + restart: unless-stopped + entrypoint: ["/bin/bash", "-c"] + command: + - | + echo "[DB Init] 开始初始化 Zabbix 数据库..." + /usr/bin/docker-entrypoint.sh init_db_only + EXIT_CODE=$? + if [ $$EXIT_CODE -eq 0 ]; then + echo "[DB Init] ✓ 数据库初始化成功" + else + echo "[DB Init] ⚠ 退出码: $$EXIT_CODE(可能已初始化)" + fi + echo "[DB Init] 容器保持运行" + exec tail -f /dev/null + environment: + DB_SERVER_HOST: ${ZABBIX_DB_HOST} + DB_SERVER_PORT: ${ZABBIX_DB_PORT:-3306} + MYSQL_DATABASE: ${ZABBIX_DB_NAME} + MYSQL_USER: ${ZABBIX_DB_USER} + MYSQL_PASSWORD: ${ZABBIX_DB_PASSWORD} + volumes: + - /etc/localtime:/etc/localtime:ro + networks: + - 1panel-network + + # --------------------------------------------------------------------------- + # Zabbix Server 核心服务 + # --------------------------------------------------------------------------- + zabbix-server: + image: zabbix/zabbix-server-mysql:ubuntu-7.0.27 + pull_policy: missing + container_name: ${CONTAINER_NAME} + restart: unless-stopped + entrypoint: ["/bin/bash", "-c"] + command: + - mysql -h${ZABBIX_DB_HOST} -P${ZABBIX_DB_PORT:-3306} -u${ZABBIX_DB_USER} -p"${ZABBIX_DB_PASSWORD}" -e "DELETE FROM ha_node; UPDATE interface SET ip='${CONTAINER_NAME}-agent',dns='${CONTAINER_NAME}-agent',useip=0 WHERE hostid=(SELECT hostid FROM hosts WHERE host='Zabbix server') AND type=1;" ${ZABBIX_DB_NAME} 2>/dev/null; exec /usr/bin/docker-entrypoint.sh /usr/sbin/zabbix_server --foreground -c /etc/zabbix/zabbix_server.conf + ports: + - ${ZABBIX_SERVER_PORT:-10051}:10051 + environment: + DB_SERVER_HOST: ${ZABBIX_DB_HOST} + DB_SERVER_PORT: ${ZABBIX_DB_PORT:-3306} + MYSQL_DATABASE: ${ZABBIX_DB_NAME} + MYSQL_USER: ${ZABBIX_DB_USER} + MYSQL_PASSWORD: ${ZABBIX_DB_PASSWORD} + ZBX_ALLOWUNSUPPORTEDDBVERSIONS: "1" + volumes: + - /etc/localtime:/etc/localtime:ro + - ./data/server/alertscripts:/usr/lib/zabbix/alertscripts:ro + - ./data/server/externalscripts:/usr/lib/zabbix/externalscripts:ro + - ./data/server/export:/var/lib/zabbix/export:rw + # Server 模块、SSH 密钥、SSL 证书 + - ./data/server/modules:/var/lib/zabbix/modules:ro + - ./data/server/ssh_keys:/var/lib/zabbix/ssh_keys:ro + - ./data/server/ssl/certs:/var/lib/zabbix/ssl/certs:ro + - ./data/server/ssl/keys:/var/lib/zabbix/ssl/keys:ro + tmpfs: /tmp + ulimits: + nproc: 65535 + nofile: + soft: 20000 + hard: 40000 + networks: + - 1panel-network + stop_grace_period: 30s + + # --------------------------------------------------------------------------- + # Zabbix Web 前端(Nginx + PHP),启动自动加载 plugin_loader.so + # --------------------------------------------------------------------------- + zabbix-web: + image: zabbix/zabbix-web-nginx-mysql:ubuntu-7.0.27 + pull_policy: missing + user: "0" + container_name: ${CONTAINER_NAME}-web + restart: unless-stopped + entrypoint: ["/bin/bash", "/opt/zabbix/install-plugins-entrypoint.sh"] + ports: + - ${PANEL_APP_PORT_HTTP}:8080 + environment: + DB_SERVER_HOST: ${ZABBIX_DB_HOST} + DB_SERVER_PORT: ${ZABBIX_DB_PORT:-3306} + MYSQL_DATABASE: ${ZABBIX_DB_NAME} + MYSQL_USER: ${ZABBIX_DB_USER} + MYSQL_PASSWORD: ${ZABBIX_DB_PASSWORD} + ZBX_SERVER_HOST: ${CONTAINER_NAME} + ZBX_SERVER_NAME: ${ZABBIX_SERVER_NAME:-Zabbix} + PHP_TZ: ${PHP_TZ:-Asia/Shanghai} + ZABBIX_PLUGINS_AUTO_INSTALL: "true" + ZABBIX_PLUGIN_LOADER_AUTO_INSTALL: "true" + ZABBIX_PLUGIN_LOADER_DIR: /var/lib/zabbix/plugin_loader + ZABBIX_MODULES_INSTALL_DIR: /usr/share/zabbix/modules + volumes: + - /etc/localtime:/etc/localtime:ro + - ./data/web/ssl:/etc/ssl/nginx:ro + - ./data/modules:/usr/share/zabbix/modules:rw + - ./data/plugins:/var/lib/zabbix/plugins:rw + - ./data/plugin_loader:/var/lib/zabbix/plugin_loader:ro + - ./scripts/install-plugins-entrypoint.sh:/opt/zabbix/install-plugins-entrypoint.sh:ro + tmpfs: + - /tmp + - /var/lib/php/session:mode=770,uid=1997,gid=1995 + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/ping"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 40s + networks: + - 1panel-network + stop_grace_period: 10s + + # --------------------------------------------------------------------------- + # Zabbix Agent(可选,通过表单开关控制) + # - 关闭时容器空转,开启后监控宿主机 + # - privileged + pid:host 用于获取宿主机进程信息 + # --------------------------------------------------------------------------- + zabbix-agent: + image: zabbix/zabbix-agent:ubuntu-7.0.27 + pull_policy: missing + container_name: ${CONTAINER_NAME}-agent + restart: unless-stopped + privileged: true + pid: "host" + entrypoint: ["/bin/bash", "-c"] + command: + - | + if [ "$${ZABBIX_AGENT_ENABLED}" = "true" ]; then + echo "[Zabbix Agent] 启动中,连接 Server: ${CONTAINER_NAME}" + /usr/bin/docker-entrypoint.sh /bin/true + sed -i 's|^Server=.*|Server=0.0.0.0/0|' /etc/zabbix/zabbix_agentd.conf + ACTIVE="${CONTAINER_NAME}" + [ -n "$${ZABBIX_AGENT_EXTERNAL_SERVERS:-}" ] && ACTIVE="$$ACTIVE,$${ZABBIX_AGENT_EXTERNAL_SERVERS}" + sed -i "s|^ServerActive=.*|ServerActive=$$ACTIVE|" /etc/zabbix/zabbix_agentd.conf + exec /usr/sbin/zabbix_agentd --foreground -c /etc/zabbix/zabbix_agentd.conf + else + echo "[Zabbix Agent] 已关闭" + exec tail -f /dev/null + fi + ports: + - ${ZABBIX_AGENT_PORT:-10050}:10050 + environment: + ZBX_SERVER_HOST: ${CONTAINER_NAME} + ZBX_SERVER_PORT: ${ZABBIX_SERVER_PORT:-10051} + ZBX_PASSIVE_ALLOW: "true" + ZBX_ACTIVE_ALLOW: "true" + ZBX_HOSTNAMEITEM: system.hostname + ZBX_HOSTNAME: Zabbix server + ZABBIX_AGENT_ENABLED: ${ZABBIX_AGENT_ENABLED:-false} + ZABBIX_AGENT_EXTERNAL_SERVERS: ${ZABBIX_AGENT_EXTERNAL_SERVERS:-} + volumes: + - /etc/localtime:/etc/localtime:ro + - ./data/agent/zabbix_agentd.d:/etc/zabbix/zabbix_agentd.d:ro + - ./data/agent/user_scripts:/var/lib/zabbix/user_scripts:ro + networks: + - 1panel-network + stop_grace_period: 5s + + # --------------------------------------------------------------------------- + # Zabbix Proxy 数据库初始化(仅首次,建表后退出) + # --------------------------------------------------------------------------- + zabbix-proxy-db-init: + image: zabbix/zabbix-proxy-mysql:ubuntu-7.0.27 + pull_policy: missing + container_name: ${CONTAINER_NAME}-proxy-db-init + restart: unless-stopped + entrypoint: ["/bin/bash", "-c"] + command: + - | + echo "[Proxy DB Init] 开始初始化 Proxy 数据库..." + /usr/bin/docker-entrypoint.sh init_db_only + EXIT_CODE=$? + if [ $$EXIT_CODE -eq 0 ]; then + echo "[Proxy DB Init] ✓ 初始化成功" + else + echo "[Proxy DB Init] ⚠ 退出码: $$EXIT_CODE" + fi + echo "[Proxy DB Init] 容器保持运行" + exec tail -f /dev/null + environment: + DB_SERVER_HOST: ${ZABBIX_PROXY_DB_HOST} + DB_SERVER_PORT: ${ZABBIX_PROXY_DB_PORT:-3306} + MYSQL_DATABASE: ${ZABBIX_PROXY_DB_NAME:-zabbix_proxy} + MYSQL_USER: ${ZABBIX_PROXY_DB_USER:-zabbix} + MYSQL_PASSWORD: ${ZABBIX_PROXY_DB_PASSWORD} + volumes: + - /etc/localtime:/etc/localtime:ro + networks: + - 1panel-network + + # --------------------------------------------------------------------------- + # Zabbix Proxy(可选,通过表单开关控制) + # - 关闭时容器空转,开启后需要独立数据库 + # - 需要独立数据库,不可与 Server 共用 + # --------------------------------------------------------------------------- + zabbix-proxy: + image: zabbix/zabbix-proxy-mysql:ubuntu-7.0.27 + pull_policy: missing + container_name: ${CONTAINER_NAME}-proxy + restart: unless-stopped + entrypoint: ["/bin/bash", "-c"] + command: + - | + if [ "$(printenv ZABBIX_PROXY_ENABLED 2>/dev/null || echo false)" = "true" ]; then + exec /usr/bin/docker-entrypoint.sh /usr/sbin/zabbix_proxy --foreground -c /etc/zabbix/zabbix_proxy.conf + else + echo "[Zabbix Proxy] 已关闭" + exec tail -f /dev/null + fi + ports: + - ${ZABBIX_PROXY_PORT:-10071}:10051 + environment: + DB_SERVER_HOST: ${ZABBIX_PROXY_DB_HOST} + DB_SERVER_PORT: ${ZABBIX_PROXY_DB_PORT:-3306} + MYSQL_DATABASE: ${ZABBIX_PROXY_DB_NAME:-zabbix_proxy} + MYSQL_USER: ${ZABBIX_PROXY_DB_USER:-zabbix} + MYSQL_PASSWORD: ${ZABBIX_PROXY_DB_PASSWORD} + ZBX_SERVER_HOST: ${ZBX_SERVER_HOST} + ZBX_HOSTNAME: ${ZBX_HOSTNAME} + ZBX_PROXYMODE: ${ZABBIX_PROXY_MODE:-0} + ZBX_SERVER_PORT: ${ZABBIX_SERVER_PORT:-10051} + ZBX_CONFIGFREQUENCY: ${ZBX_CONFIGFREQUENCY:-3600} + ZBX_DATASENDERFREQUENCY: ${ZBX_DATASENDERFREQUENCY:-1} + ZBX_STARTPOLLERS: ${ZBX_STARTPOLLERS:-5} + ZBX_STARTTRAPPERS: ${ZBX_STARTTRAPPERS:-5} + ZBX_STARTPINGERS: ${ZBX_STARTPINGERS:-1} + ZBX_STARTDISCOVERERS: ${ZBX_STARTDISCOVERERS:-1} + ZBX_STARTHTTPPOLLERS: ${ZBX_STARTHTTPPOLLERS:-1} + ZBX_CACHESIZE: ${ZBX_CACHESIZE:-8M} + ZBX_TIMEOUT: ${ZBX_TIMEOUT:-4} + ZBX_PROXYLOCALBUFFER: ${ZBX_PROXYLOCALBUFFER:-0} + ZBX_PROXYOFFLINEBUFFER: ${ZBX_PROXYOFFLINEBUFFER:-1} + ZBX_PROXYHEARTBEATFREQUENCY: ${ZBX_PROXYHEARTBEATFREQUENCY:-60} + ZABBIX_PROXY_ENABLED: ${ZABBIX_PROXY_ENABLED:-false} + volumes: + - /etc/localtime:/etc/localtime:ro + - ./data/proxy/externalscripts:/usr/lib/zabbix/externalscripts:ro + - ./data/proxy/modules:/var/lib/zabbix/modules:ro + - ./data/proxy/ssh_keys:/var/lib/zabbix/ssh_keys:ro + - ./data/proxy/ssl/certs:/var/lib/zabbix/ssl/certs:ro + - ./data/proxy/ssl/keys:/var/lib/zabbix/ssl/keys:ro + tmpfs: /tmp + ulimits: + nproc: 65535 + nofile: + soft: 20000 + hard: 40000 + networks: + - 1panel-network + stop_grace_period: 10s + +networks: + 1panel-network: + external: true diff --git a/apps/zabbix-xinchuang-edition/7.0.27/scripts/init.sh b/apps/zabbix-xinchuang-edition/7.0.27/scripts/init.sh new file mode 100755 index 000000000000..4af5ad85774a --- /dev/null +++ b/apps/zabbix-xinchuang-edition/7.0.27/scripts/init.sh @@ -0,0 +1,103 @@ +#!/bin/bash +# ============================================================================= +# Zabbix 7.0 信创版 - 安装初始化脚本 +# 此脚本在 docker-compose up 之前执行 +# ============================================================================= + +set -e + +# ── 自动修复脚本执行权限(解决下载/解压后脚本无 +x 的问题) ── +SCRIPTS_DIR="$(cd "$(dirname "$0")" && pwd)" +echo "[Zabbix Init] 修复脚本执行权限..." +chmod +x "${SCRIPTS_DIR}"/*.sh 2>/dev/null || true +echo "[Zabbix Init] ✓ 脚本权限已修复" + +APP_DIR="$(cd "$(dirname "$0")/.." && pwd)" +DATA_DIR="${APP_DIR}/data" + +echo "=========================================" +echo "[Zabbix Init] 开始初始化数据目录..." +echo "=========================================" + +# ── 创建所有必要的目录和 .gitkeep 文件 ── +# Server 端 +for dir in \ + server/alertscripts \ + server/externalscripts \ + server/export \ + server/modules \ + server/ssh_keys \ + server/ssl/certs \ + server/ssl/keys; do + mkdir -p "${DATA_DIR}/${dir}" + [ ! -f "${DATA_DIR}/${dir}/.gitkeep" ] && touch "${DATA_DIR}/${dir}/.gitkeep" + echo "[Zabbix Init] ✓ ${dir}" +done + +# 确保 export 目录可写 +chmod -R 755 "${DATA_DIR}/server/export" 2>/dev/null || true + +# Web 端(前端插件/模块) +for dir in web/ssl modules plugins plugin_loader; do + mkdir -p "${DATA_DIR}/${dir}" + [ ! -f "${DATA_DIR}/${dir}/.gitkeep" ] && touch "${DATA_DIR}/${dir}/.gitkeep" + echo "[Zabbix Init] ✓ ${dir}" +done + +# modules 目录需要可写(插件安装、activation.dat 写入) +# plugins 也需要 rw(容器内 stamp 文件写入) +chmod -R 777 "${DATA_DIR}/modules" 2>/dev/null || true +chmod -R 777 "${DATA_DIR}/plugins" 2>/dev/null || true +chmod -R 777 "${DATA_DIR}/plugin_loader" 2>/dev/null || true +chmod 777 "${DATA_DIR}" 2>/dev/null || true + +# Agent 端 +for dir in \ + agent/zabbix_agentd.d \ + agent/user_scripts; do + mkdir -p "${DATA_DIR}/${dir}" + [ ! -f "${DATA_DIR}/${dir}/.gitkeep" ] && touch "${DATA_DIR}/${dir}/.gitkeep" + echo "[Zabbix Init] ✓ ${dir}" +done + +# Proxy 端 +for dir in \ + proxy/externalscripts \ + proxy/modules \ + proxy/ssh_keys \ + proxy/ssl/certs \ + proxy/ssl/keys; do + mkdir -p "${DATA_DIR}/${dir}" + [ ! -f "${DATA_DIR}/${dir}/.gitkeep" ] && touch "${DATA_DIR}/${dir}/.gitkeep" + echo "[Zabbix Init] ✓ ${dir}" +done + +# ── 清理 HA 残留节点(用 docker 跑,不依赖宿主机 mysql 客户端) ── +DB_HOST="${ZABBIX_DB_HOST}" +DB_PORT="${ZABBIX_DB_PORT:-3306}" +echo "[Zabbix Init] 清理 HA 残留节点..." +docker run --rm --pull never --network host \ + zabbix/zabbix-server-mysql:ubuntu-7.0-latest \ + mysql -h"${DB_HOST}" -P"${DB_PORT}" \ + -u"${ZABBIX_DB_USER}" -p"${ZABBIX_DB_PASSWORD}" \ + -e "DELETE FROM ha_node;" "${ZABBIX_DB_NAME}" 2>/dev/null && \ + echo "[Zabbix Init] ✓ HA 节点已清理" || \ + echo "[Zabbix Init] ⚠ HA 清理跳过(首次装无此表,正常)" + +# ── 验证数据库连通性(可选) ── +if command -v mysqladmin &> /dev/null; then + echo "[Zabbix Init] 检查数据库连接 (${DB_HOST}:${DB_PORT})..." + if mysqladmin ping -h"${DB_HOST}" -P"${DB_PORT}" \ + -u"${ZABBIX_DB_USER}" -p"${ZABBIX_DB_PASSWORD}" --silent 2>/dev/null; then + echo "[Zabbix Init] ✓ 数据库连接成功" + else + echo "[Zabbix Init] ⚠ 无法连接数据库,db-init 容器启动时将自动重试" + fi +else + echo "[Zabbix Init] 跳过数据库连接检查,db-init 容器将负责初始化" +fi + +echo "=========================================" +echo "[Zabbix Init] 初始化完成,目录结构:" +find "${DATA_DIR}" -maxdepth 3 -type d | sed "s|${DATA_DIR}/| |" +echo "=========================================" diff --git a/apps/zabbix-xinchuang-edition/7.0.27/scripts/install-plugins-entrypoint.sh b/apps/zabbix-xinchuang-edition/7.0.27/scripts/install-plugins-entrypoint.sh new file mode 100755 index 000000000000..3da89ce16958 --- /dev/null +++ b/apps/zabbix-xinchuang-edition/7.0.27/scripts/install-plugins-entrypoint.sh @@ -0,0 +1,844 @@ +#!/bin/bash +# Zabbix Web 容器入口:启动前自动安装 plugins 目录中的插件合集包 +# 1. 可选:从挂载目录安装 plugin_loader.so(data/plugin_loader/) +# 2. 检测 *.zip → PHP PharData 解压(核心内置,无需扩展)→ 执行 ./install.sh -m auto +# 完成后委托官方 docker-entrypoint.sh 启动 Nginx + PHP-FPM + +set -euo pipefail + +ORIGINAL_ENTRYPOINT="/usr/bin/docker-entrypoint.sh" +PLUGINS_DIR="${ZABBIX_PLUGINS_DIR:-/var/lib/zabbix/plugins}" +PLUGIN_LOADER_DIR="${ZABBIX_PLUGIN_LOADER_DIR:-/var/lib/zabbix/plugin_loader}" +WORK_DIR="${ZABBIX_PLUGINS_WORK_DIR:-/var/lib/zabbix/plugin-install}" +MANIFEST_FILE="${ZABBIX_MODULES_INSTALL_DIR:-/usr/share/zabbix/modules}/.plugin-manifest" +PLUGIN_LOADER_STAMP_FILE="${WORK_DIR}/.plugin_loader.sha256" + +ensure_php_extract() { + # PharData 是 PHP 核心内置类,无需额外扩展,优先使用 + if php -r "exit(class_exists('PharData') ? 0 : 1);" 2>/dev/null; then + export PHP_EXTRACT_METHOD="phar" + return 0 + fi + + # 回退 ZipArchive + if php -r "exit(class_exists('ZipArchive') ? 0 : 1);" 2>/dev/null; then + export PHP_EXTRACT_METHOD="ziparchive" + return 0 + fi + + echo "** 错误: PHP 缺少 PharData 和 ZipArchive,无法解压插件包" + exit 1 +} + +export_php_fpm_env_defaults() { + export PHP_FPM_PM="${PHP_FPM_PM:-dynamic}" + export PHP_FPM_PM_MAX_CHILDREN="${PHP_FPM_PM_MAX_CHILDREN:-50}" + export PHP_FPM_PM_START_SERVERS="${PHP_FPM_PM_START_SERVERS:-5}" + export PHP_FPM_PM_MIN_SPARE_SERVERS="${PHP_FPM_PM_MIN_SPARE_SERVERS:-5}" + export PHP_FPM_PM_MAX_SPARE_SERVERS="${PHP_FPM_PM_MAX_SPARE_SERVERS:-35}" + export PHP_FPM_PM_MAX_REQUESTS="${PHP_FPM_PM_MAX_REQUESTS:-0}" + export ZBX_MAXEXECUTIONTIME="${ZBX_MAXEXECUTIONTIME:-600}" + export ZBX_MEMORYLIMIT="${ZBX_MEMORYLIMIT:-128M}" + export ZBX_POSTMAXSIZE="${ZBX_POSTMAXSIZE:-16M}" + export ZBX_UPLOADMAXFILESIZE="${ZBX_UPLOADMAXFILESIZE:-2M}" + export ZBX_MAXINPUTTIME="${ZBX_MAXINPUTTIME:-300}" + export PHP_TZ="${PHP_TZ:-Europe/Riga}" + export EXPOSE_WEB_SERVER_INFO="${EXPOSE_WEB_SERVER_INFO:-on}" +} + +# 解析 Zabbix Web 容器内 PHP-FPM pool 运行用户(非 master 的 root) +resolve_zabbix_php_fpm_user() { + local pool_conf pool_user + + if [ -n "${ZABBIX_PHP_FPM_USER:-}" ]; then + echo "$ZABBIX_PHP_FPM_USER" + return 0 + fi + + pool_conf=$(ls /etc/php/*/fpm/pool.d/zabbix.conf 2>/dev/null | head -1 || true) + if [ -n "$pool_conf" ] && [ -f "$pool_conf" ]; then + pool_user=$(grep -iE '^[[:space:]]*user[[:space:]]*=' "$pool_conf" 2>/dev/null \ + | head -1 | sed 's/^[[:space:]]*user[[:space:]]*=[[:space:]]*//I;s/[[:space:]]*;.*$//;s/^[[:space:]]*//;s/[[:space:]]*$//') + if [ -n "$pool_user" ]; then + echo "$pool_user" + return 0 + fi + fi + + # pool 配置尚未生成时,优先使用 Zabbix 镜像标准环境变量 + if [ -n "${DAEMON_USER:-}" ] && getent passwd "$DAEMON_USER" >/dev/null 2>&1; then + echo "$DAEMON_USER" + return 0 + fi + + for candidate in zabbix apache nginx www-data; do + if getent passwd "$candidate" >/dev/null 2>&1; then + echo "$candidate" + return 0 + fi + done + + echo "www-data" +} + +fix_modules_ownership() { + local modules_dir="${ZABBIX_MODULES_INSTALL_DIR:-/usr/share/zabbix/modules}" + local php_user + + php_user="$(resolve_zabbix_php_fpm_user)" + if [ ! -d "$modules_dir" ]; then + return 0 + fi + + echo "** 修正模块目录所有权为 ${php_user}(供 Web 写入 activation.dat)" + chown -R "${php_user}:${php_user}" "$modules_dir" + chmod -R u+rwX,g+rX "$modules_dir" +} + +# 修复插件 includeConfig() 可能导致的函数重复声明问题 +# 将 include $path 改为 include_once $path +patch_include_once() { + local modules_dir="${ZABBIX_MODULES_INSTALL_DIR:-/usr/share/zabbix/modules}" + find "$modules_dir" -name 'CControllerZabbixDBBackup.php' -print0 2>/dev/null | while IFS= read -r -d '' f; do + if grep -q 'include \$path' "$f" 2>/dev/null && ! grep -q 'include_once \$path' "$f" 2>/dev/null; then + echo "** 修补 $(basename "$(dirname "$(dirname "$f")")")/actions/CControllerZabbixDBBackup.php: include → include_once" + sed -i 's/include \$path/include_once \$path/' "$f" + fi + done +} + +# ── 激活码文件备份/恢复,防止 install.sh 中的 unzip -o 或 update_activation 覆盖 ── +ACTIVATION_BACKUP_DIR="" + +backup_activation_files() { + local modules_dir="${ZABBIX_MODULES_INSTALL_DIR:-/usr/share/zabbix/modules}" + ACTIVATION_BACKUP_DIR=$(mktemp -d) + + local count=0 + while IFS= read -r -d '' f; do + local rel="${f#$modules_dir/}" + local backup_path="${ACTIVATION_BACKUP_DIR}/${rel}" + mkdir -p "$(dirname "$backup_path")" + cp -a "$f" "$backup_path" + count=$((count + 1)) + done < <(find "$modules_dir" -maxdepth 2 -name 'activation.dat' -print0 2>/dev/null) + + if [ "$count" -gt 0 ]; then + echo "** 已备份 ${count} 个 activation.dat → ${ACTIVATION_BACKUP_DIR}" + fi +} + +restore_activation_files() { + local modules_dir="${ZABBIX_MODULES_INSTALL_DIR:-/usr/share/zabbix/modules}" + + if [ -z "${ACTIVATION_BACKUP_DIR:-}" ] || [ ! -d "$ACTIVATION_BACKUP_DIR" ]; then + return 0 + fi + + # restore 内部关闭 errexit,防止单个文件失败导致整个脚本退出 + set +e + + local restored=0 skipped=0 error_count=0 + while IFS= read -r -d '' f; do + local rel="${f#$ACTIVATION_BACKUP_DIR/}" + local target="${modules_dir}/${rel}" + + if [ -f "$target" ]; then + local target_sum backup_sum + target_sum=$(sha256sum "$target" 2>/dev/null | awk '{print $1}') + backup_sum=$(sha256sum "$f" 2>/dev/null | awk '{print $1}') + if [ -n "$target_sum" ] && [ "$target_sum" = "$backup_sum" ]; then + skipped=$((skipped + 1)) + continue + fi + fi + + # 确保目标父目录存在(install.sh 可能 rm -rf 了) + mkdir -p "$(dirname "$target")" 2>/dev/null || true + + if cp -a "$f" "$target" 2>/dev/null; then + local php_user="${ZABBIX_PHP_FPM_USER:-zabbix}" + chown "${php_user}:${php_user}" "$target" 2>/dev/null || true + restored=$((restored + 1)) + else + echo "** 警告: 恢复 activation.dat 失败: ${target}" >&2 + error_count=$((error_count + 1)) + fi + done < <(find "$ACTIVATION_BACKUP_DIR" -name 'activation.dat' -print0 2>/dev/null) + + if [ "$restored" -gt 0 ] || [ "$skipped" -gt 0 ]; then + echo "** activation.dat: 恢复 ${restored} 个, 未变化 ${skipped} 个" \ + "${error_count:+(${error_count} 个失败)}" + fi + + rm -rf "$ACTIVATION_BACKUP_DIR" + ACTIVATION_BACKUP_DIR="" + + set -e +} + +# ── 将 activation.dat 传播到所有缺它的模块 ── +# 独立插件 zip 包不含 activation.dat,install.sh 的 update_activation() 会跳过, +# 导致新安装的模块没有许可证文件。此函数按优先级查找来源: +# 1. 已有模块目录中的 activation.dat +# 2. $PLUGINS_DIR/activation.dat(用户放在 data/plugins/ 下) +# 3. $PLUGIN_LOADER_DIR/activation.dat(用户放在 data/plugin_loader/ 下) +# 复制到所有缺失的模块(所有模块共用同一份站点许可证)。 +propagate_activation_dat() { + local modules_dir="${ZABBIX_MODULES_INSTALL_DIR:-/usr/share/zabbix/modules}" + local source_file="" + + # 优先级1: 已有模块中的 activation.dat + source_file=$(find "$modules_dir" -maxdepth 2 -name 'activation.dat' -print -quit 2>/dev/null) + + # 优先级2: plugins 目录(用户可以把激活码文件放在 zip 同级) + if [ -z "$source_file" ] || [ ! -f "$source_file" ]; then + if [ -f "${PLUGINS_DIR}/activation.dat" ]; then + source_file="${PLUGINS_DIR}/activation.dat" + echo "** activation.dat: 从 ${PLUGINS_DIR}/ 读取来源" + fi + fi + + # 优先级3: plugin_loader 目录 + if [ -z "$source_file" ] || [ ! -f "$source_file" ]; then + if [ -n "${PLUGIN_LOADER_DIR:-}" ] && [ -f "${PLUGIN_LOADER_DIR}/activation.dat" ]; then + source_file="${PLUGIN_LOADER_DIR}/activation.dat" + echo "** activation.dat: 从 ${PLUGIN_LOADER_DIR}/ 读取来源" + fi + fi + + if [ -z "$source_file" ] || [ ! -f "$source_file" ]; then + echo "** activation.dat: 未找到许可证来源文件" + echo "** → 请将 activation.dat 放到 data/plugins/ 目录下后重启容器" + echo "** → 或手动复制到各模块目录: zabbix-module-*/activation.dat" + return 0 + fi + + local source_content + source_content=$(tr -d ' \n\r' < "$source_file") + if [ -z "$source_content" ]; then + echo "** activation.dat: 来源文件内容为空,跳过" + return 0 + fi + + local php_user + php_user="$(resolve_zabbix_php_fpm_user)" + + local copied=0 skipped=0 + for mod_dir in "$modules_dir"/zabbix-module-*/; do + [ -d "$mod_dir" ] || continue + + local target="${mod_dir}activation.dat" + if [ -f "$target" ]; then + local target_content + target_content=$(tr -d ' \n\r' < "$target") + if [ "$target_content" = "$source_content" ]; then + skipped=$((skipped + 1)) + continue + fi + fi + + cp "$source_file" "$target" + chmod 644 "$target" + chown "${php_user}:${php_user}" "$target" 2>/dev/null || true + copied=$((copied + 1)) + done + + if [ "$copied" -gt 0 ]; then + echo "** activation.dat: 已传播到 ${copied} 个缺失模块 (跳过 ${skipped} 个已有)" + fi +} + +PHP_FPM_INFO_CACHE="" + +# php-fpm -i 输出较长;若与 awk exit 组成管道,pipefail 下会因 SIGPIPE 导致退出码 255 +php_fpm_info() { + if [ -n "$PHP_FPM_INFO_CACHE" ]; then + echo "$PHP_FPM_INFO_CACHE" + return 0 + fi + + local php_fpm_bin="${PHP_FPM_BIN:-}" + if [ -z "$php_fpm_bin" ]; then + resolve_php_fpm_paths + php_fpm_bin="${PHP_FPM_BIN:-}" + fi + + if [ -n "$php_fpm_bin" ] && [ -x "$php_fpm_bin" ]; then + PHP_FPM_INFO_CACHE=$("$php_fpm_bin" -i 2>/dev/null || true) + fi + + echo "$PHP_FPM_INFO_CACHE" +} + +resolve_php_fpm_paths() { + local php_ver php_fpm_bin php_fpm_conf + + php_fpm_bin="$(command -v php-fpm 2>/dev/null || true)" + if [ -z "$php_fpm_bin" ]; then + php_fpm_bin="$(ls /usr/sbin/php-fpm* 2>/dev/null | head -1 || true)" + fi + + php_ver="$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;' 2>/dev/null || true)" + if [ -n "$php_ver" ] && [ -f "/etc/php/${php_ver}/fpm/php-fpm.conf" ]; then + php_fpm_conf="/etc/php/${php_ver}/fpm/php-fpm.conf" + elif [ -f /etc/php-fpm.conf ]; then + php_fpm_conf="/etc/php-fpm.conf" + else + php_fpm_conf="$(ls /etc/php/*/fpm/php-fpm.conf 2>/dev/null | head -1 || true)" + fi + + PHP_FPM_BIN="$php_fpm_bin" + PHP_FPM_CONF="$php_fpm_conf" +} + +start_temp_php_fpm() { + if pgrep -f 'php-fpm: master' >/dev/null 2>&1; then + return 0 + fi + + export_php_fpm_env_defaults + resolve_php_fpm_paths + + if [ -z "${PHP_FPM_BIN:-}" ] || [ -z "${PHP_FPM_CONF:-}" ]; then + echo "** 警告: 未找到 php-fpm 可执行文件或配置,跳过临时启动" + return 0 + fi + + echo "** 临时启动 PHP-FPM(${PHP_FPM_BIN}),供 install.sh 检测运行环境" + local -a fpm_args=(--daemonize -y "$PHP_FPM_CONF") + if [ "$(id -u)" = "0" ]; then + fpm_args=(--allow-to-run-as-root "${fpm_args[@]}") + fi + if ! "$PHP_FPM_BIN" "${fpm_args[@]}"; then + echo "** 警告: PHP-FPM 临时启动失败,install.sh 将尝试其他检测方式" + return 0 + fi + sleep 2 +} + +stop_temp_php_fpm() { + if [ -f /tmp/php-fpm.pid ]; then + kill "$(cat /tmp/php-fpm.pid)" 2>/dev/null || true + rm -f /tmp/php-fpm.pid + fi + pkill -f 'php-fpm: master' 2>/dev/null || true + pkill -x php-fpm 2>/dev/null || true + rm -f /tmp/php-fpm.sock 2>/dev/null || true + sleep 1 +} + +plugins_zip_checksum() { + local checksum_file="$1" + shopt -s nullglob + local zips=("$PLUGINS_DIR"/*.zip) + shopt -u nullglob + + if [ ${#zips[@]} -eq 0 ]; then + : > "$checksum_file" + return 0 + fi + + for zip in "${zips[@]}"; do + sha256sum "$zip" + done | sort > "$checksum_file" +} + +# ── 从 zip 文件名解析出预期的 Zabbix modules 子目录名 ── +# 输入: host-import-export-1.0.0-zabbix70-php85-ubuntu26-amd64.zip +# 输出: zabbix-module-host-import-export-1.0.0(写入全局变量 PARSED_MODULE_DIR) +# 返回: 0=解析成功, 1=无法解析 +PARSED_MODULE_DIR="" +PARSED_PLUGIN_NAME="" +parse_module_dir_from_zip_name() { + local zip_name="$1" + + PARSED_MODULE_DIR="" + PARSED_PLUGIN_NAME="" + + # 提取版本号: 文件名中第一个 x.y.z 三段式 + local version + version=$(echo "$zip_name" | sed -n 's/.*-\([0-9]\+\.[0-9]\+\.[0-9]\+\)-.*/\1/p') + if [ -z "$version" ]; then + return 1 + fi + + # 插件名: 版本号之前的所有内容 + local plugin_name + plugin_name=$(echo "$zip_name" | sed "s/-${version}-.*//") + + PARSED_PLUGIN_NAME="$plugin_name" + PARSED_MODULE_DIR="zabbix-module-${plugin_name}-${version}" + return 0 +} + +find_install_script() { + local root="$1" + + if [ -x "${root}/install.sh" ]; then + echo "${root}/install.sh" + return 0 + fi + + local install_sh + install_sh=$(find "$root" -maxdepth 3 -type f -name 'install.sh' 2>/dev/null | head -1) + if [ -n "$install_sh" ] && [ -f "$install_sh" ]; then + chmod +x "$install_sh" 2>/dev/null || true + echo "$install_sh" + return 0 + fi + + return 1 +} + +prepare_work_dir() { + local zip="$1" + local zip_name method + + zip_name=$(basename "$zip") + method="${PHP_EXTRACT_METHOD:-phar}" + echo "** 解压插件包(PHP ${method}): ${zip_name}" + + if [ "$method" = "phar" ]; then + php -r " + try { + \$phar = new PharData('$zip'); + \$phar->extractTo('$WORK_DIR', null, true); + } catch (Exception \$e) { + fwrite(STDERR, \"** 错误: PharData 解压失败: \" . \$e->getMessage() . \"\\n\"); + exit(1); + } + " || { echo "** 错误: PHP PharData 解压 ${zip_name} 失败"; exit 1; } + else + php -r " + \$zip = new ZipArchive(); + if (\$zip->open('$zip') !== true) { + fwrite(STDERR, \"** 错误: 无法打开 $zip\\n\"); + exit(1); + } + if (!\$zip->extractTo('$WORK_DIR')) { + fwrite(STDERR, \"** 错误: 解压失败 $zip\\n\"); + \$zip->close(); + exit(1); + } + \$zip->close(); + " || { echo "** 错误: PHP ZipArchive 解压 ${zip_name} 失败"; exit 1; } + fi +} + +resolve_php_bin() { + if [ -n "${PHP_BIN:-}" ] && [ -x "$PHP_BIN" ]; then + return 0 + fi + + PHP_BIN="$(command -v php 2>/dev/null || true)" +} + +resolve_php_fpm_ini_for_loader() { + local phpinfo + + PHP_INI="" + phpinfo="$(php_fpm_info)" + if [ -n "$phpinfo" ]; then + PHP_INI=$(echo "$phpinfo" | awk -F'=> ' '/^Loaded Configuration File/{gsub(/^[[:space:]]+|[[:space:]]+$/,"",$2); print $2; exit}') + fi + + if [ -z "$PHP_INI" ] || [ ! -f "$PHP_INI" ]; then + local candidate + for candidate in /etc/php/*/fpm/php.ini /etc/php.ini; do + for candidate in $candidate; do + if [ -f "$candidate" ]; then + PHP_INI="$candidate" + return 0 + fi + done + done + fi + + resolve_php_bin + if [ -z "$PHP_INI" ] && [ -n "$PHP_BIN" ]; then + PHP_INI=$("$PHP_BIN" -r "echo php_ini_loaded_file();" 2>/dev/null || true) + fi +} + +resolve_php_ext_dir_for_loader() { + PHP_EXT_DIR="" + + resolve_php_bin + resolve_php_fpm_ini_for_loader + + if [ -n "$PHP_BIN" ] && [ -n "$PHP_INI" ] && [ -f "$PHP_INI" ]; then + PHP_EXT_DIR=$("$PHP_BIN" -c "$PHP_INI" -r "echo ini_get('extension_dir');" 2>/dev/null || true) + fi + + if [ -z "$PHP_EXT_DIR" ]; then + local phpinfo + phpinfo="$(php_fpm_info)" + if [ -n "$phpinfo" ]; then + PHP_EXT_DIR=$(echo "$phpinfo" | awk -F'=> ' '/^extension_dir /{v=$2; sub(/[[:space:]]*=>.*$/,"",v); gsub(/^[[:space:]]+|[[:space:]]+$/,"",v); print v; exit}') + fi + fi + + if [ -z "$PHP_EXT_DIR" ] && [ -n "$PHP_BIN" ]; then + PHP_EXT_DIR=$("$PHP_BIN" -r "echo ini_get('extension_dir');" 2>/dev/null || true) + fi +} + +ensure_plugin_loader_php_ini() { + local cli_ini + + if [ -z "${PHP_INI:-}" ] || [ ! -f "$PHP_INI" ]; then + echo "** 警告: 未找到 PHP-FPM php.ini,跳过 plugin_loader 扩展配置" + return 1 + fi + + if grep -qE '^[[:space:]]*extension[[:space:]]*=[[:space:]]*plugin_loader\.so' "$PHP_INI" 2>/dev/null; then + echo "** extension=plugin_loader.so 已在 PHP-FPM php.ini 中配置" + else + echo "** 添加 extension=plugin_loader.so 到 PHP-FPM php.ini (${PHP_INI})" + echo "extension=plugin_loader.so" >> "$PHP_INI" + fi + + resolve_php_bin + if [ -n "$PHP_BIN" ]; then + cli_ini=$("$PHP_BIN" -r "echo php_ini_loaded_file();" 2>/dev/null || true) + if [ -n "$cli_ini" ] && [ "$cli_ini" != "$PHP_INI" ] && [ -f "$cli_ini" ]; then + if ! grep -qE '^[[:space:]]*extension[[:space:]]*=[[:space:]]*plugin_loader\.so' "$cli_ini" 2>/dev/null; then + echo "** 同步 extension=plugin_loader.so 到 CLI php.ini (${cli_ini})" + echo "extension=plugin_loader.so" >> "$cli_ini" + fi + fi + fi +} + +find_mounted_plugin_loader_so() { + local dir="$1" + local candidate + + if [ ! -d "$dir" ]; then + return 1 + fi + + if [ -f "${dir}/plugin_loader.so" ]; then + echo "${dir}/plugin_loader.so" + return 0 + fi + + shopt -s nullglob + local candidates=("${dir}"/plugin_loader-*.so) + shopt -u nullglob + + if [ ${#candidates[@]} -eq 1 ]; then + echo "${candidates[0]}" + return 0 + fi + + if [ ${#candidates[@]} -gt 1 ]; then + echo "** 警告: ${dir} 中存在多个 plugin_loader-*.so,请仅保留一个或命名为 plugin_loader.so" >&2 + return 1 + fi + + return 1 +} + +install_mounted_plugin_loader_if_needed() { + local src target current_checksum installed_checksum + + if [ "${ZABBIX_PLUGIN_LOADER_AUTO_INSTALL:-true}" != "true" ]; then + echo "** ZABBIX_PLUGIN_LOADER_AUTO_INSTALL=false,跳过挂载目录 plugin_loader.so 安装" + return 0 + fi + + src=$(find_mounted_plugin_loader_so "$PLUGIN_LOADER_DIR") || return 0 + + echo "** 发现挂载的 plugin_loader.so: ${src}" + resolve_php_fpm_paths + resolve_php_ext_dir_for_loader + + if [ -z "${PHP_EXT_DIR:-}" ]; then + echo "** 错误: 无法解析 PHP 扩展目录,跳过 plugin_loader.so 安装" + return 1 + fi + + target="${PHP_EXT_DIR}/plugin_loader.so" + current_checksum=$(sha256sum "$src" | awk '{print $1}') + + if [ -f "$PLUGIN_LOADER_STAMP_FILE" ]; then + installed_checksum=$(cat "$PLUGIN_LOADER_STAMP_FILE") + if [ "$installed_checksum" = "$current_checksum" ] && [ -f "$target" ]; then + local target_checksum + target_checksum=$(sha256sum "$target" | awk '{print $1}') + if [ "$target_checksum" = "$current_checksum" ]; then + echo "** 挂载的 plugin_loader.so 未变化,跳过重复安装" + ensure_plugin_loader_php_ini || true + return 0 + fi + fi + fi + + echo "** 复制 plugin_loader.so 到 ${target}" + cp -f "$src" "$target" + chmod 644 "$target" + ensure_plugin_loader_php_ini || true + + mkdir -p "$(dirname "$PLUGIN_LOADER_STAMP_FILE")" + echo "$current_checksum" > "$PLUGIN_LOADER_STAMP_FILE" + echo "** 挂载目录 plugin_loader.so 安装完成" +} + +install_plugins_if_needed() { + local install_sh + local has_zip="no" + local changed_zips=() + + if [ "${ZABBIX_PLUGINS_AUTO_INSTALL:-true}" != "true" ]; then + echo "** ZABBIX_PLUGINS_AUTO_INSTALL=false,跳过插件自动安装" + return 0 + fi + + if [ ! -d "$PLUGINS_DIR" ]; then + echo "** 插件目录不存在: ${PLUGINS_DIR},跳过" + return 0 + fi + + shopt -s nullglob + local zips=("$PLUGINS_DIR"/*.zip) + shopt -u nullglob + + if [ ${#zips[@]} -eq 0 ]; then + if install_sh=$(find_install_script "$PLUGINS_DIR"); then + echo "** 未发现 zip,使用已解压目录中的 install.sh" + WORK_DIR="$PLUGINS_DIR" + else + echo "** ${PLUGINS_DIR} 中无 *.zip,跳过插件自动安装" + return 0 + fi + else + has_zip="yes" + + # ── 构建当前 per-zip checksum 映射 ── + local -A current_checksums + for zip in "${zips[@]}"; do + local zip_name sum + zip_name=$(basename "$zip") + sum=$(sha256sum "$zip" | awk '{print $1}') + current_checksums["$zip_name"]="$sum" + done + + # ── 读取上次安装 manifest ── + local -A installed_checksums + if [ -f "$MANIFEST_FILE" ]; then + while IFS=' ' read -r sum name; do + [ -n "$name" ] && installed_checksums["$name"]="$sum" + done < "$MANIFEST_FILE" + fi + + # ── 找出新的/变化的 zip ── + # 规则1: modules 目录下无同名插件 → 首次安装,必须装 + # 规则2: modules 目录下有同名插件 → 对比 zip SHA256 与 manifest,变了才装 + local any_changed=false + local modules_dir="${ZABBIX_MODULES_INSTALL_DIR:-/usr/share/zabbix/modules}" + for zip_name in "${!current_checksums[@]}"; do + local current="${current_checksums[$zip_name]}" + local installed="${installed_checksums[$zip_name]:-}" + + if parse_module_dir_from_zip_name "$zip_name"; then + if [ -d "${modules_dir}/${PARSED_MODULE_DIR}" ]; then + # 已有同名模块 → 对比 SHA256 + if [ "$current" != "$installed" ]; then + echo "** [更新] ${zip_name} → ${PARSED_MODULE_DIR}/ 已存在,zip 有变化,重新安装" + changed_zips+=("$PLUGINS_DIR/$zip_name") + any_changed=true + else + echo "** [跳过] ${zip_name} → ${PARSED_MODULE_DIR}/ 已安装且 zip 未变化" + fi + else + # 无同名模块 → 新安装 + echo "** [新增] ${zip_name} → ${PARSED_MODULE_DIR}/ 不存在,首次安装" + changed_zips+=("$PLUGINS_DIR/$zip_name") + any_changed=true + fi + else + # 无法解析 zip 名 → 回退到纯 SHA256 对比 + echo "** 警告: 无法解析 ${zip_name} 的插件名/版本号,回退到 SHA256 对比" + if [ "$current" != "$installed" ]; then + changed_zips+=("$PLUGINS_DIR/$zip_name") + any_changed=true + fi + fi + done + + if [ "$any_changed" = false ]; then + echo "** 所有插件包未变化,跳过安装" + return 0 + fi + + echo "** 检测到 ${#changed_zips[@]}/${#current_checksums[@]} 个插件有变化,增量安装" + + ensure_php_extract + mkdir -p "$WORK_DIR" + + # ── 只解压变化/新增的 zip,解压后立即定位其 install.sh ── + local changed_scripts=() + for zip in "${changed_zips[@]}"; do + local zip_name zip_stem + zip_name=$(basename "$zip") + zip_stem="${zip_name%.zip}" + + # 删除该 zip 之前解压的旧目录(按 zip 文件名匹配) + if [ -d "${WORK_DIR}/${zip_stem}" ]; then + rm -rf "${WORK_DIR:?}/${zip_stem}" + fi + + prepare_work_dir "$zip" + + # 解压后在对应目录中找 install.sh + # 优先使用根级 install.sh(如 zabbix-plugins-xxx 合集包,与 activation.dat 同级) + # 找不到时再递归查找嵌套的 install.sh(独立插件包场景) + local scr + if [ -x "${WORK_DIR}/${zip_stem}/install.sh" ]; then + scr="${WORK_DIR}/${zip_stem}/install.sh" + else + scr=$(find "${WORK_DIR}/${zip_stem}" -maxdepth 3 -type f -name 'install.sh' -print -quit 2>/dev/null) + fi + if [ -n "$scr" ] && [ -f "$scr" ]; then + changed_scripts+=("$scr") + fi + done + + if [ ${#changed_scripts[@]} -eq 0 ]; then + echo "** 变化插件未包含 install.sh,跳过" + save_manifest + return 0 + fi + fi + + # ── 收集需要执行的 install.sh ── + local install_scripts=() + if [ "$has_zip" = "yes" ]; then + install_scripts=("${changed_scripts[@]}") + else + install_scripts+=("$install_sh") + fi + + echo "** 执行 ${#install_scripts[@]} 个插件安装" + + # ── unzip wrapper ── + # 劫持 install.sh 中的 unzip 调用:解压前保存 activation.dat,解压后恢复 + local unzip_wrapper="/usr/local/bin/unzip" + cat > "$unzip_wrapper" <<'UNZIPWRAPPER' +#!/bin/sh +dest="." +while [ $# -gt 0 ]; do + case "$1" in + -d) dest="$2"; shift 2 ;; + -o|-q) shift ;; + -*) shift ;; + *) zipfile="$1"; shift ;; + esac +done +if [ -z "${zipfile:-}" ]; then + echo "unzip: missing file operand" >&2; exit 1 +fi +export UNZIP_FILE="$zipfile" UNZIP_DEST="$dest" +php -r ' +$zipfile=getenv("UNZIP_FILE"); +$dest=getenv("UNZIP_DEST"); +// 保存目标目录中已有的 activation.dat +$saved=[]; +$patterns=["$dest/zabbix-module-*/activation.dat","$dest/activation.dat"]; +foreach($patterns as $pat){ + $files=glob($pat) ?: []; + foreach($files as $f) $saved[$f]=@file_get_contents($f); +} +// 解压 +try{$p=new PharData($zipfile);$p->extractTo($dest,null,true);} +catch(Exception $e){fwrite(STDERR,"unzip error: ".$e->getMessage()."\n");exit(1);} +// 恢复被覆盖的 activation.dat +$n=0; +foreach($saved as $path=>$content){ + if($content===false) continue; + $dir=dirname($path); + if(!is_dir($dir)) @mkdir($dir,0777,true); + @file_put_contents($path,$content); + $n++; +} +if($n>0) fwrite(STDERR,"** unzip wrapper: 已保护 ".$n." 个 activation.dat\n"); +' +UNZIPWRAPPER + chmod +x "$unzip_wrapper" + + start_temp_php_fpm + + local php_fpm_user + php_fpm_user="$(resolve_zabbix_php_fpm_user)" + echo "** PHP-FPM pool 用户: ${php_fpm_user}(install.sh 将用此用户 chown 模块目录)" + + # ── 备份所有已安装模块的 activation.dat,防止 install.sh 覆盖 ── + backup_activation_files + trap restore_activation_files EXIT + + local install_status=0 + for install_sh in "${install_scripts[@]}"; do + local plugin_work_dir + plugin_work_dir=$(dirname "$install_sh") + + chmod +x "$install_sh" 2>/dev/null || true + + echo "** 执行 $(basename "$plugin_work_dir")/install.sh -m auto" + + set +e + (cd "$plugin_work_dir" && PHP_USER="$php_fpm_user" ./install.sh -m auto) + install_status=$? + set -e + + if [ "$install_status" -ne 0 ]; then + echo "** 错误: $(basename "$plugin_work_dir")/install.sh 退出码 ${install_status}" + restore_activation_files + exit "$install_status" + fi + + sleep 1 + done + + restore_activation_files + trap - EXIT + + rm -f "$unzip_wrapper" + stop_temp_php_fpm + + # ── 传播 activation.dat:新安装模块如果缺少,从已有模块复制 ── + propagate_activation_dat + + fix_modules_ownership + patch_include_once + save_manifest + + echo "** 插件自动安装完成" +} + +save_manifest() { + mkdir -p "$(dirname "$MANIFEST_FILE")" + local tmp_manifest + tmp_manifest=$(mktemp) + shopt -s nullglob + local zips=("$PLUGINS_DIR"/*.zip) + shopt -u nullglob + for zip in "${zips[@]}"; do + sha256sum "$zip" + done | while read -r sum path; do + echo "$sum $(basename "$path")" + done > "$tmp_manifest" + mv "$tmp_manifest" "$MANIFEST_FILE" +} + +if [ "$(id -u)" = "0" ]; then + install_mounted_plugin_loader_if_needed || true + install_plugins_if_needed || true + propagate_activation_dat + fix_modules_ownership +else + echo "** 非 root 用户,跳过插件自动安装(请使用 compose.plugin-loader.yaml 中的 user: \"0\")" +fi + +exec "$ORIGINAL_ENTRYPOINT" "$@" diff --git a/apps/zabbix-xinchuang-edition/7.0.27/scripts/uninstall.sh b/apps/zabbix-xinchuang-edition/7.0.27/scripts/uninstall.sh new file mode 100755 index 000000000000..3944eb42a9a1 --- /dev/null +++ b/apps/zabbix-xinchuang-edition/7.0.27/scripts/uninstall.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# ============================================================================= +# Zabbix 卸载脚本 +# 注意:此脚本在容器停止后执行 +# ============================================================================= + +set -e + +# ── 自动修复脚本执行权限 ── +SCRIPTS_DIR="$(cd "$(dirname "$0")" && pwd)" +chmod +x "${SCRIPTS_DIR}"/*.sh 2>/dev/null || true + +APP_DIR="$(cd "$(dirname "$0")/.." && pwd)" +DATA_DIR="${APP_DIR}/data" + +echo "=========================================" +echo "[Zabbix Uninstall] 开始清理..." +echo "=========================================" + +# 注意:为了保护用户数据安全,卸载时不会自动删除数据目录 +# 如需彻底删除,请手动执行: rm -rf ${DATA_DIR} +if [ -d "${DATA_DIR}" ]; then + echo "[Zabbix Uninstall] ⚠ 数据目录未自动删除,保留在: ${DATA_DIR}" + echo "[Zabbix Uninstall] 如需彻底清除数据,请手动执行: rm -rf ${DATA_DIR}" +else + echo "[Zabbix Uninstall] 数据目录不存在,无需清理" +fi + +echo "[Zabbix Uninstall] 卸载完成" diff --git a/apps/zabbix-xinchuang-edition/7.0.27/scripts/upgrade.sh b/apps/zabbix-xinchuang-edition/7.0.27/scripts/upgrade.sh new file mode 100755 index 000000000000..3932fc6ecea1 --- /dev/null +++ b/apps/zabbix-xinchuang-edition/7.0.27/scripts/upgrade.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# ============================================================================= +# Zabbix 升级脚本 +# 保留数据目录,仅更新容器镜像 +# ============================================================================= + +set -e + +# ── 自动修复脚本执行权限 ── +SCRIPTS_DIR="$(cd "$(dirname "$0")" && pwd)" +chmod +x "${SCRIPTS_DIR}"/*.sh 2>/dev/null || true + +APP_DIR="$(cd "$(dirname "$0")/.." && pwd)" +DATA_DIR="${APP_DIR}/data" + +echo "=========================================" +echo "[Zabbix Upgrade] 开始升级 Zabbix..." +echo "=========================================" + +# 确保数据目录存在 +for dir in server/alertscripts server/externalscripts server/export web/ssl; do + mkdir -p "${DATA_DIR}/${dir}" + if [ ! -f "${DATA_DIR}/${dir}/.gitkeep" ]; then + touch "${DATA_DIR}/${dir}/.gitkeep" + fi +done + +echo "[Zabbix Upgrade] 保留数据目录: ${DATA_DIR}" +echo "[Zabbix Upgrade] 升级完成,将使用新版本镜像" diff --git a/apps/zabbix-xinchuang-edition/README.md b/apps/zabbix-xinchuang-edition/README.md new file mode 100644 index 000000000000..b032099b7838 --- /dev/null +++ b/apps/zabbix-xinchuang-edition/README.md @@ -0,0 +1,79 @@ +# Zabbix 7.0 信创版 + +企业级开源监控解决方案,支持网络、服务器、虚拟机和云服务的全方位监控。需外接数据库(TDSQL/MySQL/MariaDB),部署后自动初始化。Agent/Proxy 默认关闭,开启后容器启动。 + +--- + +## 组件说明 + +| 组件 | 说明 | 默认状态 | +|------|------|----------| +| zabbix-db-init | 数据库初始化(建表后保持运行) | 常驻运行 | +| zabbix-server | 监控数据采集与处理核心 | 常驻运行 | +| zabbix-web | Nginx + PHP Web 管理界面,开机自动装插件 | 常驻运行 | +| zabbix-agent | 本机监控 Agent | 可选(关闭时空转) | +| zabbix-proxy | 分布式 Proxy 节点 | 可选(关闭时空转) | + +## 镜像说明 + +> **注意**:`zabbix/zabbix-server-mysql` 和 `zabbix/zabbix-web-nginx-mysql` 中的 "mysql" 表示编译了 MySQL 客户端支持,**不是数据库镜像**。本应用不包含数据库服务。 + +| 镜像 | 标签 | +|------|------| +| zabbix/zabbix-server-mysql | ubuntu-7.0-latest | +| zabbix/zabbix-web-nginx-mysql | ubuntu-7.0-latest | +| zabbix/zabbix-agent | ubuntu-7.0-latest | +| zabbix/zabbix-proxy-mysql | ubuntu-7.0-latest | + +## 安装前提 + +- **必须**:已准备好外部数据库(支持 TDSQL / MySQL 5.7+ / MariaDB 10.5+) +- **推荐**:服务器内存 4GB 以上,CPU 2 核以上 +- 表结构由 db-init 容器在首次部署时自动创建 +- 若使用 Proxy,需额外准备一个独立的 Proxy 数据库 + +## 安装后 + +1. 浏览器访问 `http://<服务器IP>:` +2. 默认登录:`Admin` / `zabbix`,**首次登录后立即修改密码!** + +## 端口说明 + +| 端口 | 默认值 | 用途 | +|------|--------|------| +| Web UI | 8080 | Zabbix Web 管理界面 | +| Server | 10051 | Agent/Proxy 连接 Server | +| Agent | 10050 | 本机 Agent(需先启用) | +| Proxy | 10071 | Proxy 监听(需先启用,Passive 模式) | + +## 启用 Agent / Proxy + +默认关闭(容器空转,几乎不占资源)。启用步骤: +1. 1Panel → 已安装 → Zabbix → 参数 +2. 改开关为「开启」,填端口和 Proxy 数据库信息 +3. 点击「重建」 + +## 安装插件 + +上传 `zabbix-plugins-xxx.zip` 到 `data/plugins/` 目录,可通过 1Panel 文件管理或 SCP: + +```bash +cp zabbix-plugins-xxx.zip /opt/1panel/apps/local/zabbix/zabbix/data/plugins/ +``` + +1Panel → Zabbix → 重建,Web 启动时自动解压安装(PHP 内置 PharData,纯本地无需网络)。 +完成后去 Zabbix Web → 管理 → 模块 → 扫描目录 → 激活。 + +## 故障排查 + +| 现象 | 原因 | 处理 | +|------|------|------| +| Server 状态一会是一会否 | 数据库 ha_node 表有残留 | 清理: `DELETE FROM ha_node;` | +| Agent/Proxy「不存在」 | 开关未开 | 参数里改为「开启」后重建 | +| db-init「异常」 | 已初始化后不需要重建 | 正常,容器会保持运行 | + +## 相关链接 + +- 官网: https://www.zabbix.com +- 文档: https://www.zabbix.com/documentation/current/ +- GitHub: https://github.com/zabbix/zabbix diff --git a/apps/zabbix-xinchuang-edition/data.yml b/apps/zabbix-xinchuang-edition/data.yml new file mode 100644 index 000000000000..ac27149c752f --- /dev/null +++ b/apps/zabbix-xinchuang-edition/data.yml @@ -0,0 +1,31 @@ +name: Zabbix信创版 +tags: + - Tool +title: Zabbix信创版 +description: Zabbix信创版 +additionalProperties: + key: zabbix-xinchuang-edition + name: Zabbix信创版 + tags: + - Tool + shortDescZh: 企业级开源监控解决方案 | 需外接数据库,Agent/Proxy 可选,支持插件自动安装 + shortDescEn: Enterprise-class monitoring with external DB, optional Agent/Proxy, auto plugin install + shortDescEs: Solución de monitorización empresarial con base de datos externa, Agent/Proxy opcionales, instalación automática de plugins + shortDescTr: Kurumsal izleme çözümü, harici veritabanı gerektirir, isteğe bağlı Agent/Proxy, eklenti otomatik yükleme + type: tool + crossVersionUpdate: true + limit: 0 + website: https://www.zabbix.com + github: https://github.com/zabbix/zabbix + document: https://www.zabbix.com/documentation/current/ + description: + en: Zabbix is an enterprise-class open source distributed monitoring solution for networks, servers, virtual machines and cloud services. Requires external database. Agent and Proxy are optional. Plugins auto-installed on startup. + zh: Zabbix 企业级开源监控,需外接数据库(TDSQL/MySQL)。Agent/Proxy 可选,关闭时容器空转不占资源。Web 启动自动安装插件。注意:镜像不含数据库,本地已有镜像不会联网拉取。Server 状态跳变可清理数据库 ha_node 表。 + zh-Hant: Zabbix 企業級開源監控,需外接資料庫。Agent/Proxy 可選,關閉時容器空轉不佔資源。Web 啟動自動安裝插件。 + ja: Zabbixはエンタープライズ級のオープンソース分散監視ソリューションです。外部データベースが必要。Agent/Proxyはオプション。 + ms: Zabbix ialah penyelesaian pemantauan sumber terbuka kelas perusahaan. Memerlukan pangkalan data luaran. Agent/Proxy adalah pilihan. + pt-br: Zabbix é uma solução de monitoramento de código aberto de nível empresarial. Requer banco de dados externo. Agent/Proxy são opcionais. + ru: Zabbix — корпоративное решение для мониторинга с открытым кодом. Требуется внешняя база данных. Agent/Proxy опциональны. + ko: Zabbix는 엔터프라이즈급 오픈 소스 모니터링 솔루션입니다. 외부 데이터베이스가 필요합니다. Agent/Proxy는 선택 사항입니다. + es-es: Zabbix es una solución de supervisión distribuida de código abierto de nivel empresarial para redes, servidores, máquinas virtuales y servicios en la nube. Requiere base de datos externa. Agent y Proxy son opcionales. Los complementos se instalan automáticamente al iniciar. + tr: Zabbix, ağlar, sunucular, sanal makineler ve bulut hizmetleri için kurumsal sınıf açık kaynaklı dağıtılmış bir izleme çözümüdür. Harici veritabanı gerektirir. Agent ve Proxy isteğe bağlıdır. Başlangıçta eklentiler otomatik olarak yüklenir. diff --git a/apps/zabbix-xinchuang-edition/logo.png b/apps/zabbix-xinchuang-edition/logo.png new file mode 100644 index 000000000000..8cabcacd99d0 Binary files /dev/null and b/apps/zabbix-xinchuang-edition/logo.png differ