Cómo instalar Prometheus con Docker
Índice de contenidos
- Puntos clave
- ¿Qué es Prometheus y cómo funciona el modelo pull?
- ¿Cómo es el docker-compose.yml de Prometheus?
- ¿Cómo definir los targets y el scrape_interval?
- ¿Cómo hacer consultas básicas con PromQL?
- ¿Cómo preparar la integración con Grafana?
- Preguntas frecuentes
- ¿Por qué no debo usar la etiqueta latest de Prometheus?
- ¿Cuántos recursos consume Prometheus?
- ¿Prometheus guarda los datos si borro el contenedor?
- Conclusión
- Fuentes
Prometheus es el sistema de monitorización y alertas de código abierto más extendido para infraestructura self-hosted, y con Docker lo levantas con un solo archivo docker-compose.yml y un prometheus.yml. Recoge métricas mediante un modelo pull, las guarda en su base de datos temporal y las expone en el puerto 9090 listas para consultar con PromQL y visualizar en Grafana.
Prometheus es el estándar de facto para monitorizar servidores y contenedores, y con Docker lo tienes recogiendo métricas en pocos minutos. En esta guía levantas Prometheus con un solo archivo docker-compose.yml, escribes su configuración en prometheus.yml, defines los objetivos (targets) que quieres vigilar, ajustas el intervalo de recogida, haces tus primeras consultas con PromQL y dejas todo preparado para pintar los datos en Grafana. La misma explicación está disponible en inglés.
Puntos clave
- Prometheus es un proyecto graduado de la CNCF (el segundo en graduarse, tras Kubernetes, en agosto de 2018) y hoy es la base de casi cualquier pila de observabilidad self-hosted.
- La versión estable más reciente es Prometheus 3.13.1, publicada el 10 de julio de 2026; la rama 3.13 es la de soporte a largo plazo (LTS).
- Cuidado con la etiqueta
:latest: a día de hoy sigue apuntando a la rama 2 (2.53.5), no a la 3, así que fija siempre una versión concreta comoprom/prometheus:v3.13.1. - Prometheus usa un modelo pull: es él quien va a buscar las métricas a un endpoint HTTP
/metricsde cada objetivo, en el intervalo que definas (scrape_interval). - La interfaz web y la API escuchan en el puerto 9090, y los datos se guardan en una base de datos temporal local con una retención por defecto de 15 días.
¿Qué es Prometheus y cómo funciona el modelo pull?
Prometheus es un sistema de monitorización y alertas de código abierto creado en SoundCloud en 2012 y donado después a la Cloud Native Computing Foundation. Su trabajo consiste en recoger métricas numéricas a lo largo del tiempo (uso de CPU, memoria libre, peticiones por segundo, latencia) y guardarlas como series temporales, es decir, secuencias de valores con su marca de tiempo. Sobre esos datos puedes lanzar consultas, definir alertas y construir cuadros de mando.
La diferencia clave frente a otros sistemas es el modelo pull. En lugar de que cada aplicación envíe sus métricas a un servidor central (modelo push), es Prometheus quien, cada cierto intervalo, hace una petición HTTP a un endpoint /metrics de cada objetivo y se descarga el estado actual. Como resume la documentación oficial, "Prometheus recoge métricas de objetivos raspando (scraping) endpoints HTTP". Ese enfoque simplifica mucho el descubrimiento de servicios y hace trivial saber si un objetivo está caído: si no responde al scrape, la métrica interna up vale 0.
Prometheus no suele trabajar solo. Él recoge y almacena, pero las métricas del sistema operativo las expone un Node Exporter y las de los contenedores un cAdvisor, y la visualización bonita la pone Grafana. Prometheus es el corazón que orquesta la recogida.
¿Cómo es el docker-compose.yml de Prometheus?
Necesitas dos archivos en la misma carpeta: la configuración de Prometheus (prometheus.yml) y el docker-compose.yml que arranca el contenedor y monta esa configuración. Empieza por la configuración mínima:
global:
scrape_interval: 15s
scrape_timeout: 10s
evaluation_interval: 15s
scrape_configs:
- job_name: prometheus
static_configs:
- targets: ["localhost:9090"]
- job_name: node
static_configs:
- targets: ["node-exporter:9100"]
Y ahora el docker-compose.yml, que fija la versión, monta el archivo anterior en modo solo lectura, persiste los datos en un volumen con nombre y publica el puerto solo en la propia máquina:
services:
prometheus:
image: prom/prometheus:v3.13.1
restart: unless-stopped
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--storage.tsdb.retention.time=30d"
- "--web.enable-lifecycle"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prom_data:/prometheus
ports:
- "127.0.0.1:9090:9090"
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:9090/-/healthy"]
interval: 15s
timeout: 5s
retries: 5
volumes:
prom_data:
Conviene fijarse en varios detalles. El volumen con nombre prom_data se monta en /prometheus, la ruta donde Prometheus guarda su base de datos de series temporales (TSDB); si prefieres entender la diferencia entre un volumen con nombre y un bind mount, la explicamos en la guía sobre volúmenes y bind mounts en Docker. La opción --storage.tsdb.retention.time=30d sube la retención de los 15 días por defecto a 30. El indicador --web.enable-lifecycle habilita recargar la configuración sin reiniciar. Y al publicar el puerto como 127.0.0.1:9090:9090 dejas la interfaz accesible solo desde la propia máquina, porque Prometheus no trae autenticación: exponerlo en Internet sin un proxy delante es un riesgo.
Con los dos archivos listos, arranca la pila y comprueba el estado:
docker compose up -d
docker compose ps
docker compose logs -f prometheus
Abre http://127.0.0.1:9090 en el navegador y verás la interfaz de Prometheus. En el menú Status > Targets aparecen los objetivos configurados y si están UP o DOWN.
¿Cómo definir los targets y el scrape_interval?
El bloque global fija el comportamiento por defecto. El scrape_interval es cada cuánto va Prometheus a buscar métricas; 15 segundos es un valor equilibrado para un servidor casero, mientras que en entornos grandes se suele subir a 30 o 60 segundos para reducir carga y almacenamiento. El scrape_timeout es cuánto espera antes de dar por fallida una recogida, y el evaluation_interval cada cuánto evalúa las reglas de alerta.
Cada entrada de scrape_configs es un trabajo (job) con un nombre y una lista de objetivos. En el ejemplo, el job prometheus se monitoriza a sí mismo en localhost:9090, y el job node apunta a node-exporter:9100, usando el nombre del servicio como host: dentro de la red de Compose, el DNS interno de Docker resuelve node-exporter a la IP del contenedor, sin publicar ese puerto al exterior. Para que ese exportador exista, hace falta añadirlo a la misma pila, algo que cubrimos en métricas de host y contenedores con Node Exporter y cAdvisor.
Puedes fijar un intervalo distinto por job cuando un objetivo necesita más resolución (por ejemplo, cAdvisor cada 5 segundos):
- job_name: cadvisor
scrape_interval: 5s
static_configs:
- targets: ["cadvisor:8080"]
Cada vez que edites prometheus.yml, valida la sintaxis y recarga en caliente, sin reiniciar el contenedor, gracias al indicador de lifecycle:
docker compose exec prometheus promtool check config /etc/prometheus/prometheus.yml
curl -X POST http://127.0.0.1:9090/-/reload
¿Cómo hacer consultas básicas con PromQL?
PromQL (Prometheus Query Language) es el lenguaje con el que interrogas las series temporales. En la pestaña Graph de la interfaz puedes escribir expresiones y ver el resultado como tabla o como gráfica. La consulta más sencilla es escribir el nombre de una métrica; por ejemplo, up devuelve 1 o 0 por cada objetivo, según esté vivo o caído.
La mayoría de métricas útiles son contadores que solo suben, así que rara vez se consultan en crudo: se aplica la función rate(), que calcula el incremento por segundo en una ventana de tiempo. Un par de ejemplos habituales:
up
rate(node_cpu_seconds_total{mode="idle"}[5m])
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
La primera dice qué objetivos están activos. La segunda calcula, por cada núcleo, cuántos segundos por segundo pasa la CPU en reposo durante los últimos 5 minutos. La tercera es el truco clásico para obtener el porcentaje de uso de CPU por máquina: promedia el tiempo en reposo y lo resta de 100. Las llaves {...} filtran por etiquetas y by (instance) agrupa el resultado; con estas tres piezas (selección, filtro por etiquetas y funciones de tasa y agregación) cubres el 90 % de las consultas del día a día.
¿Cómo preparar la integración con Grafana?
Prometheus incluye una interfaz web propia, renovada por completo en Prometheus 3.0 (publicado el 14 de noviembre de 2024, el primer salto de versión mayor en unos siete años), pero para cuadros de mando de verdad la herramienta habitual es Grafana. La integración es directa: en Grafana añades una fuente de datos de tipo Prometheus y le indicas la URL http://prometheus:9090, usando de nuevo el nombre del servicio dentro de la red de Compose.
A partir de ahí, en Grafana puedes escribir las mismas consultas PromQL o, más cómodo, importar cuadros de mando ya hechos por su identificador (por ejemplo, el popular panel de Node Exporter tiene el ID 1860). El paso a paso de esa parte lo tienes en la guía de cómo instalar Grafana con Docker. Y cuando quieras publicar Grafana o el propio Prometheus con HTTPS y un dominio, pon delante un proxy inverso como se explica en cómo instalar Traefik con Docker Compose.
Preguntas frecuentes
¿Por qué no debo usar la etiqueta latest de Prometheus?
Porque en Prometheus la etiqueta :latest no apunta a la última versión: a día de hoy sigue resolviendo a la rama 2 (2.53.5), la LTS anterior, y no a la serie 3. Si escribes prom/prometheus:latest esperando las novedades de la versión 3 (nueva interfaz, histogramas nativos, ingesta OTLP), te llevarás una sorpresa. Fija siempre una versión concreta como prom/prometheus:v3.13.1 y decide tú cuándo actualizar.
¿Cuántos recursos consume Prometheus?
Muy pocos para un servidor doméstico. En reposo, con un puñado de objetivos, ronda los 100 o 200 MB de RAM, y el consumo crece con la cardinalidad, es decir, con el número de combinaciones distintas de métrica y etiquetas. El espacio en disco depende de la retención: por defecto guarda 15 días de datos, y puedes ajustarlo con --storage.tsdb.retention.time. Para un homelab con Node Exporter y cAdvisor, unos pocos gigabytes bastan.
¿Prometheus guarda los datos si borro el contenedor?
Sí, siempre que uses un volumen con nombre como en esta guía. El contenedor es efímero, pero el volumen prom_data sobrevive a docker compose down y se vuelve a montar al recrear el servicio. Solo perderías las series temporales si ejecutas docker compose down -v, que elimina también los volúmenes. Aun así, Prometheus está pensado como almacén de métricas a corto plazo, no como copia de seguridad: para retención a largo plazo se usan sistemas como Thanos o Mimir.
Conclusión
Con un docker-compose.yml y un prometheus.yml tienes un servidor Prometheus persistente, recogiendo métricas por su modelo pull, con la interfaz y la API en el puerto 9090 y un healthcheck que confirma que está sano. Es la pieza central de tu observabilidad: añade un Node Exporter y un cAdvisor para alimentarlo, conecta Grafana para los cuadros de mando y protégelo tras un proxy inverso antes de exponerlo. A partir de aquí, cada servicio nuevo de tu infraestructura es un objetivo más que vigilar.