Monitoriza todo tu homelab con Grafana, Prometheus y Uptime Kuma

La regla de las tres preguntas

Cuando empecé a monitorizar mi homelab, cometí el error típico: quería medirlo todo.

CPU, RAM, disco, red, temperatura, contenedores, latencia, certificados, logs, errores, servicios, procesos, tráfico, DNS, almacenamiento, alertas, dashboards… Todo parecía importante.

Hasta que me di cuenta de algo bastante obvio: si mides todo pero no sabes qué decisión tomar con esos datos, no estás monitorizando; estás decorando Grafana.

Ahora lo enfoco de otra manera. Antes de montar nada, me hago tres preguntas:

  1. ¿Están mis servicios accesibles? Para eso uso checks de uptime.
  2. ¿Mi servidor tiene recursos suficientes? Para eso uso métricas del sistema.
  3. ¿Ha pasado algo anómalo mientras dormía? Para eso uso alertas simples.

Tres preguntas. Tres piezas. Nada más.

La monitorización de un homelab no debería convertirse en otro sistema que mantener. Tiene que ayudarte a dormir mejor, no darte más trabajo.


El stack

Para este enfoque uso una combinación bastante sencilla:

  • Uptime Kuma: para saber si los servicios responden.
  • Prometheus: para almacenar métricas.
  • Node Exporter: para exponer métricas del servidor Linux.
  • Grafana: para visualizar esas métricas cuando necesito investigar.

No es el stack más sofisticado del mundo, pero sí uno muy equilibrado para un homelab. Uptime Kuma me avisa si algo cae. Prometheus recoge datos. Grafana me permite mirar tendencias. Y Node Exporter me dice cómo está el servidor.

Importante: este stack monitoriza principalmente disponibilidad y métricas. No es un stack de logs. Para logs entrarían herramientas como Loki, Promtail, Graylog o Elasticsearch, pero eso ya aumenta bastante la complejidad.


Estructura de carpetas

Creamos una carpeta para el stack:

mkdir -p ~/docker/monitoring
cd ~/docker/monitoring

mkdir -p prometheus
mkdir -p grafana/data
mkdir -p grafana/datasources
mkdir -p uptime-kuma

En esta carpeta tendremos:

~/docker/monitoring/
├── docker-compose.yml
├── .env
├── prometheus/
│   └── prometheus.yml
├── grafana/
│   ├── data/
│   └── datasources/
│       └── datasource.yml
└── uptime-kuma/

docker-compose.yml

Crea el archivo:

nano docker-compose.yml

Y pega esto:

services:
  uptime-kuma:
    container_name: uptime-kuma
    image: louislam/uptime-kuma:latest
    ports:
      - "3001:3001"
    volumes:
      - "./uptime-kuma:/app/data"
    networks:
      - monitoring
    restart: unless-stopped

  node-exporter:
    container_name: node-exporter
    image: prom/node-exporter:latest
    ports:
      - "9100:9100"
    volumes:
      - "/proc:/host/proc:ro"
      - "/sys:/host/sys:ro"
      - "/:/rootfs:ro,rslave"
    command:
      - "--path.procfs=/host/proc"
      - "--path.sysfs=/host/sys"
      - "--path.rootfs=/rootfs"
      - "--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)"
    networks:
      - monitoring
    restart: unless-stopped

  prometheus:
    container_name: prometheus
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    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=30d"
      - "--web.enable-lifecycle"
    networks:
      - monitoring
    restart: unless-stopped
    depends_on:
      - node-exporter

  grafana:
    container_name: grafana
    image: grafana/grafana:latest
    ports:
      - "3002:3000"
    volumes:
      - "./grafana/data:/var/lib/grafana"
      - "./grafana/datasources:/etc/grafana/provisioning/datasources:ro"
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
      - GF_USERS_ALLOW_SIGN_UP=false
    networks:
      - monitoring
    restart: unless-stopped
    depends_on:
      - prometheus

networks:
  monitoring:
    name: monitoring

volumes:
  prometheus_data:

Notas importantes:

  • No he puesto version: "3.8". En Docker Compose moderno ya no es necesario y suele generar avisos.
  • Grafana queda publicado en 3002 porque internamente usa 3000, y normalmente ese puerto ya lo tienes ocupado por otros servicios como Open WebUI.
  • Prometheus conserva métricas 30 días. Para un homelab suele ser suficiente.
  • Node Exporter está montado para medir el host Linux, no solo el contenedor.
  • No instalo plugins extra de Grafana. El datasource de Prometheus viene integrado, y el viejo plugin grafana-piechart-panel ya no suele hacer falta.

variables .env

Crea el archivo:

nano .env

Y añade:

GRAFANA_PASSWORD=cambia-esta-contrasena

Obvio, pero importante: no dejes esa contraseña tal cual. Usa una contraseña fuerte, especialmente si vas a acceder a Grafana desde más dispositivos.


Configuración de Prometheus

Crea el archivo:

nano prometheus/prometheus.yml

Y pega:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: "prometheus"
    static_configs:
      - targets:
          - "prometheus:9090"

  - job_name: "node"
    static_configs:
      - targets:
          - "node-exporter:9100"

La parte clave es el job_name: "node", porque muchos dashboards de Grafana para Node Exporter esperan precisamente ese nombre de job. El dashboard 1860, por ejemplo, está pensado para métricas de Node Exporter y funciona muy bien como punto de partida.

Si más adelante quieres monitorizar más servidores, puedes añadirlos como targets adicionales:

  - job_name: "node"
    static_configs:
      - targets:
          - "node-exporter:9100"
          - "192.168.1.20:9100"
          - "192.168.1.30:9100"

Eso sí: en esos otros servidores también tendrás que tener Node Exporter corriendo.


Configuración de la fuente de datos en Grafana

Crea el archivo:

nano grafana/datasources/datasource.yml

Y pega:

apiVersion: 1

datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://prometheus:9090
    isDefault: true
    editable: true

Con esto, Grafana ya arrancará sabiendo dónde está Prometheus. No tendrás que configurarlo a mano desde la interfaz.


Paso 1: Arranca todo

Levanta el stack:

docker compose up -d

Comprueba que los contenedores están vivos:

docker ps

Y revisa logs si algo falla:

docker logs uptime-kuma
docker logs prometheus
docker logs node-exporter
docker logs grafana

Abre:

  • Uptime Kuma: http://IP-DE-TU-SERVIDOR:3001
  • Prometheus: http://IP-DE-TU-SERVIDOR:9090
  • Grafana: http://IP-DE-TU-SERVIDOR:3002

En Grafana entrarás con:

  • Usuario: admin
  • Contraseña: la que hayas puesto en .env

Paso 2: Configura los checks en Uptime Kuma

Uptime Kuma es lo primero que configuro porque responde a la pregunta más importante: ¿mis servicios responden?

En el panel de Uptime Kuma, añade monitores para tus servicios principales.

Servicio Tipo Destino Intervalo
Vaultwarden HTTP(s) https://vaultwarden.tudominio.com 60s
Home Assistant HTTP(s) http://192.168.1.50:8123 60s
AdGuard Home HTTP(s) http://192.168.1.60:8081 60s
Pi-hole DNS DNS 192.168.1.61 60s
Caddy HTTP(s) https://tudominio.com 60s
Docker host Ping 192.168.1.10 60s
Certificado SSL Certificate Expiry tudominio.com 6h

Matiz importante: para comprobar WireGuard, un simple ping a la IP pública no te dice si WireGuard funciona. Puede decirte si tu conexión responde, pero WireGuard usa UDP y puede no responder a un ping como esperas.

Para WireGuard, yo haría una de estas dos cosas:

  • Monitorizar que el servidor donde corre WireGuard está vivo.
  • Crear un check interno desde fuera o desde otro nodo que compruebe que puedes llegar a una IP dentro de la VPN.

Para un homelab sencillo, no me obsesionaría. Lo importante es saber si tus servicios críticos están arriba y si puedes acceder a ellos.


Dashboard principal de Uptime Kuma mostrando el estado en tiempo real de servicios monitoreados con indicadores de disponibilidad
Dashboard de Uptime Kuma con todos tus servicios monitorizados en tiempo real.

Paso 3: Configura notificaciones por Telegram

Las alertas tienen que llegar donde las mires de verdad.

En mi caso, Telegram funciona mejor que cualquier dashboard. No necesito mirar una pantalla 24/7. Necesito enterarme cuando algo cambia de estado.

En Uptime Kuma:

  1. Ve a Settings → Notifications.
  2. Añade una nueva notificación.
  3. Selecciona Telegram.
  4. Introduce el bot token y el chat ID.
  5. Guarda y prueba el envío.

Después, en cada monitor importante, asigna esa notificación.

Mi regla es simple:

  • Notificar cuando un servicio cae.
  • Notificar cuando se recupera.
  • No notificar cada pequeño cambio irrelevante.
  • No crear alertas que no voy a atender.

La alerta que no piensas mirar es ruido. Y el ruido, en monitorización, es veneno.


Paso 4: Importa un dashboard en Grafana

Grafana sin dashboards no sirve de mucho. Y diseñar uno desde cero está bien para aprender, pero no hace falta empezar por ahí.

Para métricas de servidor, el dashboard clásico es:

1860 - Node Exporter Full

Para importarlo:

  1. Entra en Grafana.
  2. Ve a Dashboards → New → Import.
  3. Introduce el ID 1860.
  4. Selecciona Prometheus como datasource.
  5. Importa.

Verás CPU, RAM, disco, red, carga, filesystem y muchas métricas más.

Mi consejo: no intentes entender todo el dashboard el primer día. Empieza mirando cuatro cosas:

  • CPU: si hay carga sostenida o picos raros.
  • RAM: si el sistema está entrando en swap.
  • Disco: si algún volumen se está llenando.
  • Red: si hay tráfico raro o caídas.

Con eso ya tienes el 80% del valor.

¿Y Docker?

Node Exporter mide el host Linux, no los contenedores Docker de forma detallada.

Si quieres métricas por contenedor, tienes varias opciones:

  • cAdvisor: clásico para métricas de contenedores.
  • Docker daemon metrics: Docker puede exponer métricas para Prometheus configurando el daemon.
  • Portainer: si quieres algo más visual y menos Prometheus.

Yo no lo metería de entrada. Para un homelab sencillo, primero host + uptime. Si luego necesitas saber qué contenedor consume más, añades esa capa.


Paso 5: Alertas: Uptime Kuma primero, Prometheus después

He aprendido por las malas que cuantas más alertas configuras, menos caso les haces.

Por eso sigo una regla muy simple: en un homelab, primero alertas de disponibilidad; después, si hace falta, alertas de métricas.

Uptime Kuma es perfecto para lo básico:

  • Un servicio se cae.
  • Un servicio se recupera.
  • Un certificado está próximo a caducar.
  • Un endpoint deja de responder.
  • Un DNS no resuelve.

¿Se puede alertar desde Prometheus? Por supuesto. Y en entornos serios lo normal es usar Prometheus con Alertmanager. Alertmanager agrupa, deduplica, enruta, silencia y gestiona alertas de forma mucho más potente.

Pero para un homelab personal, mi opinión es esta: si empiezas montando Alertmanager antes de tener claro qué quieres alertar, probablemente estás complicando demasiado el sistema.

Yo empezaría así:

  • Uptime Kuma: alertas reales que quiero recibir sí o sí.
  • Grafana: mirar métricas cuando algo falla o cuando investigo tendencias.
  • Prometheus: almacenar datos y servirlos a Grafana.
  • Alertmanager: solo si el homelab crece y necesitas alertas de métricas de verdad.

Ejemplo de alerta útil en un homelab:

  • Disco por encima del 90% durante varias horas.
  • Servidor sin espacio libre.
  • Certificado a punto de caducar.
  • Servicio crítico caído más de 2 minutos.
  • DNS local no responde.

Ejemplo de alerta que suele acabar siendo ruido:

  • CPU alta durante 30 segundos.
  • RAM usada al 80% sin contexto.
  • Un contenedor reiniciado una vez.
  • Latencia puntual de una web externa.

Monitorizar no va de enterarte de todo. Va de enterarte de lo importante.


Configuración de alertas en Grafana con reglas de Prometheus para monitorización del homelab

Configuración de alertas en Grafana usando métricas de Prometheus.

¿Y para logs?

Este stack no es de logs. Es importante decirlo claro.

Uptime Kuma te dice si algo responde. Prometheus guarda métricas. Grafana te las pinta. Node Exporter te muestra el estado del servidor.

Pero si necesitas investigar logs, necesitas otra capa.

Opciones:

  • docker logs: suficiente para empezar.
  • Loki + Promtail: buena combinación si ya usas Grafana.
  • Graylog: potente, pero más pesado.
  • ELK/OpenSearch: muy potente, pero demasiado para muchos homelabs.

Para mi caso, normalmente tiro de:

docker logs nombre-contenedor
docker logs --tail=200 nombre-contenedor
docker logs -f nombre-contenedor

Si algo llama la atención, reviso manualmente. Y si tengo muchos logs o quiero ayuda para encontrar patrones, puedo pasarlos a un modelo local con Ollama o LM Studio, como explico en el artículo de IA local en el homelab.

Pero no metería Loki o Graylog solo por meterlos. Primero una necesidad real. Luego la herramienta.


Seguridad: no publiques los paneles a Internet

Esto parece obvio, pero conviene repetirlo.

No publiques directamente a Internet:

  • Grafana.
  • Prometheus.
  • Node Exporter.
  • Uptime Kuma.

Prometheus y Node Exporter no están pensados para quedar expuestos alegremente. Grafana y Uptime Kuma tienen login, sí, pero eso no significa que deban estar abiertos al mundo sin más.

Mi recomendación:

  • Acceso solo desde LAN.
  • O acceso remoto mediante WireGuard/Tailscale.
  • O reverse proxy con HTTPS, autenticación fuerte y restricciones adicionales si sabes lo que haces.

En un homelab, muchas veces la opción más segura y simple es: no expongas nada; entra por VPN.


Página de estado pública creada con Uptime Kuma mostrando el historial de uptime de los servicios del homelab

Página de estado pública generada con Uptime Kuma para compartir el estado de tu infraestructura.

Lo que he aprendido monitorizando mi homelab

Después de meses con este enfoque, esto es lo que he aprendido:

  1. El 90% de las alertas que configuré al principio eran ruido. Las he ido eliminando hasta quedarme con las imprescindibles.
  2. Uptime Kuma es lo que más valor me da en el día a día. Si algo cae, me entero. Eso es lo primero.
  3. Grafana es para investigar, no para mirar compulsivamente. Lo abro cuando algo falla o cuando quiero entender una tendencia.
  4. Prometheus consume menos de lo que parece en un homelab pequeño. Pero el consumo depende del número de targets, métricas, intervalo de scraping y retención.
  5. Las alertas por Telegram funcionan mejor que cualquier panel permanente. No necesito una pantalla 24/7. Necesito saber cuándo algo importante cambia.
  6. Si una alerta no implica una acción, probablemente sobra. Esta regla me ha ahorrado muchísimo ruido.

Lo más importante no es tener muchas herramientas. Es tener claro qué pregunta responde cada una.


Resumen

Este stack no intenta convertir tu homelab en un NOC empresarial. Y precisamente por eso funciona.

Pregunta Herramienta Respuesta
¿El servicio responde? Uptime Kuma Disponible o caído
¿El servidor tiene recursos? Node Exporter + Prometheus CPU, RAM, disco, red
¿Qué ha pasado? Grafana Tendencias y métricas visuales
¿Me tengo que enterar? Uptime Kuma + Telegram Alertas simples y accionables

Mi recomendación es empezar pequeño:

  • Primero Uptime Kuma.
  • Después Prometheus + Node Exporter.
  • Luego Grafana.
  • Y solo si lo necesitas, logs y alertas avanzadas.

La monitorización buena no es la que más datos recoge. Es la que te avisa a tiempo, te ayuda a entender qué ha pasado y no te convierte el homelab en otro trabajo.


¿Tú cómo monitorizas tu homelab? ¿Usas Uptime Kuma, Grafana, Prometheus, Netdata, Zabbix o algo más simple? Cuéntalo en los comentarios — siempre se aprende de otras configuraciones.

Artículos relacionados:

Lectura desde Gestión TIC

Monitorizar no es poner gráficas bonitas. Desde gestión TIC, es una forma de detectar antes, responder mejor y tener evidencias de lo que ocurre. Cuando un servicio cae, la diferencia está en enterarte por una alerta o por un usuario. Herramientas como Grafana, Prometheus o Uptime Kuma no sustituyen a una buena gestión, pero ayudan a ver tendencias, anticipar problemas y reducir el impacto cuando algo falla.


Artículos relacionados

Deja un comentario