El problema#
Después de pasar meses ejecutando contenedores en mi servidor doméstico, me cansé de descubrir problemas cuando las cosas ya estaban rotas. Un contenedor consumiendo toda la memoria. Un volumen lleno sin aviso. Necesitaba visibilidad real sobre lo que ocurría en mi infraestructura.
Decidí implementar un stack de monitorización con Prometheus y Grafana. Aquí documento exactamente cómo lo hice.
Arquitectura elegida#
- Prometheus: recopila métricas de Docker
- cAdvisor: expone métricas de contenedores
- Grafana: visualiza todo en dashboards
- Alertmanager: notifica cuando algo falla
Paso 1: Docker Compose con el stack completo#
Creé un archivo docker-compose.yml que levanta todo junto:
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- ./alertas.yml:/etc/prometheus/alertas.yml
- prometheus_data:/prometheus
ports:
- "9090:9090"
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
networks:
- monitoring
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
ports:
- "8080:8080"
networks:
- monitoring
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
networks:
- monitoring
alertmanager:
image: prom/alertmanager:latest
container_name: alertmanager
volumes:
- ./alertmanager.yml:/etc/alertmanager/alertmanager.yml
- alertmanager_data:/alertmanager
ports:
- "9093:9093"
networks:
- monitoring
volumes:
prometheus_data:
grafana_data:
alertmanager_data:
networks:
monitoring:
driver: bridgePaso 2: Configurar Prometheus#
Archivo prometheus.yml:
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
rule_files:
- '/etc/prometheus/alertas.yml'
scrape_configs:
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']Paso 3: Definir las alertas#
Archivo alertas.yml:
groups:
- name: docker_alerts
interval: 10s
rules:
- alert: HighCPUUsage
expr: 'rate(container_cpu_usage_seconds_total[5m]) > 0.8'
for: 2m
annotations:
summary: "CPU alta en contenedor {{ $labels.name }}"
description: "{{ $labels.name }} está usando {{ $value | humanizePercentage }} de CPU"
- alert: HighMemoryUsage
expr: 'container_memory_usage_bytes / container_spec_memory_limit_bytes > 0.85'
for: 2m
annotations:
summary: "Memoria alta en {{ $labels.name }}"
description: "Uso de memoria: {{ $value | humanizePercentage }}"
- alert: DiskSpaceRunningOut
expr: 'node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} < 0.1'
for: 5m
annotations:
summary: "Espacio en disco por debajo del 10%"Paso 4: Configurar Alertmanager#
Archivo alertmanager.yml:
global:
resolve_timeout: 5m
route:
receiver: 'console'
group_by: ['alertname']
group_wait: 10s
group_interval: 10s
repeat_interval: 1h
receivers:
- name: 'console'
webhook_configs:
- url: 'http://localhost:5001/'Paso 5: Iniciar y verificar#
docker-compose up -dAcceso:
- Prometheus:
http://localhost:9090 - Grafana:
http://localhost:3000 - cAdvisor:
http://localhost:8080
Paso 6: Crear dashboards en Grafana#
En Grafana importé el dashboard público 893 (Docker and Host Monitoring) que funciona directo con cAdvisor.
Resultado#
Ahora tengo visibilidad completa. Recibo alertas cuando:
- Un contenedor consume más del 80% de CPU durante 2 minutos
- La memoria supera el 85% del límite
- El disco cae por debajo del 10%
El setup completo ocupa menos de 500MB de RAM en reposo y me ha ahorrado ya varios sustos. Vale la pena.
Equipamiento recomendado#
- Raspberry Pi 3 B+ — Servidor ligero de bajo consumo para empezar tu homelab
- Raspberry Pi 4 (4GB) — La base perfecta para homelab, Docker y monitorización
Enlaces de afiliado. Sin coste extra para ti.