Если вы пока не знаете, что такое 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
Перед следующим шагом убедитесь, что A-запись DNS для 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 перейдите в Подключения > Data sources > Add data source и выберите 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, поэтому схема «хаб и спицы» работает без доработок.
Перейти к Dashboards > Новинка > Import dashboard, введите 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 опрашивает приватные адреса. Это самый безопасный вариант после первоначальной настройки WireGuard. Мы предлагаем WireGuard как развёртывание в один клик, а ещё у нас есть готовое руководство по настройке по нему.
- Приватная сеть Cloudzy. Инстансы VPS Cloudzy в одном регионе получают приватный интерфейс для трафика «восток-запад», поэтому вы можете опрашивать этот адрес вместо того, чтобы поднимать отдельный туннель WireGuard.
Когда Node Exporter заработает на втором VPS и станет доступен по приватному IP, замените существующий job 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 и предоставляет совместимый с Prometheus API запросов, поэтому может работать как долговременное хранилище или как бэкенд метрик для Grafana. Проверьте её на своей нагрузке, а не переключайтесь по фиксированному порогу ОЗУ.
