Cómo actualizar de Grafana 12 a Grafana 13 en Docker sin romper los dashboards
Índice de contenidos
- Puntos clave
- Qué cambia en Grafana 13 y qué te afecta
- Paso 1: prepara un Grafana 12 con datasource y dashboards aprovisionados
- Paso 2: escribe el script que usa ids numéricos
- Paso 3: haz la copia de seguridad de grafana.db
- Paso 4: sube la imagen a Grafana 13 y mira qué se rompe
- Paso 5: corrige las llamadas para usar uid
- Cómo volver atrás si algo falla
- Qué revisar fuera de mi laboratorio
- Preguntas frecuentes
- ¿Qué versión de Grafana 13 debo instalar?
- ¿Se rompen los dashboards al actualizar a Grafana 13?
- ¿Puedo seguir usando las API por id numérico?
- Conclusión
- Fuentes
Al pasar de Grafana 12.4.12 a 13.2.3 en Docker, mis dos dashboards siguieron funcionando, pero un script que consultaba Prometheus por id numérico empezó a devolver 404. Grafana 13 desactiva por defecto las API de datasource por id, y la corrección es llamar por uid. Te dejo el procedimiento, con copia de grafana.db y vuelta atrás.
Grafana 13, publicada el 14 de abril de 2026, desactiva por defecto las API de datasources que se llaman con el id numérico, y esa es la rotura que de verdad notarás al actualizar desde Grafana 12. Probé la subida de 12.4.12 a 13.2.3 en Docker con Prometheus aprovisionado y dos dashboards: los dashboards siguieron funcionando y un script que usaba ids numéricos dejó de funcionar. También tienes la versión en inglés.
Puntos clave
- La guía oficial dice: "Data source APIs that reference data sources by numeric
idhave been deprecated since Grafana 9. In Grafana 13, they’re disabled by default." - En mi prueba, las 2 llamadas por id (
/api/datasources/1y el proxy/api/datasources/proxy/1/...) pasaron de 200 a 404. Las 2 equivalentes por uid devolvieron 200. - Los 2 dashboards, uno aprovisionado y otro creado por API con el datasource escrito por nombre, se abrieron igual en 13.2.3.
- La copia de seguridad es un solo fichero: mi
grafana.dbocupaba 1 495 040 bytes, y restaurarlo devolvió Grafana 12.4.12 a su estado anterior. - La versión de destino importa: la 13.0.0 tenía un fallo de migración con Git Sync y la guía manda subir a 13.0.1 o posterior.
Qué cambia en Grafana 13 y qué te afecta
La guía de actualización a Grafana 13.0[1] lista los cambios que rompen compatibilidad. Estos son los que importan para una instalación en Docker, con lo que comprobé de cada uno:
| Cambio | Quién lo nota | Lo que probé |
|---|---|---|
| API de datasources por id numérico, desactivadas | Scripts, Terraform, herramientas propias | Sí: 404 en las dos llamadas |
| Plugin Image Renderer deja de funcionar como plugin | Quien genera imágenes o informes programados | No: es un servicio aparte |
/api pasa a estar obsoleta en favor de /apis |
Integraciones a largo plazo | Solo vi que /apis responde 200 |
| Roles personalizados con permisos obsoletos pueden fallar | Quien usa roles personalizados de RBAC | No: necesita roles personalizados |
| Fallo de migración de la 13.0.0 con Git Sync | Quien usa Git Sync | No: no lo uso |
Sobre /api, la guía aclara que "Legacy APIs are not being disabled for the moment", así que no tienes que migrar todo a la vez. No encontré ninguna sección sobre dashboards anteriores a Scenes en la guía de actualización; lo que dice la página de novedades es que los dashboards existentes "are migrated to the new schema when you open them".
Paso 1: prepara un Grafana 12 con datasource y dashboards aprovisionados
Para reproducir el escenario monté dos servicios con Docker Compose: Prometheus v3.15.0 y Grafana 12.4.12. Si no tienes la pila, empieza por cómo instalar Grafana con Docker y cómo instalar Prometheus con Docker. El docker-compose.yml mínimo:
services:
prometheus:
image: prom/prometheus:v3.15.0
volumes: ["./prometheus.yml:/etc/prometheus/prometheus.yml:ro"]
grafana:
image: grafana/grafana:${GF_TAG:-12.4.12}
ports: ["29400:3000"]
environment:
GF_SECURITY_ADMIN_PASSWORD: admin
volumes:
- gfdata:/var/lib/grafana
- ./prov:/etc/grafana/provisioning:ro
- ./dash:/var/lib/grafana/dashboards:ro
volumes: {gfdata: {}}
El datasource se aprovisiona con un uid fijo. Es la decisión que más te ahorra en la subida, porque un uid estable sobrevive a recrear el servidor:
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
uid: prom-main
isDefault: true
Añadí un dashboard aprovisionado (Overview, con el datasource por uid) y creé otro por API (Legacy by name) con "datasource": "Prometheus", la forma antigua de referirse al datasource por su nombre. Ese segundo dashboard simula los que llevan años en tu base de datos.
Paso 2: escribe el script que usa ids numéricos
El script de automatización que imita el caso típico consulta el datasource por su id y lanza una consulta por el proxy con ese mismo id:
curl -s -u admin:admin -w '\nHTTP %{http_code}\n' \
http://localhost:29400/api/datasources/1
curl -s -u admin:admin -w '\nHTTP %{http_code}\n' \
"http://localhost:29400/api/datasources/proxy/1/api/v1/query?query=up"
En Grafana 12.4.12 las dos devuelven HTTP 200: la primera con el JSON del datasource ("id":1,"uid":"prom-main") y la segunda con "status":"success" y las series de up.
Paso 3: haz la copia de seguridad de grafana.db
La guía recomienda: "We recommend that you back up your Grafana database so that you can roll back to a previous version, if required." Con SQLite, la base de datos es el fichero grafana.db del volumen. Paro Grafana para copiarlo sin escrituras a medias:
docker compose stop grafana
docker run --rm -v b8p14_gfdata:/v -v "$PWD":/b alpine \
cp /v/grafana.db /b/grafana.db.bak-12.4.12
docker compose start grafana
El nombre del volumen lleva el prefijo del proyecto de Compose (b8p14 en mi caso). Si usas MySQL o PostgreSQL, haz el volcado con mysqldump o pg_dump en lugar de copiar un fichero. Guarda también tu grafana.ini o las variables de entorno GF_*.
Paso 4: sube la imagen a Grafana 13 y mira qué se rompe
Cambié la etiqueta de la imagen a 13.2.3, la última 13.x en Docker Hub el 7 de octubre de 2026, y recreé solo el servicio de Grafana:
GF_TAG=13.2.3 docker compose up -d grafana
curl -s localhost:29400/api/health
La salud devolvió "version": "13.2.3" y "database": "ok". Los registros muestran las migraciones de la base de datos ejecutándose al arrancar, sin errores. Entonces repetí el script del paso 2:
== GET /api/datasources/1
{"message":"Not found"}
HTTP 404
== GET /api/datasources/proxy/1/api/v1/query?query=up
{"message":"Not found"}
HTTP 404
El mensaje es un Not found genérico, sin ninguna pista sobre la causa, y por eso conviene saber de antemano que es esto. Un script con curl -s y sin comprobar el código de estado fallaría en silencio. Los dashboards, en cambio, no sufrieron ningún cambio: Overview y Legacy by name se abrieron y pintaron sus series.
Paso 5: corrige las llamadas para usar uid
La corrección es resolver el uid una vez y llamar a las rutas por uid. Si solo conoces el nombre del datasource, la ruta /api/datasources/name/<nombre> sigue funcionando y te devuelve el uid:
G=http://localhost:29400
UID_DS=$(curl -s -u admin:admin \
$G/api/datasources/name/Prometheus \
| python3 -c 'import json,sys;print(json.load(sys.stdin)["uid"])')
curl -s -u admin:admin -o /dev/null -w '%{http_code}\n' \
"$G/api/datasources/uid/$UID_DS"
curl -s -u admin:admin -o /dev/null -w '%{http_code}\n' \
"$G/api/datasources/proxy/uid/$UID_DS/api/v1/query?query=up"
Las dos devolvieron 200 en Grafana 13.2.3. Lo mejor es guardar el uid en tu configuración (en mi aprovisionamiento es prom-main) en lugar de resolverlo en cada ejecución. Las rutas están descritas en la API HTTP de datasources[2].
Si no puedes tocar el script hoy, existe una salida temporal. La guía dice que se reactiva con el flag datasourceLegacyIdApi. Lo probé con GF_FEATURE_TOGGLES_ENABLE=datasourceLegacyIdApi: las dos llamadas por id volvieron a dar 200. Ten en cuenta que el flag y las API obsoletas se retirarán en una versión futura, así que sirve para ganar tiempo, no para quedarte.
Cómo volver atrás si algo falla
Restaurar es la inversa de la copia: paras Grafana, devuelves el fichero al volumen y arrancas la etiqueta anterior. Lo probé tras subir a 13.2.3:
docker compose stop grafana
docker run --rm -v b8p14_gfdata:/v -v "$PWD":/b alpine sh -c \
'cp /b/grafana.db.bak-12.4.12 /v/grafana.db && chown 472:0 /v/grafana.db'
GF_TAG=12.4.12 docker compose up -d grafana
La salud volvió a decir 12.4.12 y las llamadas por id volvieron a dar 200. El chown 472:0 es necesario porque el usuario de Grafana en la imagen es el 472. Sin la copia no hay vuelta atrás. Grafana 13 migra el esquema: mi base de datos pasó de 1 495 040 a 1 650 688 bytes al arrancar. No probé a abrir ese fichero con la versión 12.
Qué revisar fuera de mi laboratorio
Mi laboratorio no cubre dos cambios de la guía, así que compruébalos tú antes de subir:
- Image Renderer. Si generas imágenes o informes programados, la guía indica desplegarlo como servicio independiente. Además, la autenticación por JWT está activa por defecto y pide un valor no vacío en
[rendering] renderer_token. - Roles personalizados. Revisa que ningún rol global lleve
datasources:uid:<uid>,fixed:annotations.dashboard:writer,fixed:annotations.dashboard:readerniannotations:*. La guía dice que hay que recrear los permisos de datasource en roles no globales.
Si además centralizas logs, mira cómo centralizar logs con Grafana Loki en Docker: los datasources de Loki están sujetos al mismo cambio de id a uid.
Preguntas frecuentes
¿Qué versión de Grafana 13 debo instalar?
La última 13.x disponible. El 7 de octubre de 2026 era la 13.2.3. Evita la 13.0.0 si usas Git Sync: su migración podía perder dashboards y carpetas, y la guía pide subir a 13.0.1.
¿Se rompen los dashboards al actualizar a Grafana 13?
En mi prueba no. Un dashboard aprovisionado con datasource por uid y otro creado por API con el datasource por nombre se abrieron igual. Lo que se rompe son las llamadas a la API por id numérico.
¿Puedo seguir usando las API por id numérico?
Solo si activas el flag datasourceLegacyIdApi, y es temporal: Grafana retirará las API y el flag en una versión futura. Migra tus scripts a uid.
Conclusión
Actualizar de Grafana 12 a 13 en Docker es un cambio de etiqueta con una sola rotura que probé: los scripts que llaman a los datasources por id numérico devuelven 404. Haz la copia de grafana.db, sube a la última 13.x, cambia las llamadas a uid y conserva la copia hasta que todo funcione.
Antes de subir, busca /api/datasources/ con un número en tus scripts, en Terraform y en cualquier herramienta que hable con Grafana. Esa búsqueda te dice si te afecta.
Fuentes: [1] Actualizar a Grafana v13.0[1], [2] Novedades de Grafana v13.0[3], [3] API de datasources obsoletas desactivadas por defecto[4], [4] API HTTP de datasources[2], [5] Aprovisionamiento de Grafana[5], [6] Etiquetas de grafana/grafana en Docker Hub[6], [7] Versión v13.2.3 en GitHub[7].