Перейти до основного вмісту
Знижка 50% усі плани, обмежений час. Від $2.48/mo
14 min left
Інструменти розробника та DevOps

Налаштування стека моніторингу Grafana + Prometheus на вашому VPS (посібник із Docker Compose)

C Автор: Chike 14 хв читання
Prometheus and Grafana monitoring stack illustration: a central dashboard panel showing Prometheus and Grafana logos over metric graphs, with three server nodes feeding metrics into it

Якщо ви ще не знаєте, що таке Prometheus і Grafana, прочитайте нашу статтю про Prometheus проти Grafana. Якщо різницю ви вже знаєте, ось як запустити їх разом.

Ця стаття — практичне доповнення. Вона розгортає Prometheus, Grafana та Node Exporter на одному VPS за допомогою Docker Compose, ставить перед Grafana HTTPS через Caddy, імпортує дашборд Node Exporter Full (ID 1860) і показує, як збирати метрики з другого VPS через WireGuard.

Початковий тест у квітні 2026 року виконувався на Ubuntu 24.04 LTS із Docker Engine 27.x і Docker Compose v2.30. Версії, зафіксовані в конфігурації нижче, відтоді оновлено до актуальних підтримуваних випусків. У тому початковому тесті з п'ятьма хостами хаб споживав приблизно 300 МБ оперативної пам'яті в простої та від 530 до 650 МБ під час постійного збору метрик.

TL;DR

  • VPS-хаб запускає Prometheus, Grafana та Node Exporter в одному стеку Compose, а Caddy встановлено на хості як зворотний проксі.
  • Prometheus і Grafana слухають лише 127.0.0.1. Публічний доступ іде через Caddy з автоматичним HTTPS.
  • Додавайте нові сервери, встановлюючи на кожен Node Exporter і дописуючи записи у prometheus.yml.
  • WireGuard — рекомендований мережевий шлях між хабом і вузлами. Приватна мережа добре працює, коли ваші сервери вже перебувають в одній приватній мережі.
  • Для тесту з п'ятьма хостами нижче вистачило VPS із 2 ГБ, але сприймайте це як орієнтир, а не жорстке правило за кількістю хостів.

Що ви побудуєте

Diagram of monitoring traffic boundaries: ports 80 and 443 are public, Grafana on 3000, Prometheus on 9090 and Node Exporter on 9100 stay on loopback, and a remote Node Exporter on 10.10.0.2:9100 is reachable only over the private network

Ось як приблизно виглядатиме готова конфігурація.

                 +-------------------+
                 |  Your laptop      |
                 +---------+---------+
                           | HTTPS
                           v
+--------------------------+----------------------------+
| MONITORING HUB VPS    (2 GB RAM starting point) |
|  Caddy        (reverse proxy, auto HTTPS)             |
|  Grafana      (port 3000, only via Caddy)             |
|  Prometheus   (port 9090, internal only)              |
|  Node Exporter (port 9100, scraped on localhost)      |
+----+---------------------------------+----------------+
     |                                 |
     | scrape over WireGuard           | scrape over WG
     v                                 v
+----+--------+                  +-----+-------+
|  App VPS 1  |                  |  App VPS 2  |
|  Node Expo. |                  |  Node Expo. |
+-------------+                  +-------------+

Увесь стек моніторингу тримає один VPS-хаб. На кожному іншому VPS, який ви хочете спостерігати, працює лише Node Exporter. Prometheus на хабі забирає метрики з кожного з них, Grafana їх візуалізує, а Caddy відповідає за HTTPS.

Що вам потрібно

Саме для цієї конфігурації потрібні один VPS з Ubuntu під хаб, домен і доступ через sudo.

  • VPS щонайменше з 2 ГБ оперативної пам'яті під керуванням Ubuntu 24.04 LTS.
  • Доменне ім'я з A-записом, що вказує на публічну IP-адресу VPS (наприклад, grafana.example.com). Потрібне для HTTPS.
  • Доступ root або sudo через SSH.

У всьому посібнику замінюйте grafana.example.com на той піддомен, який ви справді спрямували на свій VPS моніторингу. Використовуйте той самий домен у змінній середовища Grafana, під час перевірки DNS і в Caddyfile.

Якщо ви хочете спостерігати лише за одним сервером і HTTPS вам поки не потрібен, запустіть стек Compose на наявному VPS без розділу про зворотний проксі. Решта посібника залишається чинною.

Розгорнути Ubuntu VPS

Запустіть Ubuntu VPS миттєво з root-доступом і сховищем NVMe.

Розгорнути Ubuntu VPS

Крок 1. Підготовка сервера

Підключіться по SSH до VPS-хаба користувачем із правами sudo. Спершу оновіть систему.

sudo apt update && sudo apt upgrade -y

Встановіть Docker Engine і плагін Compose з офіційного репозиторію Docker.

# Install prerequisites
sudo apt install -y ca-certificates curl gnupg lsb-release

# Add Docker's official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Add the Docker repository
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Переконайтеся, що обидва встановлено.

docker --version
docker compose version

Обидві команди мають без помилок вивести версію. Конкретні версії Docker Engine і Compose залежатимуть від того, що пропонує офіційний репозиторій на момент встановлення.

sudo usermod -aG docker $USER

Перш ніж продовжувати, вийдіть із сесії та зайдіть знову, щоб членство в новій групі набуло чинності. Група docker фактично дає права рівня root, тож додавайте до неї лише довірених адміністраторів.

Налаштуйте UFW так, щоб на хабі моніторингу були дозволені SSH, HTTP і HTTPS. Порт 80 відповідає за перенаправлення з HTTP на HTTPS і перевірку ACME. Сама Grafana залишається за Caddy.

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status

Не відкривайте порти 3000, 9090 чи 9100 у публічний інтернет. Служби моніторингу слухають 127.0.0.1 не просто так.

Крок 2. Стек Compose

Створіть каталог для стека та конфігурації Prometheus.

mkdir -p ~/monitoring/prometheus
cd ~/monitoring

Створіть файл Compose.

# ~/monitoring/docker-compose.yml
services:
  prometheus:
    image: prom/prometheus:v3.13.2
    container_name: prometheus
    restart: unless-stopped
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--storage.tsdb.retention.time=15d'
      - '--web.enable-lifecycle'
      - '--web.listen-address=127.0.0.1:9090'
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus_data:/prometheus
    network_mode: host
  node-exporter:
    image: prom/node-exporter:v1.12.1
    container_name: node-exporter
    restart: unless-stopped
    pid: host
    network_mode: host
    command:
      - '--path.rootfs=/host'
      - '--web.listen-address=127.0.0.1:9100'
      - '--collector.filesystem.mount-points-exclude=^/(dev|proc|sys|var/lib/docker/.+|var/lib/kubelet/.+)($$|/)'
    volumes:
      - '/:/host:ro,rslave'
  grafana:
    image: grafana/grafana:13.1.3
    container_name: grafana
    restart: unless-stopped
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD}
      - GF_USERS_ALLOW_SIGN_UP=false
      - GF_SERVER_ROOT_URL=https://grafana.example.com
      - GF_SERVER_HTTP_ADDR=127.0.0.1
    volumes:
      - grafana_data:/var/lib/grafana
    network_mode: host
    depends_on:
      - prometheus
volumes:
  prometheus_data:
  grafana_data:

Тепер створіть конфігурацію Prometheus.

# ~/monitoring/prometheus/prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s
  external_labels:
    monitor: 'monitoring-hub'
scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['127.0.0.1:9090']
  - job_name: 'node'
    static_configs:
      - targets: ['127.0.0.1:9100']
        labels:
          host: 'monitoring-hub'

Створіть файл .env із паролем адміністратора Grafana. Візьміть надійний пароль і не додавайте цей файл до git.

cat > ~/monitoring/.env <<'EOF'
GRAFANA_ADMIN_PASSWORD='replace-with-a-strong-password'
EOF
chmod 600 ~/monitoring/.env

Кілька прапорців вище заслуговують на пояснення.

  • --web.listen-address=127.0.0.1:9090 змушує Prometheus слухати лише петльовий інтерфейс хоста. Порт 9090 залишається поза публічною мережею, але Grafana й локальне адміністрування досі мають до нього доступ.
  • --web.enable-lifecycle вмикає POST /-/reload, завдяки чому зміни конфігурації Prometheus застосовуються без перезапуску контейнера.
  • pid: host, network_mode: host, монтування кореня хоста та --path.rootfs=/host дають Node Exporter у контейнері потрібний контекст хоста замість того, щоб він бачив лише власне середовище контейнера.
  • GF_USERS_ALLOW_SIGN_UP=false забороняє відвідувачам самостійно створювати облікові записи Grafana. Приватною від цього Grafana не стає: сторінка входу досі доступна публічно через Caddy.

Порада: Якщо ручне встановлення вам не потрібне, у Cloudzy є розгортання одним кліком для Grafana та Prometheus . Розгортання Prometheus може заодно встановити й Node Exporter.

Крок 3. Перший запуск і перевірка

Підніміть стек.

cd ~/monitoring
docker compose up -d

Зачекайте кілька секунд і перевірте, що всі три контейнери працюють.

docker compose ps

Усі три служби мають бути у стані running.

Відкрийте SSH-тунель зі свого ноутбука, щоб перевірити сторінку цілей Prometheus.

ssh -L 9090:localhost:9090 your-user@your-vps-ip

Потім відкрийте в браузері http://localhost:9090/targets. Ви маєте побачити дві цілі, обидві у стані UP:

prometheus            UP    http://127.0.0.1:9090/metrics
node                  UP    http://127.0.0.1:9100/metrics

Якщо хоча б одна в стані DOWN, перейдіть до розділу «Типові проблеми». Не продовжуйте, доки обидві не стануть UP.

Закрийте тунель, коли перевірите цілі. Ззовні VPS Prometheus залишиться доступним лише через цей SSH-тунель. На наступному кроці ми відкриємо Grafana через HTTPS.

Крок 4. Зворотний проксі з HTTPS на Caddy

Caddy — це один бінарний файл, і HTTPS він налаштовує автоматично. Для зворотного проксі з одним сайтом його конфігурація коротша за еквівалентний блок Nginx.

Встановіть Caddy з офіційного репозиторію.

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | \
  sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | \
  sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg
sudo chmod o+r /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install -y caddy

Перед наступним кроком переконайтеся, що DNS-запис A для grafana.example.com вказує на публічну IP-адресу VPS. Без цього перевірка ACME не пройде.

dig +short grafana.example.com
# Should print the VPS public IP

Відредагуйте Caddyfile.

# /etc/caddy/Caddyfile
grafana.example.com {
    reverse_proxy 127.0.0.1:3000
    encode gzip
}

Перезавантажте конфігурацію Caddy.

sudo systemctl reload caddy

Caddy автоматично отримує та продовжує публічно довірені TLS-сертифікати через ACME, щойно домен вказує на ваш сервер, а порти 80 і 443 доступні. Відкрийте в браузері https://grafana.example.com: ви маєте побачити сторінку входу Grafana через дійсне HTTPS-з'єднання. Увійдіть під іменем admin із паролем із файлу .env.

Крок 5. Додаємо Prometheus як джерело даних та імпортуємо дашборд 1860

В інтерфейсі Grafana перейдіть до Підключення > Джерела даних > Додати джерело даних і виберіть Prometheus.

Вкажіть такий URL:

http://127.0.0.1:9090

У цій конфігурації Grafana та Prometheus спільно використовують мережу хоста, а Prometheus слухає лише петльовий інтерфейс. Натисніть Save & test і переконайтеся, що Grafana може звертатися до API Prometheus. Має з'явитися повідомлення «Successfully queried the Prometheus API».

Тепер імпортуємо дашборд. Node Exporter Full (ID 1860 від rfmoz) — широко вживаний спільнотний дашборд для метрик Node Exporter. Він охоплює процесор, пам'ять, дисковий ввід-вивід, мережу, файлові дескриптори та температури обладнання, якщо хост їх віддає. Також у ньому є змінні job та instance, тож схема «хаб і промені» працює без доопрацювань.

Перейти до Дашборди > Новий > Імпортувати дашборд, введіть ID дашборда 1860, виберіть своє джерело даних Prometheus та імпортуйте його.

Дашборд має заповнитися, щойно ваша ціль Node Exporter перейде у стан UP. Для частини панелей дашборд 1860 використовує метрики необов'язкових колекторів systemd і processes, тож одна порожня панель ще не означає, що ціль зламана.

Крок 6. Додаємо другий VPS (схема «хаб і промені»)

Перш ніж запускати Node Exporter, переконайтеся, що приватна IP-адреса, до якої ви плануєте прив'язатися, вже існує на другому VPS. Якщо ви користуєтеся WireGuard, спершу завершіть його налаштування.

На другому VPS встановіть Docker за тією частиною кроку 1, де описано встановлення Docker, але не відкривайте порти 80 чи 443 лише заради моніторингу. Потім запустіть сам лише Node Exporter.

mkdir -p ~/node-exporter
cd ~/node-exporter

cat > docker-compose.yml <<'EOF'
services:
  node-exporter:
    image: prom/node-exporter:v1.12.1
    container_name: node-exporter
    restart: unless-stopped
    pid: host
    command:
      - '--path.rootfs=/host'
      - '--web.listen-address=10.10.0.2:9100'  # bind to the private monitoring IP, never 0.0.0.0
    volumes:
      - '/:/host:ro,rslave'
    network_mode: host
EOF

docker compose up -d

Замініть 10.10.0.2 на приватну IP-адресу цього сервера для моніторингу. Якщо ви користуєтеся WireGuard, візьміть його WireGuard-адресу; якщо приватною мережею Cloudzy — IP приватного інтерфейсу VPS. Якщо на цьому VPS уже ввімкнено UFW, дозвольте доступ до Node Exporter лише хабу моніторингу. Наприклад, якщо приватна IP хаба — 10.10.0.1:

sudo ufw allow proto tcp from 10.10.0.1 to any port 9100
sudo ufw status

Замініть 10.10.0.1 на справжню приватну IP-адресу хаба. Якщо UFW вимкнено, явно заданий --web.listen-address все одно тримає Node Exporter поза публічним інтерфейсом, але інші машини, що мають доступ до цієї приватної мережі, теж зможуть дістатися до порту 9100.

Два хороші варіанти мережевого шляху між хабом і вузлами:

  1. Мережа WireGuard. Кожен VPS приєднується до мережі WireGuard, а Prometheus збирає метрики з приватних IP-адрес. Після початкового налаштування WireGuard це найбезпечніший варіант. Ми пропонуємо WireGuard як розгортання одним кліком, а ще в нас є готовий посібник із налаштування щодо нього.
  2. Приватна мережа Cloudzy. Інстанси VPS Cloudzy в одному регіоні отримують приватний інтерфейс для трафіку «схід-захід», тож ви можете збирати метрики просто з цієї адреси, а не будувати окремий тунель WireGuard.

Щойно Node Exporter запрацює на другому VPS і стане доступним за приватною IP-адресою, замініть наявне завдання node у файлі prometheus.yml на хабі наведеним нижче блоком.

# Update the existing 'node' job in ~/monitoring/prometheus/prometheus.yml
  - job_name: 'node'
    static_configs:
      - targets: ['127.0.0.1:9100']
        labels:
          host: 'monitoring-hub'
      - targets: ['10.10.0.2:9100']
        labels:
          host: 'app-vps-1'
          tier: 'production'

Перезавантажте конфігурацію Prometheus без перезапуску контейнера.

curl -X POST http://localhost:9090/-/reload

Знову відкрийте SSH-тунель із кроку 3 і зайдіть на http://localhost:9090/targets. Нова ціль має відображатися як UP. Відкрийте дашборд Node Exporter Full, перемкніть змінну instance вгорі на новий сервер, і ви побачите його графіки.

Споживання ресурсів і коли час розширюватися

Observed five-host baseline from the April 2026 test: Prometheus 250 to 350 MB, Grafana 200 MB, Caddy 40 MB, hub Node Exporter 15 to 20 MB, total hub 530 to 650 MB RAM on a 2 GB VPS with a 1.5 GB fifteen-day working set

Ці цифри взято з початкового тесту у квітні 2026 року на VPS з Ubuntu та 2 ГБ пам'яті за п'яти спостережуваних хостів. Сприймайте їх як орієнтир для такого навантаження, а не як гарантію розміру для новіших випусків.

КомпонентRAM у стані спокоюОЗП під навантаженням (1 хост)ОЗП за 5 хостівДиск (зберігання 15 днів, 5 хостів)
Prometheus~100 MB~150 MB~250-350 МБ~500 МБ до 1,5 ГБ
Grafana~150 MB~180 MB~200 MB~50 MB
Node Exporter~15 МБ~20 МБне застосовнознехтувано мало
Caddy~30 MB~40 МБ~40 МБне застосовно
Разом на хабі~300 МБ~390 МБ~530-650 МБ~1,5 ГБ робочого набору

Розширюйтеся, коли хабу починає бракувати пам'яті чи запасу на диску. Сама лише кількість хостів — поганий орієнтир для вибору розміру, бо на споживання впливають кардинальність серій, увімкнені колектори, інтервал збору та строк зберігання. Для тривалого централізованого зберігання Prometheus підтримує інтеграції з віддаленими сховищами. VictoriaMetrics — один із сумісних із Prometheus варіантів.

Типові проблеми

Сім найчастіших проблем і способи їх усунення.

  1. Prometheus доступний із публічного інтернету. Звичайне прокидання порту 9090:9090 відкриває Prometheus усьому світу. Рішення: залиште --web.listen-address=127.0.0.1:9090 у команді Prometheus, як показано вище. Тоді Prometheus слухає лише петльовий інтерфейс хоста.
  2. Джерело даних Grafana не може дістатися до Prometheus. Цей стек використовує мережу хоста, тож Grafana звертається до Prometheus за адресою http://127.0.0.1:9090. Перевірте, що Prometheus запущено і він досі слухає петльовий інтерфейс.
  3. Дашборд Node Exporter показує «No data». Три звичні причини. (a) Prometheus не опитує ціль. Перевірте /targets. (b) Мітка job у змінній дашборда не збігається з job_name в конфігурації збору. (c) Фаєрвол блокує порт 9100 між хабом і ціллю.
  4. Пароль адміністратора Grafana залишився admin/admin у продакшені. Встановити GF_SECURITY_ADMIN_PASSWORD з файлу .env ще до першого запуску. Якщо ви це пропустили, змініть пароль під час першого входу та вимкніть самореєстрацію.
  5. Caddy повідомляє «ACME challenge failed». A-запис DNS ще не поширився або порт 80 заблоковано. Виконайте ufw allow 80,443/tcp, дочекайтеся поширення DNS і виконайте sudo systemctl reload caddy. Скористайтеся dig +short , щоб підтвердити поширення.
  6. Диск під Prometheus заповнюється. Мітки з високою кардинальністю або короткі інтервали збору за великої кількості хостів швидко заповнюють том. Стежте за prometheus_tsdb_head_series та розміром тому. Що допоможе: вимкнути невикористовувані колектори Node Exporter, збільшити scrape_interval до 30s або скоротити строк зберігання.
  7. Помилки прав доступу під час bind-монтування. Якщо ви монтуєте каталог хоста замість іменованого тому, UID контейнера (65534 для Prometheus, 472 для Grafana) має мати права на запис. Іменовані томи, як у файлі Compose вище, знімають цю проблему.

Коли цей стек надлишковий

Якщо все, чого ви хочете, — сповіщення про те, що URL перестав відповідати, цей стек надлишковий. Uptime Kuma набагато легший варіант, якщо вам потрібні лише базові перевірки доступності.

Часті запитання

У чому різниця між Prometheus і Grafana?

Prometheus — це база даних часових рядів: вона збирає метрики з налаштованих цілей із заданим вами інтервалом, зберігає їх на диску й відповідає на запити PromQL. Grafana — шар візуалізації, який під'єднується до Prometheus (і багатьох інших джерел даних) та малює дашборди. Майже завжди потрібні обидва: Prometheus збирає та зберігає, Grafana показує.

Скільки оперативної пам'яті потрібно зв'язці Prometheus + Grafana?

Хаб моніторингу, на якому в межах одного VPS працюють Prometheus, Grafana, Node Exporter і зворотний проксі, споживає приблизно 300 МБ оперативної пам'яті в простої та від 530 до 650 МБ під час активного збору з п'яти хостів кожні 15 секунд.

Чи можна стежити за кількома серверами з одного примірника Grafana?

Так. Стандартна схема — «хаб і промені». Один примірник Prometheus на VPS-хабі збирає метрики з Node Exporter, який працює на кожному іншому сервері, за яким ви хочете стежити. Grafana на хабі звертається лише до цього одного Prometheus. Дашборд Node Exporter Full (ID 1860) підтримує змінну instance, тож перемикатися між серверами можна просто в одному дашборді.

Який дашборд Grafana найкраще підходить для Node Exporter?

Для такої конфігурації Node Exporter Full (дашборд ID 1860 від rfmoz) — надійний вибір за замовчуванням. Він охоплює основні хостові метрики Node Exporter і підтримує змінні job та instance для спостереження за кількома серверами. Частина панелей залежить від необов'язкових колекторів Node Exporter, тож одна порожня панель ще не означає, що ціль збору зламана.

Як відкрити Grafana через HTTPS?

Запустіть Grafana з прив'язкою до 127.0.0.1:3000 і поставте перед нею зворотний проксі, який візьме на себе HTTPS. Найпростіший варіант — Caddy: Caddyfile із чотирьох рядків із reverse_proxy 127.0.0.1:3000 та блоком домену робить усе, включно з автоматичним керуванням TLS-сертифікатами.

Чи безкоштовні Prometheus і Grafana для комерційного використання?

Prometheus поширюється за ліцензією Apache 2.0. Grafana OSS — за AGPLv3. Внутрішнє й комерційне використання незміненої Grafana OSS дозволене, але її модифікація, розповсюдження або надання зміненої версії через мережу можуть спричинити зобов'язання розкрити вихідний код за AGPL. Grafana Enterprise і Grafana Cloud мають окремі комерційні умови.

Коли варто переходити з Prometheus на VictoriaMetrics?

Придивіться до VictoriaMetrics, коли довше зберігання, висока кардинальність серій або кілька примірників Prometheus ускладнюють експлуатацію локальної TSDB Prometheus у межах пам'яті та диска вашого сервера. VictoriaMetrics вміє приймати дані Prometheus і надає сумісний із ним API запитів, тож може працювати як довготривале сховище або як бекенд метрик для Grafana. Перевірте її на власному навантаженні, а не переходьте за фіксованим порогом оперативної пам'яті.

Поділитися

Більше з блогу

Продовжуйте читати.

Готові розгортати? Від $2,48/міс.

Незалежна хмара з 2008 року. AMD EPYC, NVMe, 40 Gbps. Повернення коштів за 14 днів.