ToolsOps

Docker Compose: Prometheus + Grafana en local

Prometheus y Grafana con Docker Compose en local: prometheus.yml, volúmenes para los datos, conectar Grafana a Prometheus por nombre de servicio y qué monitoriza este stack y qué no.

Prometheus recoge métricas y Grafana las pinta en dashboards. Juntos son la forma más común de empezar con monitorización. Esta guía los monta en local para que aprendas el flujo, y es honesta sobre algo que muchos tutoriales callan: qué monitoriza de verdad este stack y qué no.

compose.yaml de Prometheus + Grafana

services:
  prometheus:
    image: prom/prometheus:v2.54.1
    restart: unless-stopped
    ports:
      - "127.0.0.1:9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus_data:/prometheus
  grafana:
    image: grafana/grafana:11.2.0
    restart: unless-stopped
    ports:
      - "127.0.0.1:3000:3000"
    environment:
      GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD}
    depends_on:
      - prometheus
    volumes:
      - grafana_data:/var/lib/grafana

volumes:
  prometheus_data:
  grafana_data:

Prometheus necesita su configuración. Crea un prometheus.yml junto al compose:

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: prometheus
    static_configs:
      - targets: ["localhost:9090"]

Y el .env.example con la contraseña de admin de Grafana:

GRAFANA_ADMIN_PASSWORD=CHANGE_ME

Comprobar que arrancan

docker compose up -d
# Prometheus: estado de los destinos que scrapea
#   http://localhost:9090/targets
# Endpoint de salud de Prometheus
#   http://localhost:9090/-/healthy
# Grafana: login admin / GRAFANA_ADMIN_PASSWORD
#   http://localhost:3000

Si Grafana no carga, revisa docker compose logs grafana: lo más habitual es un problema de permisos en el volumen grafana_data o que el puerto 3000 ya esté ocupado por otra cosa en tu máquina.

Qué monitoriza... y qué no

Aquí está la parte que evita falsas expectativas. Prometheus solo recoge métricas de los destinos que le indicas en scrape_configs. El prometheus.yml de arriba solo se scrapea a sí mismo, así que de entrada solo verás métricas del propio Prometheus.

  • Para monitorizar tu app: tu app debe exponer un endpoint /metrics y tú lo añades como un job nuevo en scrape_configs apuntando a tu-servicio:puerto.
  • Para métricas del host (CPU, memoria, disco) se suele añadir node_exporter como servicio aparte.
  • Lo que esto NO cubre: logs y trazas. La observabilidad completa es más que métricas; este stack es solo la pata de métricas.

Conectar Grafana a Prometheus

En Grafana, al añadir la fuente de datos Prometheus, la URL es http://prometheus:9090: el nombre del servicio, no localhost. Para que el stack sea reproducible y no dependa de clics, puedes dejar la fuente de datos y los dashboards configurados con provisioning (archivos montados en /etc/grafana/provisioning).

En resumen: esto es un excelente banco de pruebas para aprender métricas y dashboards, no un sistema de observabilidad listo para producción.

Siguientes pasos

Genera este stack en el generador de Docker Compose y vuelve al índice de ejemplos.

Preguntas frecuentes

¿Qué monitoriza este stack tal cual?
Casi nada todavía, y es importante entenderlo. Prometheus solo recoge métricas de los destinos que le indicas en scrape_configs. El prometheus.yml de ejemplo solo se scrapea a sí mismo (localhost:9090), así que verás métricas del propio Prometheus, no de tu app ni de tu máquina. Para monitorizar tu app, esta debe exponer un endpoint /metrics y tú añadirlo como job; para el host, se suele añadir node_exporter.
¿Esto es observabilidad de producción?
No. Es un entorno local para aprender Prometheus y Grafana y prototipar dashboards. La observabilidad real incluye también logs y trazas, retención y almacenamiento dimensionados, alta disponibilidad, alertas que llegan a alguien y, a menudo, almacenamiento remoto a largo plazo. Aquí cubres solo la parte de métricas, y en una sola instancia.
En Grafana, ¿qué URL pongo para la fuente de datos Prometheus?
http://prometheus:9090, usando el nombre del servicio, no localhost. Grafana y Prometheus son contenedores distintos en la misma red interna de Compose, así que se encuentran por nombre. Dentro del contenedor de Grafana, localhost sería Grafana.
¿Para qué son los dos volúmenes?
prometheus_data guarda la base de datos de series temporales (las métricas que va recogiendo) en /prometheus. grafana_data guarda la configuración de Grafana en /var/lib/grafana: usuarios, fuentes de datos y dashboards que crees por la interfaz. Sin esos volúmenes, perderías métricas y dashboards en cada docker compose down.
¿Puedo dejar los dashboards y la fuente de datos ya configurados?
Sí, con provisioning. En vez de configurarlo a mano cada vez, Grafana puede leer al arrancar archivos de provisioning montados como volumen (datasources y dashboards en /etc/grafana/provisioning). Es opcional para este ejemplo, pero es lo que harías para que el stack sea reproducible y no dependa de clics.