Grafana convierte números sueltos en cuadros de mando que se entienden de un vistazo, y con Docker lo tienes funcionando en pocos minutos. En esta guía levantas Grafana con un solo archivo docker-compose.yml, persistes sus datos en un volumen, añades Prometheus como fuente de datos (con aprovisionamiento automático), importas un cuadro de mando ya hecho por su identificador y lo dejas preparado para publicarlo con HTTPS tras un proxy inverso. La misma explicación está disponible en inglés.

Puntos clave

  • Grafana es la herramienta de visualización de código abierto más popular para infraestructura self-hosted: se conecta a Prometheus, Loki, InfluxDB, PostgreSQL y decenas de fuentes más sin guardar una copia de los datos.
  • La versión estable más reciente es Grafana 13.1.0, publicada el 1 de julio de 2026; usa la imagen grafana/grafana, porque grafana/grafana-oss dejó de actualizarse a partir de la 12.4.0.
  • La interfaz web y la API escuchan en el puerto 3000, y toda la configuración (cuadros de mando, fuentes de datos, usuarios) se guarda en /var/lib/grafana, que debes montar en un volumen para que persista.
  • Las credenciales por defecto son admin / admin y Grafana obliga a cambiarlas en el primer inicio; mejor aún, fija la contraseña de arranque con la variable GF_SECURITY_ADMIN_PASSWORD.
  • El contenedor se ejecuta como el usuario con UID 472, un detalle que importa cuando usas bind mounts en lugar de volúmenes con nombre.

¿Qué es Grafana y para qué sirve?

Grafana es una plataforma de código abierto para consultar, visualizar y alertar sobre datos de series temporales y de otras muchas fuentes. Nació en 2014 como un fork de Kibana centrado en métricas y hoy es la capa de visualización estándar de la observabilidad self-hosted. Su idea central es que Grafana no almacena los datos: se conecta a una fuente de datos externa (Prometheus para métricas, Loki para logs, InfluxDB, Elasticsearch, PostgreSQL, MySQL y muchas más) y dibuja los resultados en paneles interactivos.

Un cuadro de mando (dashboard) de Grafana es un conjunto de paneles, y cada panel ejecuta una consulta contra una fuente de datos y la representa como gráfica de líneas, medidor, tabla o mapa de calor. Sobre esas mismas consultas puedes definir alertas unificadas que avisan por correo, Telegram o un servicio de notificaciones cuando un valor cruza un umbral.

En una pila típica de homelab, Grafana es la cara visible: Prometheus recoge las métricas, Grafana las pinta. Por eso ambos suelen convivir en el mismo docker-compose.yml, y por eso esta guía asume que ya tienes un Prometheus escuchando (si no, empieza por él).

¿Cómo es el docker-compose.yml de Grafana?

El despliegue mínimo cabe en un archivo. Fija una versión concreta de la imagen, guarda los datos en un volumen con nombre, pasa la contraseña del administrador por una variable y publica el puerto 3000 solo en la propia máquina:

services:
  grafana:
    image: grafana/grafana:13.1.0
    restart: unless-stopped
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD:?define GRAFANA_ADMIN_PASSWORD en .env}
      - GF_USERS_ALLOW_SIGN_UP=false
    volumes:
      - grafana_data:/var/lib/grafana
      - ./provisioning:/etc/grafana/provisioning:ro
    ports:
      - "127.0.0.1:3000:3000"
    healthcheck:
      test: ["CMD-SHELL", "wget -q --spider http://localhost:3000/api/health || exit 1"]
      interval: 15s
      timeout: 5s
      retries: 5

volumes:
  grafana_data:

Merece la pena detenerse en varias decisiones. El volumen con nombre grafana_data se monta en /var/lib/grafana, la ruta donde Grafana guarda su base de datos SQLite con los cuadros de mando, las fuentes y los usuarios; 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 contraseña se lee de la variable GRAFANA_ADMIN_PASSWORD de tu archivo .env, y la sintaxis ${VAR:?mensaje} hace que Compose se niegue a arrancar si esa variable no existe, en lugar de dejar la contraseña admin por defecto. La opción GF_USERS_ALLOW_SIGN_UP=false cierra el registro de nuevos usuarios. Y al publicar el puerto como 127.0.0.1:3000:3000 dejas la interfaz accesible solo desde la propia máquina, porque más adelante la sacaremos a Internet a través de un proxy con HTTPS.

Guarda un archivo .env junto al Compose con la contraseña y arranca la pila:

echo "GRAFANA_ADMIN_PASSWORD=una-contrasena-larga-y-unica" > .env
docker compose up -d
docker compose ps
docker compose logs -f grafana

Abre http://127.0.0.1:3000 en el navegador y entra con admin y la contraseña que pusiste en el .env. Si en su lugar prefieres usar Docker secrets en vez de variables de entorno para la contraseña, revisa cómo se gestionan en la guía de variables de entorno y secretos en Docker.

¿Cómo añadir Prometheus como fuente de datos?

Puedes añadir la fuente a mano desde la interfaz (Connections > Data sources > Add data source > Prometheus), pero lo elegante es aprovisionarla con un archivo, para que Grafana la cree sola al arrancar y no dependas de clics. Ese es el motivo del segundo volumen del Compose: montamos una carpeta ./provisioning en /etc/grafana/provisioning, que Grafana lee al iniciarse.

Crea el archivo provisioning/datasources/prometheus.yml con este contenido:

apiVersion: 1

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

La clave es la url: apunta a http://prometheus:9090 usando el nombre del servicio, no una IP. Dentro de la red de Docker Compose, el DNS interno resuelve prometheus a la IP del contenedor, así que Grafana y Prometheus deben compartir la misma red (lo más fácil es tenerlos en el mismo docker-compose.yml). El modo access: proxy hace que sea el servidor de Grafana, y no tu navegador, quien consulte a Prometheus, de modo que el puerto 9090 no necesita estar publicado al exterior.

Recarga la pila para que Grafana lea el aprovisionamiento y verás la fuente ya creada en Connections > Data sources:

docker compose up -d --force-recreate grafana

De la misma forma puedes aprovisionar Loki para centralizar los logs: basta con añadir otro bloque de tipo loki apuntando a http://loki:3100, y así tendrás métricas y registros en el mismo Grafana.

¿Cómo importar un cuadro de mando por su ID?

No hace falta construir los paneles desde cero. La comunidad publica miles de cuadros de mando en el catálogo oficial de grafana.com, cada uno con un identificador numérico. El más famoso para servidores es Node Exporter Full, con el ID 1860, que muestra CPU, memoria, disco y red de la máquina en una sola pantalla.

Para importarlo, ve en la interfaz a Dashboards > New > Import, escribe 1860 en el campo del identificador, pulsa Load, elige tu fuente de datos Prometheus en el desplegable y confirma. En segundos tienes decenas de paneles funcionando, siempre que Prometheus ya esté recogiendo las métricas de un Node Exporter y un cAdvisor.

También puedes automatizar la importación con aprovisionamiento, dejando los ficheros JSON de los cuadros de mando en una carpeta y un archivo de configuración que Grafana lea al arrancar; es lo que se conoce como cuadros de mando como código, ideal para que tu configuración viva en un repositorio y se recree igual en cualquier servidor.

¿Cómo publicar Grafana con Traefik y autenticación?

Mientras trabajas en la propia máquina, el puerto 127.0.0.1:3000 es suficiente. Para acceder a Grafana desde fuera con un dominio y HTTPS, lo correcto es poner delante un proxy inverso en lugar de abrir el puerto 3000 en el cortafuegos. El proceso completo, con certificados automáticos de Let’s Encrypt, está en la guía de cómo instalar Traefik con Docker Compose.

Con Traefik en la misma red, añades unas etiquetas al servicio de Grafana y le indicas a Grafana cuál es su URL pública para que los enlaces y el inicio de sesión funcionen:

    environment:
      - GF_SERVER_ROOT_URL=https://grafana.midominio.com
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.grafana.rule=Host(`grafana.midominio.com`)"
      - "traefik.http.routers.grafana.entrypoints=websecure"
      - "traefik.http.routers.grafana.tls.certresolver=letsencrypt"
      - "traefik.http.services.grafana.loadbalancer.server.port=3000"

Grafana ya trae su propio inicio de sesión, así que no necesitas una capa extra de autenticación como en servicios que no la incluyen. Sí conviene reforzarlo: usa una contraseña de administrador larga, mantén GF_USERS_ALLOW_SIGN_UP=false para que nadie se registre solo y, si expones el panel a Internet, valora activar la autenticación en dos pasos o delegar el inicio de sesión en un proveedor OAuth. La variable GF_SERVER_ROOT_URL es importante: sin ella, algunas redirecciones y los enlaces compartidos apuntarían a localhost:3000 en vez de a tu dominio.

Preguntas frecuentes

¿Por qué Grafana me pide cambiar la contraseña al entrar?

Porque las credenciales de fábrica son admin / admin y Grafana obliga a cambiarlas en el primer inicio de sesión por seguridad. Si has definido GF_SECURITY_ADMIN_PASSWORD en el Compose, entra directamente con esa contraseña y no verás el aviso. Ten en cuenta que esa variable solo fija la contraseña la primera vez que se crea la base de datos: si más adelante la cambias en el archivo, no se aplicará sobre un /var/lib/grafana ya existente; tendrías que restablecerla con grafana-cli admin reset-admin-password.

¿Grafana conserva mis cuadros de mando 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 grafana_data, montado en /var/lib/grafana, sobrevive a docker compose down y se vuelve a montar al recrear el servicio. Solo perderías los cuadros de mando creados a mano si ejecutas docker compose down -v, que elimina también los volúmenes. Para no depender de ese volumen, muchos equipos definen las fuentes y los paneles por aprovisionamiento, de modo que la configuración vive en archivos versionados y se reconstruye idéntica en cualquier máquina.

¿Uso la imagen grafana o grafana-oss?

Usa grafana/grafana. Durante años convivieron dos imágenes: grafana/grafana, con las funciones Enterprise incluidas pero desactivadas salvo licencia, y grafana/grafana-oss, estrictamente de código abierto. A partir de Grafana 12.4.0, el repositorio grafana/grafana-oss en Docker Hub dejó de recibir actualizaciones, así que la opción recomendada y mantenida es grafana/grafana. En ambos casos, no uses la etiqueta :latest en producción: fija una versión concreta como grafana/grafana:13.1.0 y decide tú cuándo actualizar.

Conclusión

Con un docker-compose.yml, un volumen y un archivo de aprovisionamiento tienes un Grafana persistente escuchando en el puerto 3000, con Prometheus ya conectado como fuente de datos y un cuadro de mando profesional importado por su identificador. Es la última pieza de tu observabilidad: alimenta a Grafana con Prometheus para las métricas, añade Loki para los logs y publícalo con HTTPS tras Traefik cuando quieras verlo desde fuera. A partir de aquí, cada nuevo servicio de tu infraestructura cabe en un panel más de tu cuadro de mando.

Fuentes

  1. Documentación oficial de Grafana
  2. Imagen oficial grafana/grafana en Docker Hub
  3. Repositorio y releases de Grafana en GitHub
  4. Ciclo de versiones de Grafana (endoflife.date)

Ruta: Monitorización y observabilidad con Docker