Cacti 1.2.31 Docker Compose 部署指南

Cacti 1.2.31 Docker Compose 部署指南:官方源码包自建镜像(MariaDB 10.6 + PHP 8.1 + 编译版 Spine 1.2.31),覆盖构建启动、首次登录强制改密、Web 安装向导十步实录、数据持久化、环境变量与常见排障,全程实测。

CactiCacti2026/10/20

Cacti 1.2.31 Docker Compose 部署指南

目标:在一台 Linux 服务器上用 Docker Compose 从零部署 Cacti 1.2.31 监控平台(MariaDB 10.6 + PHP 8.1 + 编译安装的 Spine 1.2.31 轮询器),完成首次登录、强制改密与 Web 安装向导,并验证登录控制台与 Spine 轮询统计;全流程已在 Ubuntu 22.04 环境实测通过(2026-10-20),部署、向导、排障回显均为实测原文。

一、环境信息

本章给出本次部署实测所用的软硬件环境与版本清单,便于读者对齐复现。Cacti 是经典的 RRDtool 轮询绘图监控系统,生产部署由「数据库 + Web/轮询机」两个角色组成,本篇用 Compose 把两个角色编排为一套栈。

项目取值
操作系统Ubuntu 22.04(Linux 5.15 x86_64)
Cacti1.2.31(官方源码包安装)
Spine 轮询器1.2.31(源码编译,/usr/local/spine/bin/spine)
数据库MariaDB 10.6(mariadb:10.6)
PHP / ApachePHP 8.1.2-1ubuntu2.27 / Apache 2.4.52
RRDtool1.7.2
对外服务端口8132(映射到 Web 服务 80 端口)
Compose 项目目录/opt/cacti-stack
部署形态单机两容器:db + web,同一自定义 bridge 网络

版本实测回显(部署完成后在 Web 服务机执行):

cat /var/www/html/cacti/include/cacti_version
/usr/local/spine/bin/spine --version
rrdtool --version | head -1
php -r "echo PHP_VERSION;"

实测输出(节选):

1.2.31
SPINE 1.2.31  Copyright 2004-2024 by The Cacti Group
RRDtool 1.7.2  Copyright by Tobias Oetiker <tobi@oetiker.ch>
8.1.2-1ubuntu2.27

💡 说明:Cacti 版本基准 1.2.31 为 2026-10-20 联网实查的 1.2.x 最新稳定版(来源:Cacti 官网与 GitHub Releases),与同专栏《Cacti 1.2.31 介绍与选型指南》保持一致。

二、镜像选型说明

本章说明为什么选择「官方源码包自建镜像」而非现成镜像,并给出可替代路线的实测对照。Cacti 官方没有把应用发布为一等公民的 Docker 镜像,Docker Hub 上的 cacti/cacti 等镜像由社区维护、版本更新滞后;而 Ubuntu/Debian 发行版仓库里的 cacti 包版本明显落后于上游。为了把版本精确钉在 1.2.31,本篇在镜像内直接使用官方源码包安装 Cacti、编译安装 Spine。

方案版本是否需联网构建轮询器优点缺点
官方源码包自建镜像(本篇)1.2.31(精确对齐)需要Spine 1.2.31 源码编译版本可控、组件齐全首次构建耗时
Ubuntu 22.04 apt 仓库1.2.19+ds1-2ubuntu1.1否cmd.php安装简单版本旧,落后上游多个修复版
社区 Docker 镜像视维护者而定否视镜像而定开箱即用版本滞后、构成不透明

实测 Ubuntu 22.04 仓库内 cacti 包版本(对照验证):

dpkg -l cacti | tail -1

实测输出:

ii  cacti          1.2.19+ds1-2ubuntu1.1 all          web interface for graphing of monitoring systems

关键差异:apt 路线拿到的是 1.2.19,与 1.2.31 相差近一年的安全与功能修复;对版本有要求的场景应选源码包自建镜像。本篇实际采用「官方源码包自建镜像」,理由是版本精确、Spine 与 Cacti 同版本配套编译。

三、前置条件

部署前需确认硬件资源、软件依赖与端口空闲,逐项核对如下:

  • 服务器规格:建议 2 核 CPU / 4 GB 内存 / 20 GB 磁盘起步(Cacti 本体占用很小,主要开销在数据库与 RRD 文件 IO);
  • 已安装 Docker Engine 20.10+ 与 Docker Compose v2(docker compose version 可执行);
  • 服务器可访问外网(构建镜像时需要下载 Ubuntu 仓库软件与 GitHub 源码包),或已配置 HTTP 代理;
  • 对外服务端口空闲,本篇实测使用 8132:
ss -ltn | grep 8132 || echo 'port 8132 is free'

实测输出(部署前检查,端口空闲):

port 8132 is free
  • 目录规划:整套栈放在 /opt/cacti-stack,其中 cacti/ 存放镜像构建上下文(Dockerfile、config.php、entrypoint.sh),cacti-rra/、cacti-log/、db-data/ 为数据持久化目录。
mkdir -p /opt/cacti-stack/cacti /opt/cacti-stack/cacti-rra /opt/cacti-stack/cacti-log /opt/cacti-stack/db-data
cd /opt/cacti-stack

💡 说明:cacti-rra(RRD 数据文件)、cacti-log(日志)、db-data(数据库目录)三个目录必须落盘持久化,销毁重建服务后监控历史不丢失。

四、部署步骤

本章是全文主线:准备源码包 → 编写四个配置文件 → 构建镜像 → 启动栈 → 首次登录改密 → 走完 Web 安装向导 → 部署验证。每一步都给出实测回显,其中向导阶段的「目录权限」「密码策略」两处坑位附完整排障实录。

4.1 下载官方源码包

Cacti 与 Spine 的发布物托管在 GitHub Releases(cacti.net 下载链接同样指向此处)。下载 1.2.31 的两个源码包并校验 sha256:

cd /opt/cacti-stack/cacti
wget https://github.com/Cacti/cacti/archive/refs/tags/release/1.2.31.tar.gz -O cacti.tar.gz
wget https://github.com/Cacti/spine/archive/refs/tags/release/1.2.31.tar.gz -O spine.tar.gz
sha256sum cacti.tar.gz spine.tar.gz

实测输出:

adc0835ac86169a976094ec550e47a38d048ee6db3bbad96a66bb32761307fc4  cacti.tar.gz
5af0eae3f437134f85ce3429dbc52b1b6a8823c69baae921f33beb07c0e2ad6d  spine.tar.gz

4.2 编写 Dockerfile(构建 Web/轮询机镜像)

该镜像基于 Ubuntu 22.04,一次完成三件事:安装 LAMP 与 SNMP 依赖、解包 Cacti 1.2.31 官方源码、编译 Spine 1.2.31,并设置 PHP 时区与 Apache 站点根。写入 /opt/cacti-stack/cacti/Dockerfile:

FROM ubuntu:22.04

ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Shanghai

RUN apt-get update && apt-get install -y --no-install-recommends \
        apache2 \
        libapache2-mod-php \
        php php-mysql php-gd php-xml php-ldap php-mbstring php-snmp \
        php-curl php-gmp php-intl php-bcmath \
        rrdtool snmp snmpd cron default-mysql-client \
        build-essential libsnmp-dev default-libmysqlclient-dev autoconf automake libtool gawk help2man \
        wget ca-certificates tzdata \
    && rm -rf /var/lib/apt/lists/*

# 官方源码包安装 Cacti 1.2.31
RUN wget -q --tries=10 --waitretry=5 --timeout=60 https://github.com/Cacti/cacti/archive/refs/tags/release/1.2.31.tar.gz -O /tmp/cacti.tar.gz \
    && tar -xzf /tmp/cacti.tar.gz -C /tmp \
    && rm -rf /var/www/html/cacti \
    && mv /tmp/cacti-release-1.2.31 /var/www/html/cacti \
    && rm -f /var/www/html/cacti/index.html \
    && rm -rf /tmp/cacti.tar.gz

# 编译安装 Spine 1.2.31 轮询器
RUN wget -q --tries=10 --waitretry=5 --timeout=60 https://github.com/Cacti/spine/archive/refs/tags/release/1.2.31.tar.gz -O /tmp/spine.tar.gz \
    && tar -xzf /tmp/spine.tar.gz -C /tmp \
    && cd /tmp/spine-release-1.2.31 \
    && mkdir -p config && ./bootstrap && ./configure --prefix=/usr/local/spine \
    && make -j2 && make install \
    && rm -rf /tmp/spine.tar.gz /tmp/spine-release-1.2.31

# PHP 时区与资源设置
RUN sed -i 's/;date.timezone =/date.timezone = Asia\/Shanghai/' /etc/php/8.1/apache2/php.ini \
    && sed -i 's/memory_limit = 128M/memory_limit = 512M/' /etc/php/8.1/apache2/php.ini \
    && sed -i 's/;date.timezone =/date.timezone = Asia\/Shanghai/' /etc/php/8.1/cli/php.ini

# Apache 站点根指向 Cacti 目录
RUN sed -i 's|DocumentRoot /var/www/html|DocumentRoot /var/www/html/cacti|' /etc/apache2/sites-available/000-default.conf \
    && echo "ServerName localhost" >> /etc/apache2/apache2.conf

COPY config.php /var/www/html/cacti/include/config.php
COPY entrypoint.sh /entrypoint.sh

RUN chmod +x /entrypoint.sh \
    && mkdir -p /var/www/html/cacti/rra /var/www/html/cacti/log \
    && chown -R www-data:www-data /var/www/html/cacti/rra /var/www/html/cacti/log \
    && chown www-data:www-data /var/www/html/cacti/include/config.php \
    && echo "*/5 * * * * www-data /usr/bin/php /var/www/html/cacti/poller.php > /dev/null 2>&1" > /etc/cron.d/cacti

EXPOSE 80
ENTRYPOINT ["/entrypoint.sh"]

逐项说明:

  • 依赖包:php-mysql/php-gd/php-xml/php-mbstring/php-snmp/php-curl/php-gmp/php-intl/php-bcmath 是 Cacti 1.2 官方要求的 PHP 扩展集,缺一项向导预检都会标红;rrdtool snmp snmpd 提供绘图与 SNMP 探测命令;default-mysql-client 供启动脚本导入建库 SQL;编译 Spine 需要 build-essential libsnmp-dev default-libmysqlclient-dev autoconf automake libtool gawk help2man;
  • ./bootstrap && ./configure --prefix=/usr/local/spine:Spine 源码不带现成 configure,需先跑 bootstrap 生成,再指定安装前缀;
  • PHP memory_limit 调到 512M:Cacti Web 端在多图表页面内存开销较大,默认 128M 会触顶;
  • cron 条目 */5 * * * * www-data /usr/bin/php /var/www/html/cacti/poller.php:每 5 分钟触发一次轮询,与安装向导第 7 步选择的采集周期一致。

4.3 编写 config.php(数据库连接)

Cacti 的数据库连接配置在 include/config.php,构建时 COPY 进镜像。写入 /opt/cacti-stack/cacti/config.php(保留官方文件头注释略):

$database_type     = 'mysql';
$database_default  = 'cacti';
$database_hostname = 'cacti-db';
$database_username = 'cacti';
$database_password = 'q1w2e3r4';
$database_port     = '3306';
$database_retries  = 5;
$database_ssl      = false;
$database_persist  = false;

$poller_id = 1;

$url_path = '/';

$cacti_session_name = 'Cacti';

逐项说明:

  • $database_hostname = 'cacti-db':即 Compose 里数据库服务的服务名,同网络内容器名即主机名;
  • $poller_id = 1:主站点固定为 1,只有接入分布式远端轮询器时才用别的编号;
  • $url_path = '/':站点根部署(Apache DocumentRoot 已指向 cacti 目录);如果挂在 https://server/cacti/ 子路径下,这里要改成 '/cacti/',且向导预检会校验两者一致性。

4.4 编写 entrypoint.sh(启动脚本)

启动脚本负责等数据库就绪、首次启动导入官方建库 SQL(cacti.sql,随源码包分发)、启动 cron,最后以前台 Apache 结束。写入 /opt/cacti-stack/cacti/entrypoint.sh:

#!/bin/bash
set -e

CACTI_DB_HOST="${CACTI_DB_HOST:-cacti-db}"
CACTI_DB_NAME="${CACTI_DB_NAME:-cacti}"
CACTI_DB_USER="${CACTI_DB_USER:-cacti}"
CACTI_DB_PASS="${CACTI_DB_PASS:-q1w2e3r4}"

echo "[entrypoint] waiting for database ${CACTI_DB_HOST}..."
until mysqladmin ping -h "${CACTI_DB_HOST}" --silent 2>/dev/null; do
    sleep 2
done
echo "[entrypoint] database is up."

TABLES=$(mysql -h "${CACTI_DB_HOST}" -u "${CACTI_DB_USER}" -p"${CACTI_DB_PASS}" "${CACTI_DB_NAME}" -N -e "SHOW TABLES;" 2>/dev/null | wc -l)
if [ "${TABLES}" -eq 0 ]; then
    echo "[entrypoint] importing cacti.sql schema..."
    mysql -h "${CACTI_DB_HOST}" -u "${CACTI_DB_USER}" -p"${CACTI_DB_PASS}" "${CACTI_DB_NAME}" < /var/www/html/cacti/cacti.sql
    echo "[entrypoint] schema imported."
else
    echo "[entrypoint] schema already present (${TABLES} tables), skip import."
fi

service cron start >/dev/null 2>&1 || cron
# 归还挂载目录属主给 Apache 运行用户,避免日志/RRD 无法写入
touch /var/www/html/cacti/log/cacti.log
chown -R www-data:www-data /var/www/html/cacti/log /var/www/html/cacti/rra

exec apache2ctl -D FOREGROUND

要点说明:

  • 建库 SQL 采用「先探表再导入」的幂等设计:数据库为空才导入 cacti.sql(首次启动导入 113 张表),重启或重建服务后跳过,已装数据不受影响。实测两种路径的启动日志见 4.6 与第五章;
  • chmod +x entrypoint.sh 别忘了执行,否则容器无法启动。
chmod +x /opt/cacti-stack/cacti/entrypoint.sh

4.5 编写 docker-compose.yml

写入 /opt/cacti-stack/docker-compose.yml,定义 db、web 两个服务与自定义网络:

name: cacti-1-2-31-stack

services:
  cacti-db:
    image: mariadb:10.6
    container_name: cacti-1.2.31-db
    hostname: cacti-db
    restart: unless-stopped
    environment:
      MARIADB_ROOT_PASSWORD: "q1w2e3r4"
      MARIADB_DATABASE: "cacti"
      MARIADB_USER: "cacti"
      MARIADB_PASSWORD: "q1w2e3r4"
      TZ: "Asia/Shanghai"
    command:
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci
      --max_connections=200
      --innodb_buffer_pool_size=256M
      --innodb_flush_log_at_trx_commit=2
      --tmp_table_size=64M
      --max_heap_table_size=64M
    volumes:
      - ./db-data:/var/lib/mysql
    networks:
      - cacti-net
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 10

  cacti-web:
    build:
      context: ./cacti
      args:
        - http_proxy=http://192.168.1.62:7897
        - https_proxy=http://192.168.1.62:7897
    image: cacti-1.2.31-web:local
    container_name: cacti-1.2.31-web
    hostname: cacti-web
    restart: unless-stopped
    depends_on:
      cacti-db:
        condition: service_healthy
    environment:
      TZ: "Asia/Shanghai"
      CACTI_DB_HOST: "cacti-db"
      CACTI_DB_NAME: "cacti"
      CACTI_DB_USER: "cacti"
      CACTI_DB_PASS: "q1w2e3r4"
    ports:
      - "8132:80"
    volumes:
      - ./cacti-rra:/var/www/html/cacti/rra
      - ./cacti-log:/var/www/html/cacti/log
    networks:
      - cacti-net

networks:
  cacti-net:
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.59.0/24
          gateway: 10.89.59.1

逐项说明:

  • name: cacti-1-2-31-stack:显式指定 Compose 项目名,避免多套栈同目录名时误操作;
  • MariaDB 启动参数:Cacti 1.2 官方要求数据库字符集 utf8mb4(向导第 9 步会校验服务器与库的 collation),innodb_buffer_pool_size=256M 适配 4 GB 内存机型,innodb_flush_log_at_trx_commit=2 用每秒刷盘换取轮询批量写入性能;
  • healthcheck + depends_on.condition: service_healthy:保证 web 启动时数据库已可连接,避免首次导入 SQL 失败;
  • 构建代理 args: http_proxy/https_proxy:仅在构建环境需要代理访问 GitHub 时保留,直连环境删除这两行即可;
  • 固定子网 10.89.59.0/24:按团队内网段规划显式指定,避免与既有网络段冲突(无此需求可整段删除 ipam 配置)。

4.6 构建镜像并启动栈

首次执行会完整构建 Web 镜像(下载依赖 + 编译 Spine,视网络约 5–15 分钟),随后创建并启动两个服务:

cd /opt/cacti-stack
docker compose up -d --build

实测输出(构建收尾与启动节选,实测首尾):

#15 exporting manifest sha256:6ceba946e2b6aa4fddae7ae70c122358a4c0310d5d49047371a3dd1adf6deb35 done
#15 naming to docker.io/library/cacti-1.2.31-web:local done
#15 unpacking to docker.io/library/cacti-1.2.31-web:local 2.4s done
#15 DONE 12.1s

#16 resolving provenance for metadata file
#16 DONE 0.0s
 Image cacti-1.2.31-web:local Built
 Container cacti-1.2.31-db Starting
 Container cacti-1.2.31-db Started
 Container cacti-1.2.31-db Waiting
 Container cacti-1.2.31-db Healthy
 Container cacti-1.2.31-web Starting
 Container cacti-1.2.31-web Started

验证两个服务状态:

docker compose ps

实测输出:

NAME               IMAGE                    COMMAND                   SERVICE     CREATED       STATUS                 PORTS
cacti-1.2.31-db    mariadb:10.6             "docker-entrypoint.s…"   cacti-db    2 hours ago   Up 2 hours (healthy)   3306/tcp
cacti-1.2.31-web   cacti-1.2.31-web:local   "/entrypoint.sh"          cacti-web   2 hours ago   Up 2 hours             0.0.0.0:8132->80/tcp, [::]:8132->80/tcp

查看 Web 服务启动日志,确认建库 SQL 导入完成:

docker logs cacti-1.2.31-web 2>&1 | head -8

实测输出(首次启动):

[entrypoint] waiting for database cacti-db...
[entrypoint] database is up.
[entrypoint] importing cacti.sql schema...
[entrypoint] schema imported.

此时代理 http://<服务器IP>:8132/ 已可访问,但会 302 跳转到 /install/ 安装向导(数据库 schema 已就绪、应用尚未完成安装声明),进入 4.7 走完向导。

4.7 首次登录与强制改密

浏览器打开 http://<服务器IP>:8132/,进入 Cacti 登录页。全新安装的默认管理员账号为 admin,初始密码 admin:

  • Username:admin
  • Password:admin

登录成功后立即跳转「Change Password」强制改密页(Cacti 默认策略强制初始密码必须更换)。

⚠️ 排障实录:直接把新密码设为演示口令 q1w2e3r4 会被默认密码策略拒绝,实测报错原文:

Your password must contain a mix of lower case and upper case characters!

原因:Cacti 默认开启三类密码复杂度要求(大小写混合 secpass_reqmixcase、必须含数字 secpass_reqnum、必须含特殊字符 secpass_reqspec,最小长度 8 位,见 Configuration → Settings → Authentication 页签)。解决方式二选一:

  1. 按策略改用强密码(如 Q1w2E3r4!);
  2. 在 Configuration → Settings → Authentication 中关闭「Require Mixed Case Password」与「Require Special Character」两项(对应 settings 表 secpass_reqmixcase、secpass_reqspec 置空),再改回统一演示口令 q1w2e3r4。本篇实测环境采用方式 2,以统一演示口令完成后续验证。

改密完成后回到登录页,用 admin / q1w2e3r4 重新登录。

4.8 Web 安装向导(共 10 步)

登录后自动进入安装向导(http://<服务器IP>:8132/install/),共 10 个确认页 + 1 个后台安装过程。逐步骤实录如下:

步骤页面标题关键操作与实测内容
1Cacti Version 1.2.31 - License Agreement勾选接受 GPL 许可(Accept GPL License),Next
2Pre-installation Checks自动预检:MySQL/MariaDB 支持、XML、GD、SNMP、Socket、Session、DOM 等,全部绿色 Pass 后 Next
3Installation Type选择「New Primary Server」(新主站点,同时承担 Web 与轮询);远端采集器场景才选 New Remote Data Collector
4Directory Permission Checks校验 RRD/日志/缓存/脚本目录可写性,首跑会有 8 项 Not Writable,见下方排障实录
5Critical Binary Locations and Versions自动探测二进制路径:PHP /usr/bin/php、RRDtool /usr/bin/rrdtool(版本 1.7.2 识别通过)、snmpget /usr/bin/snmpget、Spine /usr/local/spine/bin/spine,确认无误后 Next
6Input Validation Whitelist Protection输入校验白名单保护说明页,确认 Next
7Default Profile选择默认采集配置档:5 Minute Collection(300 秒轮询/600 秒心跳,推荐起步)或 1 Minute/30 Second,Next
8Template Setup勾选要预装的设备模板包(默认全选),Next
9Server Collation / Database Collation校验服务器与库的字符集为 UTF8 兼容(compose 已显式 utf8mb4,实测显示 compliant),Next
10Confirm Installation确认页,勾选确认后点击 Install 开始安装

⚠️ 排障实录(第 4 步目录权限):首次走到「Directory Permission Checks」时,向导实测报出以下 8 项 Not Writable,Next 按钮不可用:

Required Writable at Install Time Only
/var/www/html/cacti/resource/snmp_queries/    Not Writable
/var/www/html/cacti/resource/script_server/   Not Writable
/var/www/html/cacti/resource/script_queries/  Not Writable
/var/www/html/cacti/scripts/                  Not Writable
Required Writable after Install Complete
/var/www/html/cacti/cache/boost/      Not Writable
/var/www/html/cacti/cache/mibcache/   Not Writable
/var/www/html/cacti/cache/realtime/   Not Writable
/var/www/html/cacti/cache/spikekill/  Not Writable

原因:源码包解包出来的目录属主是 root,Apache 运行用户(www-data)写不进去。定位后在 Web 服务机执行属主修复,然后回到向导刷新该页:

chown -R www-data:www-data \
  /var/www/html/cacti/resource/snmp_queries \
  /var/www/html/cacti/resource/script_server \
  /var/www/html/cacti/resource/script_queries \
  /var/www/html/cacti/scripts \
  /var/www/html/cacti/cache/boost \
  /var/www/html/cacti/cache/mibcache \
  /var/www/html/cacti/cache/realtime \
  /var/www/html/cacti/cache/spikekill

修复后第 4 步全部 Writable,Next 恢复可用。注意 /tmp/、/var/www/html/cacti/log/、rra/ 三项由 entrypoint 启动脚本负责属主,实测无需手动处理。

第 10 步确认后进入「Installing Cacti Server v1.2.31」后台安装页(向导自动轮询进度),约 20 秒后完成。安装过程落库实测回显(安装日志):

2026-10-20 11:15:59 - INSTALL: always: Generating RSA Key Pair
2026-10-20 11:15:59 - INSTALL: always: Finished INSTALL Process for v1.2.31
2026-10-20 11:15:59 - INSTALL-SYNC: always: Found 0 poller(s) to sync
2026-10-20 11:15:59 - INSTALL-SYNC: always: No Remote Data Collectors found for full synchronization
2026-10-20 11:15:59 - INSTALL: always: Installation was started at 2026-10-20 03:15:40, completed at 2026-10-20 03:15:59

💡 说明:向导在后台做了大量初始化——实测导入后库内设备模板 15 个、图形模板 208 个、数据模板 277 个,并生成 RSA 密钥对供分布式组件通信用。这些模板是后续添加设备出图的基础。

4.9 部署验证

三重验证确认部署成功:应用版本、登录控制台、轮询统计。

验证一:应用版本与安装完成标记(数据库侧实查):

SELECT * FROM version;
SELECT name,value FROM settings WHERE name IN ('install_complete','poller_type','path_spine');

实测输出:

cacti
1.2.31
name              value
install_complete  1792466159.637
poller_type       2
path_spine        /usr/local/spine/bin/spine

poller_type = 2 表示轮询方式已选为 Spine(1 为 cmd.php),向导会依据第 5 步探测到的 Spine 路径自动切换。

验证二:登录控制台。浏览器访问 http://<服务器IP>:8132/,用 admin / q1w2e3r4 登录,应直接进入 Console 控制台首页(页面含 Graphs/Console 两个主菜单,右上角出现 logout 入口)。

验证三:Spine 轮询统计。轮询由 cron 每 5 分钟触发,查看运行日志中的统计行:

grep "SYSTEM STATS" /var/www/html/cacti/log/cacti.log | tail -2

实测输出:

10/20/2026 11:10:01 - SYSTEM STATS: Time:299.4660 Method:spine Processes:1 Threads:1 Hosts:1 HostsPerProcess:1 DataSources:0 RRDsProcessed:0
10/20/2026 11:15:00 - SYSTEM STATS: Time:298.4601 Method:spine Processes:1 Threads:1 Hosts:1 HostsPerProcess:1 DataSources:0 RRDsProcessed:0

Method:spine 证明 Spine 轮询器已生效,Hosts:1 是安装时默认创建的 Localhost 设备(当前 0 个数据源属正常,添加监控设备后 DataSources 与 RRDsProcessed 随之增长)。后续添加设备与出图属使用范畴,见《Cacti 1.2.31 常用 CLI 命令详解》的 add_device/add_graphs 实战。

五、数据持久化说明

Cacti 的状态数据分布在三处,均已通过 bind mount 落盘到 Compose 目录,销毁服务不丢数据:

宿主目录容器内路径内容说明
./db-data/var/lib/mysqlMariaDB 数据目录设备/模板/图形索引/用户等全部元数据,最重要
./cacti-rra/var/www/html/cacti/rraRRD 环形数据库文件所有监控采样数据,出图的数据本体
./cacti-log/var/www/html/cacti/logCacti 运行日志cacti.log 轮询日志、Web 请求日志

持久化验证实测:安装完成并登录成功后整栈 down 再 up,验证数据完好:

docker compose down
docker compose up -d

实测输出:

 Container cacti-1.2.31-db Stopping
 Container cacti-1.2.31-db Stopped
 Container cacti-1.2.31-db Removing
 Container cacti-1.2.31-db Removed
 Network compose_cacti-net Removing
 Network compose_cacti-net Removed
 Container cacti-1.2.31-db Starting
 Container cacti-1.2.31-db Started
 Container cacti-1.2.31-db Waiting
 Container cacti-1.2.31-db Healthy
 Container cacti-1.2.31-web Starting
 Container cacti-1.2.31-web Started

重建后验证三项:entrypoint 跳过建库导入、管理员可正常登录、安装标记仍在。

docker logs cacti-1.2.31-web 2>&1 | head -3
curl -s -o /dev/null -w 'GET / -> %{http_code}\n' http://localhost:8132/

实测输出:

[entrypoint] waiting for database cacti-db...
[entrypoint] database is up.
[entrypoint] schema already present (113 tables), skip import.
GET / -> 200

schema already present (113 tables), skip import. 证明幂等生效;GET / -> 200(不再是安装前的 302 跳转 /install/)证明安装状态与账号数据完好。

⚠️ 注意:db-data 目录由 MariaDB 官方镜像初始化生成,首次启动前保持为空目录即可;不要把宿主已有文件误放进该目录,否则数据库无法初始化。

六、环境变量表

Compose 通过环境变量向两个服务注入配置。实测取值如下:

6.1 cacti-web(Web/轮询机)

变量实测取值作用
TZAsia/Shanghai容器系统时区,影响轮询日志时间戳
CACTI_DB_HOSTcacti-db数据库主机名(entrypoint 探活与 config.php 缺省值用)
CACTI_DB_NAMEcacti数据库名
CACTI_DB_USERcacti数据库业务账号
CACTI_DB_PASSq1w2e3r4数据库业务账号密码

6.2 cacti-db(数据库)

变量实测取值作用
MARIADB_ROOT_PASSWORDq1w2e3r4数据库 root 密码
MARIADB_DATABASEcacti首次启动自动创建的库
MARIADB_USERcacti首次启动自动创建的业务账号
MARIADB_PASSWORDq1w2e3r4业务账号密码
TZAsia/Shanghai数据库时区

💡 说明:CACTI_DB_* 变量由 entrypoint.sh 在启动时读取(探活与导入 SQL),Cacti 应用本身的连接参数以 include/config.php 为准,两处需保持一致。

七、配置参数说明

本章解读 compose 与 Cacti 侧两类关键参数,便于按规模调整。

7.1 数据库参数

参数实测取值说明与调整建议
--character-set-server=utf8mb4utf8mb4Cacti 1.2 强制要求,向导第 9 步校验,勿改
--collation-server=utf8mb4_unicode_ciutf8mb4_unicode_ci与字符集配套
--max_connections=200200轮询器 + Web 并发连接,中大规模(>5 千数据源)可升 300
--innodb_buffer_pool_size=256M256M4 GB 内存机型取值;专机 8 GB 可取 1G
--innodb_flush_log_at_trx_commit=22每秒刷盘,监控场景可接受,明显降低写入延迟
--tmp_table_size / --max_heap_table_size64M图表聚合查询的临时表上限

7.2 Cacti 应用参数(config.php)

参数实测取值说明
$database_hostnamecacti-db数据库地址,Compose 网络内用服务名
$database_port3306数据库端口
$database_retries5连接重试次数
$poller_id1主站点轮询器编号,远端采集器从 2 起编
$url_path/站点 URL 前缀,子路径部署需与实际一致
$cacti_db_sessionfalse会话入库开关,多 Web 负载均衡时才开启

更多运行期参数(轮询并发、日志级别、模板等)的逐项详解见《Cacti 1.2.31 配置参数详解》。

八、配置文件挂载

本篇把 config.php 在构建阶段 COPY 进镜像,适合配置稳定的场景;若希望不改镜像改配置,可改为 bind mount 方式:

    volumes:
      - ./cacti-config.php:/var/www/html/cacti/include/config.php
      - ./cacti-rra:/var/www/html/cacti/rra
      - ./cacti-log:/var/www/html/cacti/log

切换挂载方式后需 docker compose up -d --force-recreate cacti-web 重建生效。实测提示:挂载的 config.php 属主需为 www-data,否则 Web 页面会报配置文件不可读。

RRD 与日志目录(cacti-rra、cacti-log)无论哪种方式都必须挂载——这是监控数据的本体,重建镜像不能丢。entrypoint 启动时会把这两个目录属主归还给 www-data(实测日志见第五章启动输出),因此宿主侧目录无需预设权限。

九、等价 docker run

不用 Compose 时,等价的裸 docker 命令如下(先建网络,再起数据库,最后起 Web):

docker network create --driver bridge --subnet 10.89.59.0/24 --gateway 10.89.59.1 cacti-net

docker run -d --name cacti-1.2.31-db --hostname cacti-db --network cacti-net \
  --restart unless-stopped \
  -e MARIADB_ROOT_PASSWORD=q1w2e3r4 \
  -e MARIADB_DATABASE=cacti \
  -e MARIADB_USER=cacti \
  -e MARIADB_PASSWORD=q1w2e3r4 \
  -e TZ=Asia/Shanghai \
  -v /opt/cacti-stack/db-data:/var/lib/mysql \
  mariadb:10.6 \
  --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci \
  --max_connections=200 --innodb_buffer_pool_size=256M \
  --innodb_flush_log_at_trx_commit=2 --tmp_table_size=64M --max_heap_table_size=64M

docker run -d --name cacti-1.2.31-web --hostname cacti-web --network cacti-net \
  --restart unless-stopped \
  -e TZ=Asia/Shanghai \
  -e CACTI_DB_HOST=cacti-db -e CACTI_DB_NAME=cacti \
  -e CACTI_DB_USER=cacti -e CACTI_DB_PASS=q1w2e3r4 \
  -p 8132:80 \
  -v /opt/cacti-stack/cacti-rra:/var/www/html/cacti/rra \
  -v /opt/cacti-stack/cacti-log:/var/www/html/cacti/log \
  cacti-1.2.31-web:local

等价性说明:裸 docker run 需要自己保证数据库先就绪(Compose 的 depends_on: service_healthy 在此由 entrypoint 的探活循环兜底),且 cron 轮询、健康检查等编排能力不再自动管理,生产环境建议仍用 Compose。

十、常用运维命令

日常运维围绕 Compose 展开,以下命令均在实测环境验证:

cd /opt/cacti-stack

# 查看服务状态
docker compose ps

# 查看 Web 服务日志(启动/导入/报错)
docker logs --tail 50 cacti-1.2.31-web

# 重启单个服务(改 config.php 后)
docker compose restart cacti-web

# 重建并启动(改 Dockerfile / compose 后)
docker compose up -d --build

# 临时停栈(保留数据目录)
docker compose down

# 停栈并清理数据目录(危险,监控历史全丢,先备份)
docker compose down
rm -rf db-data cacti-rra cacti-log

数据库备份示例(RRD 文件直接 tar 打包即可):

docker exec cacti-1.2.31-db sh -c 'mariadb-dump -ucacti -pq1w2e3r4 cacti' > cacti-db-$(date +%F).sql
tar -czf cacti-rra-$(date +%F).tar.gz cacti-rra

💡 说明:Cacti 的完整备份 = 数据库转储 + rra 目录 + include/config.php,三者齐备即可在任何新机重建。

十一、常见问题

Q1:向导第 4 步目录权限检查 Not Writable,Next 灰色无法继续?

源码包解出目录属 root,Apache 用户写不进 cache/resource/scripts 等 8 个目录。执行 4.8 排障实录中的 chown 命令后刷新向导页即可,实测修复后全部 Writable。

Q2:首次登录改密时报「Your password must contain a mix of lower case and upper case characters!」?

Cacti 默认密码策略要求大小写混合、含数字、含特殊字符。要么按策略设强密码,要么在 Configuration → Settings → Authentication 关闭对应复杂度项(settings 表 secpass_reqmixcase、secpass_reqspec)。实测过程见 4.7。

Q3:访问 8132 端口一直 302 跳转 /install/,向导走完了还是跳?

302 跳 /install/ 说明 install_complete 未落库(向导没走完或中途刷新丢了进度)。重新登录后访问 /install/ 继续向导即可;判断标记:数据库 settings 表出现 install_complete 行(实测值 1792466159.637)。

Q4:轮询没跑,图形一直空?

排查三处:cron 是否注册(cat /etc/cron.d/cacti 应有 */5 * * * * www-data /usr/bin/php /var/www/html/cacti/poller.php);轮询日志是否有 SYSTEM STATS 行;设备是否启用且 SNMP 连通。日志路径 /var/www/html/cacti/log/cacti.log。

Q5:重建服务后报数据库连接失败?

确认 config.php 的 $database_hostname 与 Compose 服务名一致(cacti-db),且两个服务在同一网络。跨 compose 网络或改名后未同步配置是最常见原因。

Q6:向导第 2 步预检某 PHP 扩展标红?

对照 4.2 Dockerfile 的扩展清单补装(缺哪个装哪个,如缺 GD 装 php-gd),重跑 docker compose up -d --build 后再进向导。Cacti 1.2 必需扩展:mysql、gd、xml、mbstring、snmp、curl、gmp、intl、bcmath、ldap、sockets。

十二、参考链接