Подробный гайд: Развертывание Grafana + Prometheus + Экспортеры через Docker Compose
Этот гайд описывает production-ready стек мониторинга на базе официальных образов.
Стек включает:
- Prometheus – сбор и хранение метрик
- Grafana – визуализация и алертинг
- Node Exporter – метрики хоста (CPU, RAM, Disk, Network, OS)
- cAdvisor – метрики Docker-контейнеров
Важно:
node-exporterкорректно работает только на Linux. На Docker Desktop (macOS/Windows) он будет собирать метрики внутренней Linux-VM, а не вашей хост-ОС.
1. Структура проекта
Создайте директорию и следующую структуру файлов:
mkdir monitoring-stack && cd monitoring-stack
mkdir -p prometheus grafana/provisioning/datasources grafana/provisioning/dashboards
touch docker-compose.yml .env
touch prometheus/prometheus.yml
touch grafana/provisioning/datasources/datasources.yml
touch grafana/provisioning/dashboards/dashboards.yml
Итоговое дерево:
monitoring-stack/
├── docker-compose.yml
├── .env
├── prometheus/
│ └── prometheus.yml
└── grafana/
└── provisioning/
├── datasources/
│ └── datasources.yml
└── dashboards/
└── dashboards.yml
2. Файлы конфигурации
Файл .env (секреты и параметры)
# Grafana
GF_SECURITY_ADMIN_USER=admin
GF_SECURITY_ADMIN_PASSWORD=your_strong_password_here
GF_USERS_ALLOW_SIGN_UP=false
# Prometheus (хранение метрик)
PROMETHEUS_RETENTION_TIME=30d
PROMETHEUS_STORAGE_RETENTION_SIZE=10GB
Файл prometheus/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_timeout: 10s
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
- job_name: "node-exporter"
static_configs:
- targets: ["node-exporter:9100"]
- job_name: "cadvisor"
static_configs:
- targets: ["cadvisor:8080"]
metrics_path: /metrics
Файл grafana/provisioning/datasources/datasources.yml
Автоматически подключит Prometheus при первом запуске Grafana.
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: false
Файл grafana/provisioning/dashboards/dashboards.yml
Указывает Grafana, откуда брать дашборды.
apiVersion: 1
providers:
- name: "default"
orgId: 1
folder: "Monitoring"
type: file
disableDeletion: false
editable: true
updateIntervalSeconds: 30
options:
path: /var/lib/grafana/dashboards
3. Файл docker-compose.yml
services:
prometheus:
image: prom/prometheus:v2.53.0
container_name: prometheus
restart: unless-stopped
user: "nobody"
read_only: true
tmpfs:
- /tmp
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=${PROMETHEUS_RETENTION_TIME:-30d}'
- '--storage.tsdb.retention.size=${PROMETHEUS_STORAGE_RETENTION_SIZE:-10GB}'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--web.enable-lifecycle'
ports:
- "9090:9090"
networks:
- monitoring
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:9090/-/healthy"]
interval: 30s
timeout: 5s
retries: 3
grafana:
image: grafana/grafana:11.1.0
container_name: grafana
restart: unless-stopped
user: "472"
read_only: true
tmpfs:
- /var/lib/grafana/plugins
- /tmp
volumes:
- grafana-data:/var/lib/grafana
- ./grafana/provisioning/datasources:/etc/grafana/provisioning/datasources:ro
- ./grafana/provisioning/dashboards:/etc/grafana/provisioning/dashboards:ro
- ./grafana/dashboards:/var/lib/grafana/dashboards:ro
environment:
GF_SECURITY_ADMIN_USER: ${GF_SECURITY_ADMIN_USER:-admin}
GF_SECURITY_ADMIN_PASSWORD: ${GF_SECURITY_ADMIN_PASSWORD:-admin}
GF_USERS_ALLOW_SIGN_UP: ${GF_USERS_ALLOW_SIGN_UP:-false}
ports:
- "3000:3000"
networks:
- monitoring
depends_on:
prometheus:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:3000/api/health || exit 1"]
interval: 30s
timeout: 5s
retries: 3
node-exporter:
image: prom/node-exporter:v1.8.2
container_name: node-exporter
restart: unless-stopped
pid: host
network_mode: host
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--path.rootfs=/rootfs'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
- '--web.listen-address=:9100'
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.49.1
container_name: cadvisor
restart: unless-stopped
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
devices:
- /dev/kmsg
privileged: true
ports:
- "8080:8080"
networks:
- monitoring
networks:
monitoring:
driver: bridge
volumes:
prometheus-data:
grafana-data:
Примечание по версиям:
- В production рекомендуется фиксировать теги, а не использовать
latest. Указанные версии стабильны на момент 2026 года. В конфигурации исправлены названия volume для корректной работы Docker Compose.
4. Запуск и первичная настройка
1. Запуск стека:
docker compose up -d
2. Проверка логов:
docker compose logs -f prometheus
docker compose logs -f grafana
3. Доступ:
- Prometheus:
http://<IP>:9090-> Status -> Targets (все должны быть UP) - Grafana:
http://<IP>:3000-> Логин:admin, Пароль: из.env
4. Добавление дашбордов:
- В Grafana откройте Dashboards -> Browse. Дашборды появятся автоматически благодаря provisioning.
Или импортируйте вручную через Import:
- Node Exporter Full:
1860 - Docker & System Monitor (cAdvisor):
14282или19319
5. Перезагрузка конфига Prometheus без рестарта:
curl -X POST http://localhost:9090/-/reload
5. Как добавить другие экспортеры
Принцип одинаков для любого экспортера:
- Добавить сервис в
docker-compose.yml - Добавить
job_nameвprometheus.yml - Перезапустить или перезагрузить стек
Пример: PostgreSQL Exporter
# docker-compose.yml (добавить в services)
postgres-exporter:
image: prometheuscommunity/postgres-exporter:v0.15.0
container_name: postgres-exporter
restart: unless-stopped
environment:
DATA_SOURCE_NAME: "postgresql://monitor_user:password@host.docker.internal:5432/yourdb?sslmode=disable"
ports:
- "9187:9187"
networks:
- monitoring
# prometheus/prometheus.yml (добавить в scrape_configs)
- job_name: "postgres"
static_configs:
- targets: ["postgres-exporter:9187"]
Аналогично добавляются:
mysql-exporter,redis-exporter,blackbox-exporter,snmp-exporter,node-exporterдля удалённых хостов (черезfile_sd_configsилиec2_sd_configs/consul_sd_configs).
6. Рекомендации для Production
| Категория | Рекомендация |
|---|---|
| Сеть | Не открывайте порты 9090 и 9100 наружу. Используйте reverse-proxy (Nginx/Traefik/Caddy) с HTTPS и базовой авторизацией. |
| Безопасность | В .env используйте сильные пароли. Отключите GF_USERS_ALLOW_SIGN_UP. Настройте OAuth/LDAP в Grafana. |
| Хранение | Для долгосрочного хранения подключите Thanos, VictoriaMetrics или Cortex. Prometheus не предназначен для хранения более 1-2 лет. |
| Алертинг | Добавьте alertmanager в compose. Настройте правила в prometheus/rules/ и роутинг в Grafana/Slack/Telegram. |
| Резервное копирование | Делайте снапшоты prometheus-data и grafana-data или используйте штатные механизмы бэкапа Grafana. |
| Мониторинг самого стека | Добавьте self-monitoring job в Prometheus. Следите за prometheus_tsdb_head_series, grafana_alerting_notification_sent_total, node_filesystem_avail_bytes. |
| Ресурсы | Ограничьте контейнеры через deploy.resources (CPU/Memory), особенно для Prometheus под нагрузкой. |
Пример ограничения ресурсов в compose:
deploy:
resources:
limits:
cpus: '2.0'
memory: 4G
reservations:
cpus: '1.0'
memory: 2G
Заключение
Вы получили полностью автоматизированный стек мониторинга с:
- Provisioning Grafana (источники данных + дашборды)
- Безопасной конфигурацией (read_only, user, tmpfs, healthchecks)
- Готовыми экспортерами для хоста и контейнеров
- Возможностью масштабирования и подключения алертинга