How to Self-Host Cacti with Docker Compose
Docker Compose Configuration
Cacti does not have an official Docker image — the project predates Docker conventions. The most reliable community image is smcline06/cacti, which bundles Apache, PHP, Spine poller, and SNMP tools into a single container alongside a MariaDB database.
Create a docker-compose.yml file:
services:
cacti:
image: smcline06/cacti:1.2.17
container_name: cacti
restart: unless-stopped
ports:
- "8443:443"
- "8080:80"
environment:
# Database connection
DB_NAME: cacti_master
DB_USER: cactiuser
DB_PASS: "${DB_PASSWORD}"
DB_HOST: cacti-db
DB_PORT: "3306"
DB_ROOT_PASS: "${DB_ROOT_PASSWORD}"
# Auto-create database on first boot
INITIALIZE_DB: "1"
# Timezone (must match PHP and MariaDB)
TZ: "UTC"
volumes:
- cacti_data:/var/www/html/cacti
- cacti_spine:/var/www/html/spine
- cacti_backups:/var/www/html/backups
depends_on:
cacti-db:
condition: service_healthy
networks:
- cacti
cacti-db:
image: mariadb:11.4.10
container_name: cacti-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: "${DB_ROOT_PASSWORD}"
MYSQL_DATABASE: cacti_master
MYSQL_USER: cactiuser
MYSQL_PASSWORD: "${DB_PASSWORD}"
volumes:
- cacti_db:/var/lib/mysql
command: >
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
--max_connections=200
--max_heap_table_size=256M
--tmp_table_size=256M
--innodb_buffer_pool_size=1G
--innodb_doublewrite=OFF
--innodb_flush_log_at_timeout=3
--innodb_read_io_threads=32
--innodb_write_io_threads=16
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 30s
timeout: 10s
retries: 5
start_period: 60s
networks:
- cacti
networks:
cacti:
driver: bridge
volumes:
cacti_data:
cacti_spine:
cacti_backups:
cacti_db:
Create a .env file alongside:
# CHANGE THESE — use strong, unique passwords
DB_PASSWORD=change_me_strong_password_here
DB_ROOT_PASSWORD=change_me_root_password_here
Start the stack:
docker compose up -d
What Is Cacti?
Cacti is an RRDtool-based network graphing platform that polls SNMP-enabled devices on a schedule and renders the data as graphs. It’s been the go-to SNMP graphing solution since 2001, used primarily for monitoring bandwidth utilization on switches, routers, and servers. Think of it as a web frontend for RRDtool with built-in SNMP polling, device management, and user access control. Official site
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended)
- Docker and Docker Compose installed (guide)
- 2 GB of RAM minimum (4 GB recommended for 100+ devices)
- 10 GB of free disk space
- Network devices with SNMP enabled (v2c or v3)
- A domain name (optional, for remote access)
Initial Setup
- First boot takes 5–10 minutes while the database schema imports. Watch progress:
docker compose logs -f cacti - Open
https://your-server-ip:8443/cactiin your browser (HTTPS with self-signed cert). - Accept the license agreement.
- The installer checks PHP dependencies, database connectivity, and file permissions. All should pass with the Docker image.
- Select New Primary Server installation type.
- Log in with default credentials:
admin/admin. You’ll be prompted to change the password immediately.
Add Your First Device
- Go to Management → Devices → Add
- Enter the device IP and SNMP community string (default:
public) - Select a device template (e.g., Cisco Router, Linux Server, Net-SNMP Device)
- Click Create and wait for Cacti to query the device
- Once SNMP data is confirmed, go to Create → New Graphs and select the interfaces you want to graph
Configuration
Spine Poller
Cacti’s default poller (cmd.php) is slow — it polls devices sequentially. The Spine poller (included in the Docker image) polls in parallel using multithreaded C code.
Enable Spine:
- Go to Configuration → Settings → Poller
- Change Poller Type to spine
- Set Maximum Concurrent Poller Processes based on your CPU cores (4–8 is typical)
- Cacti polls every 5 minutes by default — this is the standard RRDtool interval
SNMP v3 Configuration
For secure SNMP polling:
- When adding a device, select SNMP Version 3
- Configure:
- Security Level: authPriv (recommended)
- Auth Protocol: SHA
- Auth Passphrase: your SNMP v3 auth password
- Privacy Protocol: AES
- Privacy Passphrase: your SNMP v3 privacy password
Graph Templates
Cacti ships with templates for common metrics:
- Interface traffic (in/out bytes, errors, discards)
- CPU utilization (via Host MIB)
- Memory usage (via Host MIB)
- Disk space (via Host MIB)
- Temperature sensors (via Entity Sensor MIB)
For custom OIDs, create a Data Query or Data Template under Configuration → Data Queries.
Advanced Configuration
Threshold Alerting (Thold Plugin)
Cacti doesn’t include alerting out of the box — you need the Thold plugin:
- Go to Configuration → Plugins → Install/Enable Thold
- Create threshold: Management → Thresholds → Add
- Set high/low watermarks for bandwidth, CPU, etc.
- Configure email notifications in Configuration → Settings → Mail/DNS
Remote Pollers
For monitoring devices across multiple sites:
services:
cacti-remote:
image: smcline06/cacti:1.2.17
environment:
REMOTE_POLLER: "1"
DB_HOST: central-db-host
RDB_HOST: central-db-host
# ... remote database credentials
Remote pollers report back to the central Cacti instance, enabling distributed monitoring.
Weathermap Plugin
Visualize network topology with live bandwidth overlays:
- Install the Weathermap plugin via Cacti’s plugin management
- Create network maps showing device interconnections
- Associate graph data sources with map links
- Maps update automatically with each polling cycle
Reverse Proxy
The Docker image includes Apache with a self-signed certificate. For proper TLS:
server {
listen 443 ssl;
server_name cacti.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/cacti.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cacti.yourdomain.com/privkey.pem;
location / {
proxy_pass https://127.0.0.1:8443;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Backup
Cacti stores data in two locations:
- MariaDB — device configurations, user accounts, graph templates, thresholds
- RRD files — historical graph data (in the
cacti_datavolume underrra/)
# Backup database
docker exec cacti-db mariadb-dump -u root -p"${DB_ROOT_PASSWORD}" cacti_master > cacti-db-backup.sql
# Backup RRD files and configs
docker cp cacti:/var/www/html/cacti/rra ./cacti-rra-backup
docker cp cacti:/var/www/html/cacti/scripts ./cacti-scripts-backup
RRD files are compact (fixed-size, typically 100–500 KB per data source) and are the most important data to preserve.
Troubleshooting
Graphs show “No data” or are blank
Symptom: Device added and SNMP works, but graphs remain empty. Fix: Wait at least two polling cycles (10 minutes with default 5-minute interval). RRDtool requires two data points to draw a line. If still blank, check that the correct data query was associated with the device and that SNMP community string matches.
Spine poller not running
Symptom: Poller set to Spine but polling is slow or not happening. Fix: Verify Spine binary exists and is executable:
docker exec cacti which spine
docker exec cacti spine --version
Check cron is running inside the container: docker exec cacti crontab -l
SNMP timeouts
Symptom: Devices show “SNMP error” or “Down” status. Fix: Test SNMP from inside the container:
docker exec cacti snmpwalk -v2c -c public DEVICE_IP sysDescr.0
If this fails, the issue is network connectivity or SNMP configuration on the device. Ensure UDP port 161 is accessible from the container.
Database connection errors on startup
Symptom: Cacti container fails to start, logs show database connection refused.
Fix: The depends_on with service_healthy ensures MariaDB is ready, but if the healthcheck fails, verify the database passwords match between the Cacti and MariaDB containers. Check MariaDB logs: docker compose logs cacti-db
High CPU during polling
Symptom: CPU spikes every 5 minutes during poll cycle. Fix: Reduce Maximum Concurrent Poller Processes in Spine settings. For a 2-core VPS, set to 2–4 threads. Also verify you’re using Spine, not cmd.php — PHP polling is significantly more CPU-intensive.
Resource Requirements
| Metric | Value |
|---|---|
| RAM (idle) | ~300 MB (Cacti + MariaDB) |
| RAM (100 devices) | ~800 MB |
| RAM (500+ devices) | 2–4 GB |
| CPU | Low (spikes during polling cycles) |
| Disk per device | ~5–50 MB (RRD files, depends on data sources) |
| Minimum total disk | 10 GB |
RRD files are inherently space-efficient — they use fixed-size round-robin databases that automatically consolidate old data. A Cacti instance monitoring 100 switches with 20 interfaces each uses roughly 2–5 GB of RRD storage total, regardless of how long it’s been running.
Verdict
Cacti does one thing well: SNMP-based network graphing. If your primary need is monitoring bandwidth utilization across switches and routers with beautiful RRDtool graphs, Cacti delivers with minimal resource overhead. The Spine poller handles large-scale polling efficiently, and the fixed-size RRD storage model means disk usage stays predictable.
For new deployments in 2026, consider whether Zabbix or LibreNMS would serve you better — both offer SNMP graphing plus alerting, auto-discovery, and modern web interfaces. Cacti’s strength is its simplicity and 20+ years of proven reliability. If you don’t need alerting or auto-discovery, Cacti remains a perfectly valid choice that runs on minimal hardware.
FAQ
Is Cacti still maintained?
Yes, but development is slow. The community Docker image (smcline06/cacti) was last updated in 2021 with version 1.2.17. The upstream Cacti project continues receiving patches, but the Docker ecosystem lags behind significantly. Major new features are rare.
Can Cacti monitor things besides SNMP?
Yes, through custom data input methods and scripts. You can create scripts that query any data source (APIs, databases, files) and feed the results into RRDtool via Cacti’s data input system. But SNMP polling is the core strength.
Why is there no official Docker image?
Cacti predates modern Docker practices. The project maintains installation guides for bare-metal Linux but hasn’t invested in official container images. Community images like smcline06/cacti fill this gap reliably.
How does Cacti compare to LibreNMS?
LibreNMS is the modern successor to the same concept — SNMP-based network monitoring with auto-discovery, alerting, and a modern web UI. LibreNMS is the better choice for new deployments. See our Zabbix vs Cacti comparison for a detailed breakdown.
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments