[{"data":1,"prerenderedAt":204},["ShallowReactive",2],{"seo-verification":3,"blog-vps-monitoring-with-grafana-and-prometheus-ma-en":6,"promo-bar-likely":203},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-vps-monitoring-with-grafana-and-prometheus-ma-en",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"noindex":19,"publishedAt":20,"updatedAt":21,"category":22,"categories":28,"featuredImage":30,"bgImage":31,"posterImage":32,"relatedSolution":33,"intro":36,"sections":37,"ctaTitle":143,"ctaBody":144,"ctaButton":145,"ctaUrl":146,"relatedPosts":147},106,"vps-monitoring-with-grafana-and-prometheus",{"fr":12,"en":10,"ar":13,"es":14},"monitoring-vps-grafana-prometheus","مراقبة-الخادم-الافتراضي-vps-باستخدام-grafana-و-prometheus","monitorizacion-vps-grafana-prometheus","VPS Monitoring with Grafana and Prometheus","Deploy Prometheus 3.x, Grafana 13.x, Node Exporter and Alertmanager on your VPS with Docker Compose. Dashboards, alerts and hardening.",11,1,false,"2026-03-06T00:00:00+00:00","2026-10-05T14:05:27+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},8,"Security & Monitoring","securite-monitoring","bg-rose-500\u002F10 text-rose-400","security",[29],{"id":23,"name":24,"slug":25,"color":26,"icon":27},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fmonitoring-vps-grafana-prometheus-poster.svg",{"categorySlug":34,"appSlug":35},"monitoring-observability","grafana","When you want historical metrics, custom dashboards and fine-grained alerting, the Prometheus + Grafana duo is the open source reference. Prometheus 3.x collects and stores time series, Grafana 13.x visualizes them. Here is how to deploy this complete stack — Node Exporter, cAdvisor, Alertmanager included — on your own VPS.",[38,42,54,57,85,88,91,130,134,137,140],{"type":39,"title":40,"body":41},"h2","Why self-host Prometheus and Grafana on a VPS","Unlike an all-in-one tool, the Prometheus + Grafana stack clearly separates collection (Prometheus scrapes metrics exposed by exporters), storage (built-in time series database) and visualization (Grafana). This modularity is precisely what makes it a standard: you monitor the VPS itself with Node Exporter, your containers with cAdvisor, your PostgreSQL or MySQL database with the dedicated exporter, and you instrument your own applications in the Prometheus format.\n\nAll of this on a VPS you control, which spares you from sending sensitive infrastructure metrics to a SaaS billed by ingestion. You keep the history for as long as your disk allows, you build dashboards specific to your stack, and you define your own alerting rules via Alertmanager.\n\nWith the release of **Prometheus 3.x** (latest stable: v3.15.0, September 2026), the TSDB storage engine has been optimized to reduce memory consumption by 15 to 20% on modest machine fleets — a direct advantage for VPS. Grafana 13.x (v13.2.3, late September 2026) brings a redesigned dashboard composer and a unified alerting system. This is the approach to favor when you go beyond simply 'is the site responding?' to move into fine-grained analysis of load trends.",{"type":43,"title":44,"items":45},"ul","What this stack brings to your VPS",[46,47,48,49,50,51,52,53],"Detailed system metrics (CPU, RAM, disk I\u002FO, network) via **Node Exporter v1.12.1**, kept as long-term history.","Monitoring of Docker containers with cAdvisor: per-container consumption in real time.","Custom Grafana dashboards, importable from a community library of thousands of templates.","Powerful alerting via **Alertmanager v0.34.1**: thresholds, grouping, silences and multi-channel routing (email, Slack, PagerDuty...).","HTTP\u002FTCP endpoint monitoring with Blackbox Exporter: response time detection and TLS certificate expiry.","Application log collection with **Loki** (same vendor as Grafana): correlate logs and metrics in a single dashboard.","PromQL query language to create derived indicators and rates of change.","Instrumentation of your own applications in the Prometheus format, with no external ingestion cost.",{"type":39,"title":55,"body":56},"VPS prerequisites and resources to plan for","This stack is more demanding than a simple monitor because Prometheus keeps time series in memory before writing them to disk. Plan for a VPS with **2 vCPU and 2 to 4 GB of RAM** to monitor one to several servers. Add Loki and Alertmanager and aim for 4 GB minimum.\n\n**Storage is the critical point**: Prometheus generates approximately 1 to 2 MB per time series per day depending on scrape frequency (15 s by default). For 500 series over 30 days, plan for 15 to 30 GB. Start with 40 GB of SSD, and adjust `--storage.tsdb.retention.time` according to your needs.\n\n**Software prerequisites:** Docker 26+ and Docker Compose v2, a domain name pointing to your VPS (for the HTTPS reverse proxy for Grafana), and `ufw` or equivalent to restrict ports.",{"type":58,"title":59,"steps":60},"steps","Deploying the stack with Docker Compose",[61,64,67,70,73,76,79,82],{"title":62,"body":63},"Create the project directory structure","On your VPS, create a dedicated folder and the file structure:\n```bash\nmkdir -p ~\u002Fmonitoring\u002F{prometheus,alertmanager,loki}\ncd ~\u002Fmonitoring\n```\nThis organization isolates each configuration in its own directory, simplifying updates.",{"title":65,"body":66},"Write the docker-compose.yml file","Define the following services in a `docker-compose.yml` file: `prometheus` (image `prom\u002Fprometheus:v3.15.0`), `grafana` (image `grafana\u002Fgrafana:13.2.3`), `node-exporter` (image `prom\u002Fnode-exporter:v1.12.1`), `cadvisor` (image `gcr.io\u002Fcadvisor\u002Fcadvisor:latest`), `alertmanager` (image `prom\u002Falertmanager:v0.34.1`).\n\nMount configuration files as bind-mount volumes and create named volumes to persist data: `prometheus_data`, `grafana_data`. Example bind for `node-exporter`:\n```bash\nvolumes:\n  - \u002Fproc:\u002Fhost\u002Fproc:ro\n  - \u002Fsys:\u002Fhost\u002Fsys:ro\n  - \u002F:\u002Frootfs:ro\n```\nThen run `docker compose up -d` to start the stack.",{"title":68,"body":69},"Configure prometheus.yml with all scrape jobs","In `prometheus\u002Fprometheus.yml`, declare targets in the `scrape_configs` section. Four essential jobs:\n```bash\nscrape_configs:\n  - job_name: 'node'\n    static_configs:\n      - targets: ['node-exporter:9100']\n  - job_name: 'cadvisor'\n    static_configs:\n      - targets: ['cadvisor:8080']\n  - job_name: 'alertmanager'\n    static_configs:\n      - targets: ['alertmanager:9093']\n  - job_name: 'prometheus'\n    static_configs:\n      - targets: ['localhost:9090']\n```\nReload configuration without restarting: `curl -X POST http:\u002F\u002Flocalhost:9090\u002F-\u002Freload` (requires `--web.enable-lifecycle` flag).",{"title":71,"body":72},"Configure Alertmanager (alertmanager.yml)","Create `alertmanager\u002Falertmanager.yml`. A minimal configuration routing alerts to Slack:\n```bash\nroute:\n  receiver: 'slack-notifications'\n  group_wait: 30s\n  group_interval: 5m\n  repeat_interval: 4h\nreceivers:\n  - name: 'slack-notifications'\n    slack_configs:\n      - api_url: 'https:\u002F\u002Fhooks.slack.com\u002Fservices\u002FYOUR\u002FWEBHOOK'\n        channel: '#vps-alerts'\n        title: '{{ .CommonAnnotations.summary }}'\n```\nFor email, replace `slack_configs` with `email_configs` with `to`, `from`, `smarthost`, `auth_username` and `auth_password` fields.",{"title":74,"body":75},"Create Prometheus alerting rules","In `prometheus\u002Frules.yml`, define your rules. Three essentials for a VPS:\n```bash\ngroups:\n  - name: vps\n    rules:\n      - alert: HighCPU\n        expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode=\"idle\"}[5m])) * 100) > 85\n        for: 5m\n        annotations:\n          summary: 'CPU > 85% for 5 min'\n      - alert: LowMemory\n        expr: node_memory_MemAvailable_bytes \u002F node_memory_MemTotal_bytes \u003C 0.10\n        for: 5m\n        annotations:\n          summary: 'Available memory \u003C 10%'\n      - alert: DiskFull\n        expr: (node_filesystem_size_bytes - node_filesystem_avail_bytes) \u002F node_filesystem_size_bytes > 0.85\n        for: 10m\n        annotations:\n          summary: 'Disk > 85%'\n```\nReference this file in `prometheus.yml` under `rule_files: ['rules.yml']`.",{"title":77,"body":78},"Connect Grafana to Prometheus (and Loki)","Open Grafana on port 3000. Default credentials: **admin \u002F admin** — change them immediately.\n\nAdd a Prometheus data source with URL `http:\u002F\u002Fprometheus:9090`. Test the connection: it should return 'Data source is working'.\n\nIf you added Loki to the Compose (`grafana\u002Floki:3.3.2`), add a second Loki data source with URL `http:\u002F\u002Floki:3100`. You can then correlate CPU spikes in a Prometheus dashboard with application logs in Loki, without switching tools.",{"title":80,"body":81},"Expose Grafana over HTTPS via a reverse proxy","Grafana should never be exposed over plain HTTP. Configure Nginx as a reverse proxy:\n```bash\nserver {\n  listen 443 ssl;\n  server_name grafana.your-domain.com;\n  ssl_certificate \u002Fetc\u002Fletsencrypt\u002Flive\u002Fgrafana.your-domain.com\u002Ffullchain.pem;\n  ssl_certificate_key \u002Fetc\u002Fletsencrypt\u002Flive\u002Fgrafana.your-domain.com\u002Fprivkey.pem;\n  location \u002F {\n    proxy_pass http:\u002F\u002F127.0.0.1:3000;\n    proxy_set_header Host $host;\n  }\n}\n```\nBlock internal ports at the firewall: `ufw deny 9090`, `ufw deny 9093`, `ufw deny 3000`. Only port 443 (Nginx) should be publicly open.",{"title":83,"body":84},"Verify that Prometheus is scraping all targets","Go to `http:\u002F\u002Flocalhost:9090\u002Ftargets` (via SSH or through the reverse proxy). All declared targets should show **UP** status in green. A **DOWN** status indicates a Docker network issue (wrong service name), a port issue, or a configuration problem. Fix it before moving on: a Grafana connected to a Prometheus with no data renders empty dashboards, and nothing in the interface explicitly says why.",{"type":39,"title":86,"body":87},"Importing community Grafana dashboards","Grafana offers a library of ready-to-use dashboards at **grafana.com\u002Fgrafana\u002Fdashboards**. Two essential identifiers for a VPS:\n\n**ID 1860 — Node Exporter Full**: the reference dashboard for system metrics. It displays in real time and over time: CPU load per core, memory usage (including buffers\u002Fcache), disk I\u002FO per device, network saturation and queue. Filterable by instance, making it usable to monitor multiple VPS from a single Grafana.\n\n**ID 893 — cAdvisor**: per-container Docker metrics — CPU throttling, memory usage, I\u002FO and network errors. Useful for detecting a container that consumes abnormally without slowing down the VPS overall.\n\nTo import a dashboard: in Grafana, go to **Dashboards → Import**, enter the ID, select your Prometheus data source and confirm. The dashboard is imported in seconds, with nothing to build by hand.",{"type":39,"title":89,"body":90},"Configuring alerts with Alertmanager","Alertmanager is the component that receives alerts from Prometheus and decides what to do with them: group them, silence them during maintenance, route them to different channels based on severity.\n\n**Grouping**: multiple alerts triggered at the same time (network outage → high CPU + inaccessible disk + service down) are grouped into a single notification, not three separate emails. This is the `group_by: ['alertname', 'instance']` field in `alertmanager.yml`.\n\n**Silences**: before planned maintenance, create a silence in the Alertmanager interface (`http:\u002F\u002Flocalhost:9093`) or via the API: `amtool silence add --duration=2h alertname=~'.*'`. Alerts continue to be evaluated by Prometheus but are not sent during the window.\n\n**Multi-channel routing**: critical alerts (CPU > 95%) go to PagerDuty or Slack with `@channel` mention, warnings (CPU > 85%) to a less urgent monitoring channel. Configure this with nested `routes` and `match_re` in `alertmanager.yml`.\n\nAfter each modification to `alertmanager.yml`, reload without restarting: `curl -X POST http:\u002F\u002Flocalhost:9093\u002F-\u002Freload`.",{"type":92,"title":93,"headers":94,"rows":99},"comparison","Prometheus vs InfluxDB vs Zabbix: which to choose?",[95,96,97,98],"Criterion","Prometheus","InfluxDB","Zabbix",[100,105,110,115,120,125],[101,102,103,104],"Collection model","Pull (active scrape)","Push (agents or API)","Agent + SNMP + JMX",[106,107,108,109],"Storage","Built-in TSDB, efficient on VPS","InfluxDB OSS or Cloud","PostgreSQL \u002F MySQL, heavy",[111,112,113,114],"Query language","PromQL (powerful, steep curve)","Flux \u002F InfluxQL (SQL-like)","Zabbix macros (limited)",[116,117,118,119],"Alerting","Dedicated Alertmanager, flexible","Built-in (OSS limited)","Built-in, rich but complex",[121,122,123,124],"Learning curve","Moderate (PromQL)","Low (SQL-like)","High (dense UI, agents)",[126,127,128,129],"Ideal use case","Containerized infra, instrumented apps","IoT, high-frequency time series","Enterprise networks, SNMP",{"type":131,"title":132,"body":133},"tip","Hardening: never expose Prometheus publicly","Prometheus has no native authentication system. Its web interface exposes the list of all your targets, your infrastructure labels and your alerting rules — valuable information for an attacker mapping your infrastructure.\n\nThree non-negotiable rules:\n1. Bind Prometheus on `127.0.0.1:9090` only (`--web.listen-address=127.0.0.1:9090` in the Compose).\n2. Block ports 9090, 9093, 9100 and 8080 at the firewall (`ufw deny 9090`).\n3. Protect Grafana with a strong password and disable the anonymous account (`GF_AUTH_ANONYMOUS_ENABLED=false` as an environment variable).\n\nIf you need to access the Prometheus interface from outside for debugging, use an SSH tunnel (`ssh -L 9090:localhost:9090 user@your-domain.com`) rather than a public reverse proxy.",{"type":39,"title":135,"body":136},"Adding Docker container monitoring with cAdvisor","cAdvisor (Container Advisor) exposes per-container Docker metrics in Prometheus format: CPU usage as a proportion of the allocated quota, memory consumption with and without cache, network and disk I\u002FO, and restarts.\n\nIn `docker-compose.yml`, add the service:\n```bash\ncadvisor:\n  image: gcr.io\u002Fcadvisor\u002Fcadvisor:latest\n  volumes:\n    - \u002F:\u002Frootfs:ro\n    - \u002Fvar\u002Frun:\u002Fvar\u002Frun:ro\n    - \u002Fsys:\u002Fsys:ro\n    - \u002Fvar\u002Flib\u002Fdocker\u002F:\u002Fvar\u002Flib\u002Fdocker:ro\n  ports:\n    - '127.0.0.1:8080:8080'\n  restart: unless-stopped\n```\nThen add the corresponding job in `prometheus.yml`. The Grafana dashboard ID 893 (cAdvisor) then displays a per-container view, with a filter on the Docker service name — useful for comparing consumption between your applications and detecting memory leaks.",{"type":39,"title":138,"body":139},"Troubleshooting: the most common errors","**Target DOWN in Prometheus (`\u002Ftargets`)**: first check the service name in `docker-compose.yml` — Prometheus resolves names by Docker internal DNS. If the service is named `node-exporter` in the Compose, the scrape URL must be `node-exporter:9100`, not `localhost:9100`. Also verify that all services are on the same Docker network (`networks: monitoring`).\n\n**Empty dashboards after import**: the most common cause is a scrape `job` whose label does not match what the dashboard expects. Node Exporter Full (ID 1860) expects a job named `node` — if you named it `node_exporter` in `prometheus.yml`, filter manually in the dashboard variables or rename the job.\n\n**Alertmanager not receiving alerts**: verify that Prometheus can reach Alertmanager. In `prometheus.yml`, the `alerting` section must point to `alertmanager:9093` (Docker service name). Test with `curl http:\u002F\u002Falertmanager:9093\u002F-\u002Fhealthy` from inside the Prometheus container: `docker compose exec prometheus curl http:\u002F\u002Falertmanager:9093\u002F-\u002Fhealthy`.\n\n**'context deadline exceeded' error on reload**: Prometheus takes more than 30 s to reload if rules are numerous or if a target is slow. Increase the scrape timeout in `prometheus.yml`: `scrape_timeout: 20s` under `global`.",{"type":39,"title":141,"body":142},"Going further","This stack covers the essentials of VPS monitoring. For more advanced needs:\n\n**Long-term retention**: Prometheus stores data locally, ideal for 30 to 90 days. For a 1 to 2 year history without saturating the disk, connect **Thanos** (S3-compatible object store) or **VictoriaMetrics** as a drop-in storage replacement. VictoriaMetrics is particularly suited to modest VPS: it consumes 5 to 10× less memory than Prometheus for the same volume of series.\n\n**HTTP endpoint monitoring**: add **Blackbox Exporter** to the Compose to test the availability of your URLs, the returned HTTP code, latency and TLS certificate expiry date — without instrumenting the application.\n\n**Logs with Loki**: if you want to correlate metrics with application logs (Nginx errors, PHP exceptions...), add Loki + Promtail to the Compose. Grafana displays metrics and logs in the same panel, reducing diagnostic time.\n\nFor all advanced configuration options, refer to the \u003Ca href=\"https:\u002F\u002Fgrafana.com\u002Fdocs\">official Grafana documentation\u003C\u002Fa> and the \u003Ca href=\"https:\u002F\u002Fprometheus.io\u002Fdocs\">Prometheus documentation\u003C\u002Fa>. ServOrbit offers a pre-configured Docker template to launch this stack in one click on a \u003Ca href=\"\u002Fvps-cloud\">Cloud VPS\u003C\u002Fa> — Grafana, Prometheus, Node Exporter and Alertmanager mounted and ready, without initial configuration.","Deploy your observability stack","The ServOrbit Cloud VPS offers the CPU, RAM and SSD needed to run Prometheus, Grafana and their exporters without a bottleneck, with a Docker template ready to configure.","Configure my Cloud VPS","\u002Fvps-cloud",[148,166,184],{"id":149,"slug":150,"slugs":151,"title":155,"excerpt":156,"readTime":23,"views":157,"isPinned":19,"noindex":19,"publishedAt":158,"updatedAt":159,"category":160,"categories":161,"featuredImage":30,"bgImage":31,"posterImage":163,"relatedSolution":164},105,"monitoring-your-vps-with-uptime-kuma",{"fr":152,"en":150,"ar":153,"es":154},"superviser-vps-uptime-kuma","مراقبة-خادمك-الافتراضي-vps-باستخدام-uptime-kuma","supervisar-vps-con-uptime-kuma","Monitoring your VPS with Uptime Kuma","Deploy Uptime Kuma on your VPS to monitor your sites and services self-hosted, with alerts and a public status page.",0,"2026-03-07T00:00:00+00:00","2026-11-09T20:55:19+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[162],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Fsuperviser-vps-uptime-kuma-poster.svg",{"categorySlug":34,"appSlug":165},"uptime-kuma",{"id":167,"slug":168,"slugs":169,"title":173,"excerpt":174,"readTime":175,"views":18,"isPinned":19,"noindex":19,"publishedAt":176,"updatedAt":177,"category":178,"categories":179,"featuredImage":30,"bgImage":31,"posterImage":181,"relatedSolution":182},107,"monitor-your-vps-in-real-time-with-netdata",{"fr":170,"en":168,"ar":171,"es":172},"monitorer-vps-netdata","راقب-خادمك-الافتراضي-vps-في-الوقت-الفعلي-باستخدام-netdata","monitorizar-vps-en-tiempo-real-con-netdata","Monitor your VPS in real time with Netdata","Install Netdata on your VPS for per-second real-time monitoring: thousands of metrics, zero configuration, alerts included.",3,"2026-03-05T00:00:00+00:00","2026-09-07T11:26:10+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[180],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Fmonitorer-vps-netdata-poster.svg",{"categorySlug":34,"appSlug":183},"netdata",{"id":185,"slug":186,"slugs":187,"title":191,"excerpt":192,"readTime":193,"views":194,"isPinned":19,"noindex":19,"publishedAt":195,"updatedAt":177,"category":196,"categories":197,"featuredImage":30,"bgImage":31,"posterImage":199,"relatedSolution":200},108,"securing-your-vps-with-crowdsec",{"fr":188,"en":186,"ar":189,"es":190},"securiser-vps-crowdsec","تأمين-خادمك-الافتراضي-vps-باستخدام-crowdsec","proteger-vps-con-crowdsec","Securing your VPS with CrowdSec","Deploy CrowdSec on your VPS to block attacks thanks to behavioral detection and a shared community blocklist.",4,2,"2026-03-04T00:00:00+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[198],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Fsecuriser-vps-crowdsec-poster.svg",{"categorySlug":201,"appSlug":202},"cybersecurity-bastion","crowdsec",true,1794270509861]