Стек мониторинга через Docker Compose
version: '3.9'
services:
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin123
volumes:
- grafana-data:/var/lib/grafana
node-exporter:
image: prom/node-exporter:latest
pid: host
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
volumes:
prometheus-data:
grafana-data:
prometheus.yml: конфигурация сбора метрик
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']
- job_name: 'nginx'
static_configs:
- targets: ['nginx-exporter:9113']
Полезные PromQL запросы
# CPU utilization
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# RAM usage %
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
# Disk free
node_filesystem_avail_bytes{mountpoint="/"} / 1024 / 1024 / 1024
Разбор типичных ошибок
В Grafana дашборд показывает No data, хотя контейнер Prometheus запущен — чаще всего Prometheus не может достучаться до экспортёра или сама Grafana смотрит не на тот datasource.
# В интерфейсе Prometheus (http://ВАШ_IP:9090/targets)
node (0/1 up)
Get "http://node-exporter:9100/metrics": dial tcp: lookup node-exporter on 127.0.0.11:53: no such host
Эта ошибка означает, что контейнеры не видят друг друга по имени сервиса — обычно потому что они объявлены в разных docker-compose.yml без общей сети. Все три сервиса — prometheus, grafana и node-exporter — обязаны быть в одном файле compose или подключены к одной внешней networks.
Ошибка context deadline exceeded в логах Prometheus при скрейпе означает, что экспортёр отвечает дольше scrape_timeout (по умолчанию равен scrape_interval). Обычно это симптом перегруженного сервера или экспортёра, который сам ждёт медленный источник данных — например, mysqld-exporter при недоступной базе.
Сравнение способов сбора метрик
| Способ | Что нужно | Когда использовать |
|---|---|---|
| node_exporter | Метрики ОС: CPU, RAM, диск, сеть | Базовый мониторинг любого Linux-сервера |
| nginx-exporter | Отдельный модуль stub_status в Nginx | Метрики запросов, соединений, кодов ответа |
| mysqld-exporter | Пользователь MySQL с правами PROCESS/REPLICATION | Метрики запросов, соединений, репликации БД |
| Приложение с /metrics | Встроенная библиотека клиента Prometheus | Бизнес-метрики самого приложения |
Когда этот стек избыточен
- Один небольшой VPS с одним сайтом — разворачивать три контейнера и разбираться с PromQL ради базовых графиков CPU и RAM избыточно, для этого хватает Netdata с готовым дашбордом из коробки.
- Нужен только внешний контроль доступности сайта, а не внутренние метрики сервера — это задача для аптайм-мониторов вроде UptimeRobot, а не для Prometheus.
- Команда не готова поддерживать хранилище метрик — без настройки retention и ресурсов под TSDB Prometheus на активном проекте быстро съедает диск и требует регулярного внимания.
Сколько диска съедает Prometheus
По умолчанию Prometheus хранит данные 15 дней (--storage.tsdb.retention.time=15d). Практическая оценка объёма — около 1–2 байт на семпл после сжатия; при интервале сбора 15 секунд и паре сотен временных рядов на небольшом стеке из трёх сервисов это обычно 200–500 МБ за две недели, но с ростом числа экспортёров и меток растёт нелинейно.
services:
prometheus:
image: prom/prometheus:latest
command:
- '--storage.tsdb.retention.time=15d'
- '--storage.tsdb.retention.size=2GB'
- '--config.file=/etc/prometheus/prometheus.yml'
Параметр retention.size — страховка от переполнения диска: Prometheus удалит старые блоки данных раньше срока retention.time, если общий объём превысит лимит, вместо того чтобы упасть с ошибкой нехватки места.
Проверка результата
- Откройте
http://ВАШ_IP:9090/targets— все job'ы должны быть в статусеUP, а неDOWN. - Откройте Grafana на
http://ВАШ_IP:3000, добавьте datasource Prometheus с адресомhttp://prometheus:9090(имя сервиса из compose, не localhost) и импортируйте дашборд по ID. - Выполните тестовый PromQL-запрос
up— он должен вернуть1для каждого работающего экспортёра. - Проверьте, что данные переживают перезапуск контейнера:
docker compose restart prometheus grafana, после чего старые графики должны остаться на месте благодаря именованным томам.
Если задача — просто быстрый обзор ресурсов без Docker и PromQL, посмотрите статью про Netdata. Сам стек удобно поднимать через Docker Compose, если ещё не знакомы с этим инструментом.