Gatus en Ubuntu: monitorización como código con Docker

Mascote LinuxPro acompanhando um painel de monitoramento do Gatus

Un endpoint puede seguir “en pie” para el servidor y aun así fallar para quien usa el producto. Gatus es una monitorización self-hosted orientada a desarrolladores: describes en YAML lo que necesitas comprobar, ejecuta las sondas, mantiene una página de estado y puede alertar cuando una condición deja de ser verdadera. En este primer artículo, el objetivo es sencillo: levantar Gatus en Ubuntu con Docker, persistir el historial en SQLite y crear el primer check. Las opciones más avanzadas quedan para una próxima guía.

Qué es Gatus

Gatus es un proyecto open source bajo licencia Apache-2.0, desarrollado en Go. Comprueba servicios por HTTP, ICMP, TCP y DNS y no se limita a “¿la URL respondió?”: las condiciones pueden validar código HTTP, tiempo de respuesta, cuerpo devuelto, caducidad del certificado y otros valores de la sonda. El resultado aparece en un panel/página de estado y puede alimentar alertas.

El punto central es la configuración como código. En lugar de registrar checks solo en una interfaz, los endpoints viven en YAML. Esto facilita la revisión en pull request, el historial en Git y la repetición de la misma política entre entornos. Si tu preferencia es una interfaz para crear monitores manualmente, lee también nuestra guía de Uptime Kuma en Linux.

Go: por qué importa el lenguaje

El código de Gatus está escrito en Go. En la práctica, esto explica por qué se puede distribuir como un único ejecutable y por qué la imagen oficial realiza una compilación Go antes de iniciar un binario en el contenedor. Para quien opera el servicio con Docker, no hay runtime Go que instalar en Ubuntu: la imagen ya entrega la aplicación. Para quien elija la instalación sin contenedor, el propio proyecto documenta go install github.com/TwiN/gatus/v5@latest.

Esto no es una garantía automática de bajo consumo en cualquier escenario: la cantidad de endpoints, el intervalo de las sondas, la retención del historial y la base de datos elegida siguen definiendo la carga. Pero la ausencia de una máquina virtual de lenguaje en el proceso de producción hace que el modelo operativo sea directo.

Por qué encuentra fallos antes que el usuario

Las métricas de una aplicación pueden parecer normales cuando ningún cliente llega hasta ella. Si un balanceador, DNS o ruta externa falla, tal vez ni siquiera haya tráfico para generar un error. Gatus realiza una petición activa en el intervalo configurado y evalúa la respuesta. Así, puede avisar de que el flujo público está roto antes de que llegue la primera llamada.

No sustituye a las métricas, logs y tracing. Para CPU, memoria, disco e investigación de un servidor Linux, complementa la estrategia con Prometheus y Node Exporter. Piensa en Gatus como una comprobación sintética de disponibilidad y de contrato: “¿este endpoint importante devuelve lo que prometió?”.

Instala Docker, Compose y Nginx en Ubuntu

En un Ubuntu nuevo, instala Docker desde el repositorio oficial y Nginx desde APT. Si la máquina ya ejecuta contenedores, revisa los paquetes instalados antes de cambiar docker.io, containerd o runc: mezclar orígenes puede provocar conflictos.

sudo apt update
sudo apt install -y ca-certificates curl nginx
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker nginx
sudo docker run hello-world
docker compose version

La prueba hello-world confirma que el daemon está funcionando. Mantenga sudo en los comandos Docker o trate la entrada en el grupo docker como acceso administrativo al host.

Antes de instalar

Esta guía usa Docker Engine y el plugin Docker Compose en Ubuntu. Si aún no los tiene, siga la instalación por el repositorio oficial de Docker en nuestro artículo sobre Uptime Kuma. Usaremos el puerto 8080 vinculado solo a 127.0.0.1: esto es seguro para la primera prueba en el servidor y evita publicar el panel sin HTTPS y control de acceso.

El README oficial también documenta la instalación mediante Go con go install github.com/TwiN/gatus/v5@latest. Vamos a usar deliberadamente Docker en este post para mantener la instalación corta y reproducible. La instalación mediante Go, proxy inverso, autenticación y bases de datos externas merecen un tutorial aparte.

Levante Gatus con Docker Compose

Cree los directorios. El directorio config guarda la definición versionable de los checks; data recibirá el SQLite, que conserva el historial tras reinicios.

sudo install -d -m 0755 /opt/gatus/config /opt/gatus/data
sudo chown -R "$USER":"$USER" /opt/gatus
cd /opt/gatus

Cree compose.yaml:

services:
  gatus:
    image: ghcr.io/twin/gatus:stable
    container_name: gatus
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:8080"
    environment:
      GATUS_CONFIG_PATH: /config/config.yaml
    volumes:
      - ./config:/config:ro
      - ./data:/data

La etiqueta stable es la indicada por la guía rápida oficial, pero sigue los cambios. Para producción, pruebe una release y fije una etiqueta de versión conocida cuando su política exija previsibilidad.

Escriba el primer monitor

Cree /opt/gatus/config/config.yaml. Este ejemplo monitoriza la página de inicio y exige HTTP 200, respuesta en menos de dos segundos y certificado válido durante más de siete días:

storage:
  type: sqlite
  path: /data/data.db

endpoints:
  - name: LinuxPro
    group: site-publico
    url: "https://www.linuxpro.com.br/"
    interval: 5m
    conditions:
      - "[STATUS] == 200"
      - "[RESPONSE_TIME] < 2000"
      - "[CERTIFICATE_EXPIRATION] > 168h"

Cambie URL, nombre y límites para su servicio. Un límite de dos segundos puede no tener sentido para toda aplicación; el objetivo es transformar una expectativa real en una condición. Para una API JSON, Gatus también permite validar un campo del cuerpo, por ejemplo [BODY].status == UP, cuando ese contrato exista.

Elección del almacenamiento: en memoria, SQLite o PostgreSQL

Gatus admite tres tipos de almacenamiento: memory, sqlite e postgres. MySQL/MariaDB no es un backend compatible por Gatus en este momento; no vale la pena levantar un contenedor MySQL y apuntar la configuración a él.

  • Memory: es el valor por defecto y sirve solo para demostración. Todo el historial se pierde al reiniciar el proceso.
  • SQLite: es la mejor elección para una única instancia, pocos o medianos conjuntos de endpoints y operación sencilla. El Compose de esta guía ya lo utiliza; mantenga ./data en disco local y haga una copia de seguridad del archivo data.db.
  • PostgreSQL: elija cuando el historial crezca, cuando ya exista PostgreSQL gestionado por el equipo o cuando necesite separar la base de datos del contenedor de la aplicación. Para dashboards grandes, Gatus ofrece storage.caching: true en SQLite y PostgreSQL.

El Compose inicial de este artículo es el escenario SQLite: el volumen ./data:/data e storage.type: sqlite en el YAML son el “docker-compose para SQLite”. No elimine esas dos partes, o volverá al almacenamiento en memoria.

Docker Compose con PostgreSQL

Cuando SQLite deje de ser suficiente, utilice una base de datos PostgreSQL aislada en la misma red Docker. Cree un archivo .env con una contraseña fuerte y no lo envíe a Git:

POSTGRES_DB=gatus
POSTGRES_USER=gatus
POSTGRES_PASSWORD=troque-por-uma-senha-longa

Después sustituya el compose.yaml por el ejemplo siguiente. PostgreSQL no publica puerto en el host: solo el contenedor Gatus se comunica con él.

services:
  postgres:
    image: postgres:18
    restart: unless-stopped
    env_file: .env
    volumes:
      - postgres-data:/var/lib/postgresql
    networks: [gatus-internal]

  gatus:
    image: ghcr.io/twin/gatus:stable
    container_name: gatus
    restart: unless-stopped
    depends_on: [postgres]
    env_file: .env
    ports:
      - "127.0.0.1:8080:8080"
    environment:
      GATUS_CONFIG_PATH: /config/config.yaml
    volumes:
      - ./config:/config:ro
    networks: [gatus-internal]

volumes:
  postgres-data:

networks:
  gatus-internal:

Modifique también el fragmento storage de config/config.yaml. Si la contraseña contiene caracteres reservados en URL, debe codificarse para su uso en la URL de conexión.

storage:
  type: postgres
  path: "postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?sslmode=disable"
  caching: true

O sslmode=disable es apropiado únicamente para esa red Docker interna. Para PostgreSQL fuera del host o gestionado, exija TLS y use la URL de conexión proporcionada por el servicio.

Inicie y valide

cd /opt/gatus
sudo docker compose up -d
sudo docker compose ps
sudo docker compose logs --tail=100
curl -I http://127.0.0.1:8080

O curl confirma que el servicio está escuchando localmente. Para abrir el panel sin exponer el puerto, cree un túnel SSH desde su máquina:

ssh -L 8080:127.0.0.1:8080 usuario@seu-servidor

Después acceda http://localhost:8080 en el navegador local. No abra 8080 en el cortafuegos solo para facilitarlo: cuando decida ofrecer una página de estado o administración, publíquela detrás de HTTPS, autenticación y un proxy inverso configurado para su entorno.

Publique el panel con Nginx

Compose mantiene Gatus en 127.0.0.1:8080. Para acceder mediante un dominio, coloque Nginx delante y use HTTPS. En /etc/nginx/sites-available/gatus, adapte el dominio y las rutas del certificado:

server {
    listen 80;
    server_name status.exemplo.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name status.exemplo.com;

    ssl_certificate /etc/letsencrypt/live/status.exemplo.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/status.exemplo.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
sudo ln -s /etc/nginx/sites-available/gatus /etc/nginx/sites-enabled/gatus
sudo nginx -t
sudo systemctl reload nginx

Emita el certificado antes de activar el bloque HTTPS y no exponga el panel administrativo sin protección. Gatus ofrece Basic Auth y OIDC en su propia configuración; use una de ellas cuando la página no sea pública. Para la implementación de Nginx en Ubuntu, consulte también nuestra guía de Nginx y varias versiones de PHP.

Gatus e IA: un uso práctico, sin bombo

Gatus no es una herramienta de IA y no “arregla” código generado por IA. La utilidad aquí es otra: los cambios son más frecuentes cuando los equipos usan asistencia de IA, y una sonda sintética puede verificar el camino crítico tras el despliegue. Además de probar 200, valide un campo JSON, una respuesta esperada o un límite de tiempo. El propio proyecto aborda ese papel de prevención en el contexto de cambios acelerados por IA.

No convierta una sonda en una acción destructiva. Si crea comprobaciones que realizan POST para probar un flujo, la operación debe ser idempotente, aislada y no puede alterar datos reales de producción. El YAML es un contrato operativo: revíselo como revisaría código.

Qué queda para el siguiente paso

Después de que el primer endpoint esté sano, avance poco a poco: añada DNS o TCP, configure alertas, use una página pública separada y lleve el YAML a Git. Antes de guardar tokens de webhook o contraseñas en la configuración, retírelos del repositorio y use el mecanismo de secretos adoptado por su equipo.

Para detalles completos sobre condiciones, alertas, almacenamiento y seguridad, consulte la documentación de Gatus y el repositorio oficial. Acompaña también las releases antes de actualizar la imagen. Con un archivo breve y una comprobación bien pensada, Gatus ya impide que el usuario sea su primer monitor.

Lectura relacionada: How Gatus Can Help Prevent Disasters in the Era of AI, en el blog oficial del proyecto.