How to Self-Host Netdata: Real-Time Infrastructure Monitoring 2026
TL;DR
Netdata (GPL 3.0, ~69K GitHub stars, C) is the most comprehensive real-time infrastructure monitoring tool available. It collects 1-second resolution metrics for CPU, memory, disk, network, processes, containers, databases, and 800+ other systems — and streams them to a beautiful web dashboard with zero configuration. Unlike Prometheus (pull-based), Netdata agents push metrics in real-time. Run it on any server for instant observability with no setup beyond docker compose up.
Key Takeaways
- Netdata: GPL 3.0, ~69K stars, C — 1-second per-metric resolution, 800+ collectors
- Zero config: Automatically detects and monitors MySQL, PostgreSQL, Redis, Nginx, Docker, etc.
- Anomaly detection: ML-based anomaly detection on every metric, no configuration needed
- Alerts: Built-in alert conditions for common failure patterns with notifications
- Distributed: Each agent is standalone; use Netdata Parents for centralized multi-host view
- vs Prometheus+Grafana: Netdata is turnkey; Prometheus is more customizable but needs configuration
Netdata vs Prometheus+Grafana vs Zabbix
| Feature | Netdata | Prometheus+Grafana | Zabbix |
|---|---|---|---|
| License | GPL 3.0 | Apache 2.0 | AGPL 2.0 |
| Setup time | Minutes | Hours | Hours |
| Resolution | 1 second | 15s default | 1 minute |
| Auto-discovery | Yes (800+ collectors) | Manual scrape config | Agent-based |
| Anomaly detection | Yes (ML, built-in) | Manual rules | Trigger-based |
| Long-term storage | 1 month (local) | Forever (disk) | DB-based |
| Dashboards | Built-in | Grafana required | Built-in |
| Alerting | Built-in | Alertmanager | Built-in |
| Agent RAM | ~100MB | ~50MB | ~200MB |
Part 1: Docker Setup
Single-node monitoring
# docker-compose.yml
services:
netdata:
image: netdata/netdata:latest
container_name: netdata
restart: unless-stopped
pid: host
network_mode: host # Required for full network monitoring
cap_add:
- SYS_PTRACE
- SYS_ADMIN
security_opt:
- apparmor:unconfined
volumes:
- netdataconfig:/etc/netdata
- netdatalib:/var/lib/netdata
- netdatacache:/var/cache/netdata
- /etc/passwd:/host/etc/passwd:ro
- /etc/group:/host/etc/group:ro
- /etc/localtime:/etc/localtime:ro
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /etc/os-release:/host/etc/os-release:ro
- /var/log:/host/var/log:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
NETDATA_CLAIM_TOKEN: "${NETDATA_CLAIM_TOKEN}" # Optional: Netdata Cloud claim
NETDATA_CLAIM_URL: "https://app.netdata.cloud"
NETDATA_CLAIM_ROOMS: "${NETDATA_CLAIM_ROOMS}"
volumes:
netdataconfig:
netdatalib:
netdatacache:
docker compose up -d
Visit http://your-server:19999 — the Netdata dashboard loads immediately.
Note:
network_mode: hostis needed for Netdata to see host network interfaces and monitor processes properly. Port 19999 is exposed by default.
Part 2: HTTPS with Caddy
Since Netdata uses network_mode: host, it's already on port 19999. Add a Caddy reverse proxy on the same host:
metrics.yourdomain.com {
reverse_proxy localhost:19999
}
Access Control
Netdata is open by default. Restrict access:
# Edit netdata.conf:
docker exec -it netdata sh
vi /etc/netdata/netdata.conf
# Add:
[web]
allow connections from = localhost 192.168.0.0/24 10.0.0.0/8
Or restrict entirely and access only via Caddy with basic auth:
metrics.yourdomain.com {
basicauth {
admin $2a$14$hashofyourpassword
}
reverse_proxy localhost:19999
}
Part 3: Auto-Detected Collectors
Netdata automatically detects and configures:
| Service | What it monitors |
|---|---|
| Docker | Container CPU, memory, network, I/O |
| PostgreSQL | Queries/sec, connections, replication lag, table bloat |
| MySQL/MariaDB | Queries, threads, InnoDB metrics |
| Redis | Operations/sec, memory, hit rate, keyspace |
| Nginx | Requests/sec, connections, response codes |
| Node.js | Event loop lag, heap, GC (via node_exporter) |
| systemd | Service status, CPU, memory per service |
| Disk | IOPS, latency, utilization per device |
| Network | Packets/sec, bandwidth, errors per interface |
| CPU | Per-core utilization, interrupts, softirqs |
No configuration needed — Netdata finds running services automatically.
Part 4: Custom Alerts
Default alerts cover common failure scenarios. Add custom ones:
# Edit alerts:
docker exec -it netdata sh
vi /etc/netdata/health.d/custom.conf
# Alert if disk usage > 85%:
alarm: disk_space_warning
on: disk.space
os: linux
lookup: average -10m unaligned of used
calc: $this * 100 / ($used + $avail)
every: 1m
warn: $this > 85
crit: $this > 95
info: disk ${label:mount_point} space utilization
delay: down 5m multiplier 1.5 max 1h
to: sysadmin
# Alert if PostgreSQL has too many connections:
alarm: pg_connections_warning
on: postgres.connections
lookup: average -5m unaligned
every: 1m
warn: $this > 80
crit: $this > 95
info: PostgreSQL active connections
to: dba
Part 5: Notifications
Configure alert notifications:
# Edit notifications:
docker exec -it netdata vi /etc/netdata/health_alarm_notify.conf
# Slack:
SEND_SLACK="YES"
SLACK_WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
DEFAULT_RECIPIENT_SLACK="#alerts"
# Telegram:
SEND_TELEGRAM="YES"
TELEGRAM_BOT_TOKEN="your-bot-token"
DEFAULT_RECIPIENT_TELEGRAM="your-chat-id"
# ntfy:
SEND_NTFY="YES"
NTFY_URL="https://ntfy.yourdomain.com"
DEFAULT_RECIPIENT_NTFY="alerts"
# PagerDuty:
SEND_PAGERDUTY="YES"
PAGERDUTY_SERVICE_KEY="your-service-key"
Part 6: Distributed Multi-Server Setup
Monitor multiple servers from one UI using Netdata Parents:
On the parent server
# docker-compose.yml on parent server
environment:
# Allow children to connect:
NETDATA_ALLOW_CONNECTIONS_FROM: "10.0.0.0/8 192.168.0.0/24"
On each child server
# stream.conf on each agent:
docker exec -it netdata vi /etc/netdata/stream.conf
[stream]
enabled = yes
destination = parent.yourdomain.com:19999
api key = your-api-key # Same on parent's netdata.conf
[parent.yourdomain.com:19999]
enabled = yes
api key = your-api-key
All child server metrics stream to the parent in real-time. The parent UI shows all servers in one dashboard.
Part 7: Anomaly Detection
Netdata runs ML models on every metric:
- Each metric gets a Gaussian Mixture Model (GMM) trained on the last 2 hours
- Anomaly Rate = percentage of metrics in anomalous state right now
- No configuration needed — it just works
- Access: Dashboard → Anomaly Advisor tab
# Get anomaly rate via API:
curl "http://localhost:19999/api/v1/alarms?all" | jq '.alarms | to_entries[] | select(.value.status=="WARNING" or .value.status=="CRITICAL") | .value.name'
Maintenance
# Update Netdata:
docker compose pull
docker compose up -d
# Check Netdata version:
docker exec netdata netdata --version
# Logs:
docker compose logs -f netdata
# Reload config (no restart):
docker exec netdata kill -HUP 1
# Backup config:
tar -czf netdata-config-$(date +%Y%m%d).tar.gz \
$(docker volume inspect netdata_netdataconfig --format '{{.Mountpoint}}')
See all open source monitoring tools at OSSAlt.com/categories/devops.