Proxy Server Setup: Squid and HAProxy Guide
Squid forward proxy, HAProxy load balancer, SSL termination, ACL rules, caching, health checks and high availability.
Prometheus + Grafana stack setup, Netdata, node_exporter, alert rules, dashboard creation and server metric monitoring.
Effectively monitoring your server infrastructure is essential for early detection of performance issues and preventing downtime. In this guide, we will set up a comprehensive server monitoring system using the Prometheus, Grafana, and Netdata trio.
Prometheus is an open-source metric collection and monitoring system supported by the Cloud Native Computing Foundation (CNCF). With its pull-based architecture, it regularly scrapes metrics from target systems via HTTP and stores them in a time-series database.
Key features of Prometheus:
Node Exporter is a Prometheus exporter that collects hardware and OS-level metrics from Linux servers.
# Download Node Exporter
cd /tmp
curl -LO https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz
tar xzf node_exporter-1.7.0.linux-amd64.tar.gz
# Move binary
sudo mv node_exporter-1.7.0.linux-amd64/node_exporter /usr/local/bin/
# Create user
sudo useradd --no-create-home --shell /bin/false node_exporter
# Systemd service file
sudo tee /etc/systemd/system/node_exporter.service > /dev/null <<EOF
[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter \\
--collector.systemd \\
--collector.processes \\
--web.listen-address=:9100
[Install]
WantedBy=multi-user.target
EOF
# Start the service
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
sudo systemctl status node_exporter
# docker-compose.yml
version: '3.8'
services:
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
restart: unless-stopped
ports:
- "9100:9100"
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--path.rootfs=/rootfs'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
Verify metrics:
curl http://localhost:9100/metrics | head -50
# docker-compose.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: unless-stopped
ports:
- "9090:9090"
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- ./prometheus/alert_rules.yml:/etc/prometheus/alert_rules.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=30d'
- '--web.enable-lifecycle'
volumes:
prometheus_data:
# prometheus/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_timeout: 10s
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
rule_files:
- "alert_rules.yml"
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node-exporter'
static_configs:
- targets:
- 'node-exporter:9100'
- '192.168.1.10:9100'
- '192.168.1.11:9100'
labels:
env: 'production'
- job_name: 'docker'
static_configs:
- targets: ['cadvisor:8080']
Detect critical conditions with Prometheus alert rules:
# prometheus/alert_rules.yml
groups:
- name: server_alerts
rules:
- alert: HighCPUUsage
expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
for: 5m
labels:
severity: warning
annotations:
summary: "High CPU usage ({{ $labels.instance }})"
description: "CPU usage is {{ $value | printf \"%.1f\" }}% - above 85% for 5 minutes."
- alert: HighMemoryUsage
expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90
for: 5m
labels:
severity: critical
annotations:
summary: "High memory usage ({{ $labels.instance }})"
description: "Memory usage is {{ $value | printf \"%.1f\" }}% - above 90%."
- alert: DiskAlmostFull
expr: (1 - (node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"})) * 100 > 85
for: 10m
labels:
severity: warning
annotations:
summary: "Disk almost full ({{ $labels.instance }})"
description: "{{ $labels.mountpoint }} disk usage is {{ $value | printf \"%.1f\" }}%"
- alert: InstanceDown
expr: up == 0
for: 2m
labels:
severity: critical
annotations:
summary: "Instance unreachable ({{ $labels.instance }})"
description: "{{ $labels.job }} target has been unreachable for 2 minutes."
- alert: HighDiskIO
expr: rate(node_disk_io_time_seconds_total[5m]) > 0.9
for: 10m
labels:
severity: warning
annotations:
summary: "High Disk I/O ({{ $labels.instance }})"
description: "Disk I/O usage is {{ $value | printf \"%.1f\" }}% - high for 10 minutes."
# alertmanager/alertmanager.yml
global:
resolve_timeout: 5m
route:
group_by: ['alertname', 'severity']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receiver: 'telegram'
routes:
- match:
severity: critical
receiver: 'telegram'
repeat_interval: 1h
receivers:
- name: 'telegram'
telegram_configs:
- bot_token: 'YOUR_BOT_TOKEN'
chat_id: YOUR_CHAT_ID
parse_mode: 'HTML'
message: |
<b>{{ .Status | toUpper }}</b>
<b>Alert:</b> {{ .CommonLabels.alertname }}
<b>Severity:</b> {{ .CommonLabels.severity }}
<b>Instance:</b> {{ .CommonLabels.instance }}
<b>Description:</b> {{ .CommonAnnotations.description }}
# docker-compose.yml (add to prometheus stack)
services:
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: unless-stopped
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=StrongPassword123!
- GF_USERS_ALLOW_SIGN_UP=false
- GF_SERVER_ROOT_URL=https://grafana.example.com
- GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-piechart-panel
volumes:
grafana_data:
# grafana/provisioning/datasources/prometheus.yml
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: true
You can import ready-made dashboards from Grafana.com:
# Node Exporter Full Dashboard
Dashboard ID: 1860
Data Source: Prometheus
# Docker Container Monitoring
Dashboard ID: 893
# Prometheus Stats
Dashboard ID: 2
# Alertmanager Dashboard
Dashboard ID: 9578
To import: Grafana → Dashboards → Import → Enter Dashboard ID → Load → Select Prometheus data source → Import.
# CPU usage percentage
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# RAM usage percentage
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100
# Disk usage percentage
(1 - (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"})) * 100
# Network traffic (bytes/second)
rate(node_network_receive_bytes_total{device="eth0"}[5m])
rate(node_network_transmit_bytes_total{device="eth0"}[5m])
# Disk I/O (read/write bytes/second)
rate(node_disk_read_bytes_total[5m])
rate(node_disk_written_bytes_total[5m])
# System uptime
node_time_seconds - node_boot_time_seconds
# Open file descriptors
node_filefd_allocated
Netdata is a real-time server monitoring tool. Installation is extremely easy and provides detailed metrics instantly.
# Automatic installation script
bash <(curl -Ss https://my-netdata.io/kickstart.sh)
# After installation
sudo systemctl status netdata
Web interface: http://SERVER_IP:19999
# docker-compose.yml
version: '3.8'
services:
netdata:
image: netdata/netdata:latest
container_name: netdata
restart: unless-stopped
ports:
- "19999:19999"
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
volumes:
netdataconfig:
netdatalib:
netdatacache:
# Edit main configuration file
sudo /etc/netdata/edit-config netdata.conf
# /etc/netdata/netdata.conf
[global]
hostname = server-01
history = 3996
update every = 1
memory mode = dbengine
page cache size = 64
dbengine multihost disk space = 2048
[web]
bind to = 0.0.0.0
default port = 19999
allow connections from = localhost 192.168.1.*
sudo /etc/netdata/edit-config health.d/cpu.conf
alarm: cpu_usage_high
on: system.cpu
lookup: average -5m percentage foreach user,system
units: %
every: 1m
warn: $this > 80
crit: $this > 95
info: CPU usage averaged $this% over the last 5 minutes
to: sysadmin
Combine all components in a single compose file:
# docker-compose.monitoring.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: unless-stopped
ports:
- "9090:9090"
volumes:
- ./prometheus:/etc/prometheus
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.retention.time=30d'
networks:
- monitoring
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: unless-stopped
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=StrongPassword123!
depends_on:
- prometheus
networks:
- monitoring
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
restart: unless-stopped
ports:
- "9100:9100"
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--path.rootfs=/rootfs'
networks:
- monitoring
alertmanager:
image: prom/alertmanager:latest
container_name: alertmanager
restart: unless-stopped
ports:
- "9093:9093"
volumes:
- ./alertmanager:/etc/alertmanager
networks:
- monitoring
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
networks:
- monitoring
networks:
monitoring:
driver: bridge
volumes:
prometheus_data:
grafana_data:
docker compose -f docker-compose.monitoring.yml up -d
You can monitor your entire REXE server infrastructure from a single dashboard by setting up the Prometheus + Grafana + Netdata stack. Alert rules enable proactive issue detection before they impact your services.
Prometheus is ideal for metric collection and long-term storage with powerful PromQL querying. Netdata is optimized for real-time monitoring and is very easy to install. The best approach is to use both together: Netdata for instant monitoring and quick issue detection, Prometheus + Grafana for long-term trend analysis and custom dashboards.
Go to Dashboards → Import in the Grafana web interface. Copy the dashboard ID from grafana.com/grafana/dashboards (e.g., 1860 for Node Exporter Full). Enter the ID, click Load, select the Prometheus data source, and click Import. The dashboard will be automatically configured.
Reduce the retention period: '--storage.tsdb.retention.time=15d'. Increase the scrape interval (30s instead of 15s). Filter unnecessary metrics with metric_relabel_configs. Use the Admin API to delete old data: 'curl -X POST http://localhost:9090/api/v1/admin/tsdb/clean_tombstones'. Monitor disk usage: 'du -sh /prometheus'.
First check that alerts are firing in Prometheus: http://localhost:9090/alerts. Verify Alertmanager is running: http://localhost:9093/#/alerts. Check the configuration file: 'amtool check-config alertmanager.yml'. Ensure the Telegram bot token and chat ID are correct. Review Alertmanager logs: 'docker logs alertmanager'.
Node Exporter collects CPU usage, RAM, disk space and I/O, network traffic, system load (load average), filesystem, boot time, running process count, open file descriptors, and more. Additional collectors can be enabled: --collector.systemd (service states), --collector.processes (detailed process info), --collector.tcpstat (TCP connection statistics).
Install Node Exporter on each server (port 9100). Add all servers under scrape_configs in the Prometheus configuration. You can filter servers by instance label in Grafana dashboards. For a large number of servers, you can scale using Prometheus federation or Thanos.
Squid forward proxy, HAProxy load balancer, SSL termination, ACL rules, caching, health checks and high availability.
Nginx Proxy Manager Docker installation, automatic SSL certificate renewal, proxy host configuration, access lists, redirects, streams and custom locations.
CrowdSec installation, bouncer configuration, attack detection, IP blocking, dashboard, collection and scenario management.