Grafana OnCall es una herramienta de gestión de guardias que recibe alertas de Alertmanager, Grafana y otros sistemas, las agrupa y avisa a la persona de guardia siguiendo una cadena de escalado hasta que alguien la reconoce. Funciona como un plugin de Grafana respaldado por un backend propio. En este tutorial desplegarás la versión OSS con Docker Compose en Ubuntu 24.04, la conectarás a Grafana, enviarás alertas desde Alertmanager y configurarás un calendario de guardia con su escalado.

Requisitos previos

  • Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con al menos 2 vCPU y 4 GB de RAM.
  • Un usuario no root con privilegios sudo.
  • Docker Engine y el plugin de Docker Compose instalados desde el repositorio oficial de Docker.
  • Opcional: un Alertmanager existente del que enviar alertas.

La instalación de ejemplo levanta su propio Grafana. Si ya tienes uno, podrás conectarlo en lugar del incluido (se explica en el paso 2).

Paso 1: Descargar el Docker Compose oficial

El repositorio de OnCall incluye un docker-compose.yml para instalaciones pequeñas (modo "hobby") con el motor, un worker Celery, Redis, una base de datos SQLite y, opcionalmente, un Grafana con el plugin ya instalado. Crea un directorio de trabajo y descarga el archivo:

mkdir -p ~/oncall
cd ~/oncall
curl -fsSL https://raw.githubusercontent.com/grafana/oncall/dev/docker-compose.yml -o docker-compose.yml

Revisa su contenido antes de usarlo:

less docker-compose.yml

Verás los servicios engine (API y web en el puerto 8080), celery (tareas en segundo plano y envío de notificaciones), redis, una tarea de migración de la base de datos y el servicio grafana, que solo se activa con el perfil with_grafana.

Paso 2: Configurar las variables de entorno

El Compose lee sus parámetros de un archivo .env. Genera primero una clave secreta aleatoria, que Django usa para firmar sesiones y tokens:

openssl rand -hex 32

Crea el archivo:

nano ~/oncall/.env

Sustituye your_server_ip por la IP o el nombre por el que Alertmanager alcanzará este servidor, y your_secret_key por la clave generada:

DOMAIN=http://your_server_ip:8080
COMPOSE_PROFILES=with_grafana
SECRET_KEY=your_secret_key
  • DOMAIN es la URL pública del motor. OnCall la usa para construir las URL de los webhooks de integración, así que debe ser alcanzable desde los sistemas que envían alertas.
  • COMPOSE_PROFILES=with_grafana levanta un Grafana en el puerto 3000 con el plugin instalado. Si ya tienes Grafana, elimina esa línea, instala el plugin con grafana-cli plugins install grafana-oncall-app en tu servidor Grafana y reinícialo.

Protege el archivo, ya que contiene la clave:

chmod 600 ~/oncall/.env

Paso 3: Arrancar OnCall

Descarga las imágenes y levanta los servicios:

cd ~/oncall
docker compose pull
docker compose up -d

La primera vez, el servicio de migración crea la base de datos y termina; el motor espera a que acabe. Comprueba el estado:

docker compose ps

Los servicios engine, celery, redis y grafana deben aparecer en estado running. La migración aparece como terminada (exited (0)), lo cual es correcto.

Comprueba que el motor responde:

curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/health/
200

Si no obtienes 200, revisa los logs del motor con docker compose logs --tail 50 engine.

Docker publica los puertos saltándose las reglas de UFW, así que los puertos 3000 y 8080 quedan abiertos a Internet aunque UFW no los permita. Si el servidor tiene IP pública, restringe el acceso con un firewall externo (por ejemplo, el firewall del panel de tu proveedor) o publica los puertos solo en 127.0.0.1 editando la sección ports del Compose y accede a través de un proxy inverso con TLS.

Paso 4: Conectar el plugin de OnCall en Grafana

Abre Grafana en http://your_server_ip:3000 e inicia sesión con admin / admin. Grafana te pedirá cambiar la contraseña en el primer acceso; hazlo.

A continuación:

  1. Ve a Administration > Plugins and data > Plugins y busca Grafana OnCall.
  2. En la página de configuración del plugin, indica como URL del backend de OnCall http://engine:8080. Es el nombre del servicio dentro de la red de Docker Compose; si usas tu propio Grafana, pon la URL por la que ese Grafana alcanza el motor, por ejemplo http://your_server_ip:8080.
  3. Pulsa Connect (o Enable y después Connect, según la versión).

Cuando la conexión funciona, aparece OnCall en el menú lateral de Grafana (dentro de Alerts & IRM). Los usuarios de Grafana se sincronizan automáticamente con OnCall.

Paso 5: Crear un calendario de guardia

Un calendario (schedule) define quién está de guardia en cada momento. Entra en OnCall > Schedules y pulsa + New schedule:

  1. Elige Set up on-call rotation schedule, ponle un nombre (por ejemplo Guardia infraestructura) y selecciona tu zona horaria.
  2. Pulsa + Add rotation y elige la frecuencia, por ejemplo Weekly, con el cambio de turno el lunes a las 09:00.
  3. Añade los usuarios que participan. OnCall los alterna en orden: una semana cada uno.
  4. Guarda la rotación.

El calendario muestra en la parte superior quién está de guardia ahora mismo. Puedes añadir una segunda capa (layer) para cubrir fines de semana con otra rotación, o crear sustituciones puntuales con Overrides para vacaciones.

Paso 6: Crear una cadena de escalado

Una cadena de escalado define a quién se avisa y cuándo, hasta que alguien reconoce la alerta (acknowledge). Ve a OnCall > Escalation chains, pulsa + New escalation chain, llámala Producción y añade estos pasos:

PasoAcción
1Notify users from on-call schedule: Guardia infraestructura
2Wait: 10 minutos
3Notify users from on-call schedule de nuevo, con la opción de notificación importante
4Wait: 15 minutos
5Notify users: el responsable del equipo

Cada usuario decide cómo recibe los avisos en su perfil de OnCall (Users > View my profile), con reglas separadas para notificaciones normales e importantes. En una instalación OSS sin conexión a Grafana Cloud, los canales disponibles son los que configures en Settings > ChatOps (Slack o Telegram) y los webhooks salientes (Outgoing webhooks), que permiten avisar a cualquier sistema con una petición HTTP.

Paso 7: Recibir alertas de Alertmanager

Cada fuente de alertas se conecta mediante una integración que genera una URL de webhook única. Ve a OnCall > Integrations, pulsa + New integration, elige Alertmanager y ponle un nombre como Alertmanager producción. En la página de la integración:

  1. Copia la URL del webhook. Tendrá la forma http://your_server_ip:8080/integrations/v1/alertmanager/<token>/.
  2. En la ruta por defecto (Default route), selecciona la cadena de escalado Producción.

Ahora configura Alertmanager para enviar las alertas a esa URL. En el servidor de Alertmanager, edita su configuración (con el paquete de Ubuntu, /etc/prometheus/alertmanager.yml):

sudo nano /etc/prometheus/alertmanager.yml

Define el receptor y úsalo en la ruta principal, sustituyendo la URL por la tuya:

route:
  receiver: oncall
  group_by: ['alertname', 'job']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h

receivers:
  - name: oncall
    webhook_configs:
      - url: "http://your_server_ip:8080/integrations/v1/alertmanager/your_token/"
        send_resolved: true

send_resolved: true hace que OnCall cierre la alerta automáticamente cuando Alertmanager la da por resuelta. Valida la configuración y reinicia el servicio (en el paquete de Ubuntu se llama prometheus-alertmanager):

amtool check-config /etc/prometheus/alertmanager.yml
sudo systemctl restart prometheus-alertmanager

Para probar la cadena completa sin esperar a una alerta real, pulsa Send demo alert en la página de la integración. En OnCall > Alert groups aparecerá un grupo nuevo en estado Firing, y la persona de guardia recibirá el aviso según su perfil. Al pulsar Acknowledge el escalado se detiene; Resolve lo cierra.

Paso 8: Enrutar alertas por etiquetas

Las rutas permiten enviar alertas distintas a cadenas distintas dentro de la misma integración. En la página de la integración pulsa Add route y escribe una condición en Jinja2 sobre el payload de Alertmanager. Por ejemplo, para enviar a una cadena urgente solo las alertas críticas:

{{ payload.commonLabels.severity == "critical" }}

Y para las alertas de bases de datos:

{{ payload.commonLabels.job == "postgres" }}

Las rutas se evalúan en orden y la primera que coincide se aplica; las alertas que no encajan en ninguna van a la ruta por defecto.

Solución de problemas

El plugin muestra un error de conexión. Grafana no alcanza la URL del backend. Con el Grafana del Compose usa http://engine:8080; con un Grafana externo, comprueba desde ese servidor que curl http://your_server_ip:8080/health/ devuelve 200.

Las alertas de Alertmanager no llegan. Revisa sudo journalctl -u prometheus-alertmanager -n 50 en el servidor de Alertmanager: un error de conexión indica que DOMAIN o el firewall no permiten el acceso al puerto 8080. Comprueba también docker compose logs --tail 50 engine en OnCall.

Las alertas llegan pero nadie recibe avisos. El envío lo hace el worker: comprueba que celery está en marcha con docker compose ps y sus logs con docker compose logs --tail 50 celery. Verifica además que hay alguien de guardia en el calendario en ese momento y que el usuario tiene reglas de notificación en su perfil.

Las URL de los webhooks muestran localhost. El valor de DOMAIN en .env es incorrecto. Corrígelo y recrea los contenedores con docker compose up -d --force-recreate.

Conclusión

Tienes Grafana OnCall OSS funcionando con Docker Compose, conectado a Grafana, recibiendo alertas de Alertmanager y escalándolas según un calendario de guardia. Como siguientes pasos, conecta Slack o Telegram en Settings > ChatOps, publica OnCall detrás de un proxy inverso con TLS y, dado que el proyecto está archivado, planifica la migración a Grafana Cloud IRM u otra herramienta mantenida antes de depender de él en producción.