Якщо ви ще не знаєте, що таке 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 ГБ, але сприймайте це як орієнтир, а не жорстке правило за кількістю хостів.
Що ви побудуєте
Ось як приблизно виглядатиме готова конфігурація.
+-------------------+
| 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 миттєво з 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.
Два хороші варіанти мережевого шляху між хабом і вузлами:
- Мережа WireGuard. Кожен VPS приєднується до мережі WireGuard, а Prometheus збирає метрики з приватних IP-адрес. Після початкового налаштування WireGuard це найбезпечніший варіант. Ми пропонуємо WireGuard як розгортання одним кліком, а ще в нас є готовий посібник із налаштування щодо нього.
- Приватна мережа 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 вгорі на новий сервер, і ви побачите його графіки.
Споживання ресурсів і коли час розширюватися
Ці цифри взято з початкового тесту у квітні 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 варіантів.
Типові проблеми
Сім найчастіших проблем і способи їх усунення.
- Prometheus доступний із публічного інтернету. Звичайне прокидання порту 9090:9090 відкриває Prometheus усьому світу. Рішення: залиште
--web.listen-address=127.0.0.1:9090у команді Prometheus, як показано вище. Тоді Prometheus слухає лише петльовий інтерфейс хоста. - Джерело даних Grafana не може дістатися до Prometheus. Цей стек використовує мережу хоста, тож Grafana звертається до Prometheus за адресою http://127.0.0.1:9090. Перевірте, що Prometheus запущено і він досі слухає петльовий інтерфейс.
- Дашборд Node Exporter показує «No data». Три звичні причини. (a) Prometheus не опитує ціль. Перевірте
/targets. (b) Мітка job у змінній дашборда не збігається зjob_nameв конфігурації збору. (c) Фаєрвол блокує порт 9100 між хабом і ціллю. - Пароль адміністратора Grafana залишився
admin/adminу продакшені. ВстановитиGF_SECURITY_ADMIN_PASSWORDз файлу .env ще до першого запуску. Якщо ви це пропустили, змініть пароль під час першого входу та вимкніть самореєстрацію. - Caddy повідомляє «ACME challenge failed». A-запис DNS ще не поширився або порт 80 заблоковано. Виконайте
ufw allow 80,443/tcp, дочекайтеся поширення DNS і виконайтеsudo systemctl reload caddy. Скористайтесяdig +short, щоб підтвердити поширення. - Диск під Prometheus заповнюється. Мітки з високою кардинальністю або короткі інтервали збору за великої кількості хостів швидко заповнюють том. Стежте за
prometheus_tsdb_head_seriesта розміром тому. Що допоможе: вимкнути невикористовувані колектори Node Exporter, збільшитиscrape_intervalдо 30s або скоротити строк зберігання. - Помилки прав доступу під час 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. Перевірте її на власному навантаженні, а не переходьте за фіксованим порогом оперативної пам'яті.
