El problema#
Después de meses corriendo varios contenedores en mi servidor doméstico, me pasó lo inevitable: un servicio se fue al piso sin que me enterara. Necesitaba visibilidad sobre qué estaba pasando con mis contenedores. Así que arremangué y configuré Prometheus + Grafana + Alertmanager. Acá está cómo lo hice.
Qué necesitas#
- Docker y Docker Compose instalados
- Un servidor con recursos suficientes (en mi caso un viejo i5 con 8GB de RAM)
- Paciencia para debuggear YAML
Paso 1: Configurar cAdvisor#
Primero necesitamos que Docker exponga métricas. Voy a usar cAdvisor, que es el exporter oficial de Google para contenedores.
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
ports:
- "8080:8080"
restart: unless-stoppedAccedé a http://localhost:8080 y verificá que las métricas estén disponibles en /metrics.
Paso 2: Instalar Prometheus#
Prometheus es quien scrappea las métricas. Creé un prometheus.yml:
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']
- job_name: 'docker'
static_configs:
- targets: ['localhost:9323']
alerting:
alertmanagers:
- static_configs:
- targets: ['alertmanager:9093']
rule_files:
- '/etc/prometheus/alerts.yml'En el docker-compose:
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- ./alerts.yml:/etc/prometheus/alerts.yml
- prometheus_data:/prometheus
ports:
- "9090:9090"
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
restart: unless-stoppedPaso 3: Reglas de alertas#
Creé alerts.yml con reglas básicas:
groups:
- name: docker
interval: 30s
rules:
- alert: ContainerHighCPU
expr: (rate(container_cpu_usage_seconds_total[5m]) * 100) > 80
for: 5m
annotations:
summary: "{{ $labels.name }} tiene CPU alta"
- alert: ContainerHighMemory
expr: (container_memory_working_set_bytes / 1073741824) > 2
for: 5m
annotations:
summary: "{{ $labels.name }} usa más de 2GB de RAM"Paso 4: Alertmanager con correo#
Alertmanager es quien envía las notificaciones. Configuré alertmanager.yml:
global:
resolve_timeout: 5m
smtp_smarthost: 'smtp.gmail.com:587'
smtp_auth_username: 'tu-email@gmail.com'
smtp_auth_password: 'tu-app-password'
smtp_from: 'tu-email@gmail.com'
route:
receiver: 'email'
repeat_interval: 1h
receivers:
- name: 'email'
email_configs:
- to: 'tu-email@gmail.com'
headers:
Subject: 'Alerta de Docker: {{ .GroupLabels.alertname }}'Nota: Para Gmail necesitas una app password, no tu contraseña normal.
En docker-compose:
alertmanager:
image: prom/alertmanager:latest
volumes:
- ./alertmanager.yml:/etc/alertmanager/alertmanager.yml
- alertmanager_data:/alertmanager
ports:
- "9093:9093"
restart: unless-stoppedPaso 5: Grafana para visualizar#
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana_data:/var/lib/grafana
restart: unless-stoppedAccedé a http://localhost:3000, configuré Prometheus como datasource y descargué un dashboard público de Docker. Yo uso este.
Resultado#
Ahora veo en tiempo real qué está pasando con mis contenedores. Cuando algo se dispara, recibo un correo en menos de un minuto. No es monitoreo de nivel enterprise, pero para casa funciona perfectamente.
Lo más importante: dormía mejor sabiendo que si algo explota, me entero.