--- title: "Cómo instalar Gatus en Ubuntu 24.04 con Docker Compose" description: "Instala Gatus con Docker Compose en Ubuntu 24.04, define checks HTTP, TCP y DNS, recibe alertas en Slack y publica una página de estado con HTTPS." category: "Observabilidad Avanzada" language: es source: https://cubepath.com/es/docs/observabilidad-avanzada/instalacion-de-gatus-dashboard-de-salud updated: 2026-09-25 --- # Cómo instalar Gatus en Ubuntu 24.04 con Docker Compose Gatus es un monitor de disponibilidad ligero que comprueba periódicamente endpoints HTTP, TCP, DNS o ICMP, evalúa condiciones sobre la respuesta (código, tiempo, contenido, caducidad del certificado) y muestra el resultado en una página de estado. Toda la configuración vive en un único archivo YAML, lo que facilita versionarla en Git. En este tutorial instalarás Gatus con Docker Compose en Ubuntu 24.04, definirás varios tipos de checks, activarás alertas en Slack y publicarás la página de estado en tu dominio con HTTPS. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath. Gatus consume muy pocos recursos: 1 vCPU y 1 GB de RAM son suficientes. - Un usuario no root con privilegios `sudo`. - Docker Engine y el plugin de Docker Compose instalados desde el repositorio oficial de Docker. - Un dominio con un registro DNS `A` (por ejemplo `status.your_domain`) apuntando a la IP del servidor, para el paso de HTTPS. - Opcional: un webhook entrante de Slack para las alertas. ## Paso 1: Crear la estructura del proyecto Gatus necesita dos cosas: el archivo de configuración y un directorio donde guardar el historial en SQLite, para que no se pierda al recrear el contenedor. Crea el directorio del proyecto: ```bash sudo mkdir -p /opt/gatus/config /opt/gatus/data sudo chown -R "$USER":"$USER" /opt/gatus cd /opt/gatus ``` ## Paso 2: Escribir una configuración mínima Empieza con un único endpoint para comprobar que todo funciona. Crea el archivo: ```bash nano /opt/gatus/config/config.yaml ``` ```yaml storage: type: sqlite path: /data/data.db endpoints: - name: Sitio web group: Público url: "https://your_domain" interval: 1m conditions: - "[STATUS] == 200" - "[RESPONSE_TIME] < 1500" - "[CERTIFICATE_EXPIRATION] > 168h" ``` Este endpoint se comprueba cada minuto y se considera sano si responde con 200, en menos de 1,5 segundos y con un certificado TLS que no caduca en los próximos 7 días (168 horas). `storage` guarda el historial en `/data/data.db` dentro del contenedor, que montarás desde `/opt/gatus/data`. ## Paso 3: Arrancar Gatus con Docker Compose Crea el archivo de Compose: ```bash nano /opt/gatus/compose.yaml ``` ```yaml services: gatus: image: twinproduction/gatus:latest container_name: gatus restart: unless-stopped ports: - "127.0.0.1:8080:8080" env_file: .env volumes: - ./config:/config:ro - ./data:/data ``` El puerto se publica solo en `127.0.0.1`: Docker se salta las reglas de UFW al publicar puertos, así que es la forma segura de que Gatus no quede expuesto directamente. El acceso público se hará a través de Nginx en el paso 7. Para producción, fija una versión concreta en lugar de `latest` (consulta las etiquetas en `github.com/TwiN/gatus/releases`). Crea el archivo `.env`, de momento vacío; en el paso 5 guardarás ahí el webhook de Slack: ```bash touch /opt/gatus/.env chmod 600 /opt/gatus/.env ``` Arranca el contenedor: ```bash docker compose up -d docker compose logs --tail 20 gatus ``` En los logs verás que Gatus ha cargado la configuración y empieza a evaluar el endpoint `Sitio web`. Comprueba que responde: ```bash curl -s http://127.0.0.1:8080/health ``` ```output {"status":"UP"} ``` Consulta el resultado del check a través de su API: ```bash curl -s http://127.0.0.1:8080/api/v1/endpoints/statuses | python3 -m json.tool | grep -E '"name"|"success"' | head ``` ```output "name": "Sitio web", "success": true, ``` ## Paso 4: Añadir checks de distintos tipos Gatus decide el tipo de check por el esquema de la URL. Abre de nuevo la configuración: ```bash nano /opt/gatus/config/config.yaml ``` Sustituye la sección `endpoints` por esta, adaptando los nombres de host a tus servicios: ```yaml endpoints: - name: Sitio web group: Público url: "https://your_domain" interval: 1m conditions: - "[STATUS] == 200" - "[RESPONSE_TIME] < 1500" - "[CERTIFICATE_EXPIRATION] > 168h" - name: API group: Público url: "https://api.your_domain/health" interval: 30s conditions: - "[STATUS] == 200" - "[BODY].status == ok" - "[RESPONSE_TIME] < 500" - name: Página de login group: Público url: "https://app.your_domain/login" interval: 2m conditions: - "[STATUS] == 200" - "[BODY] == pat(*Iniciar sesión*)" - name: PostgreSQL group: Interno url: "tcp://10.0.0.5:5432" interval: 30s conditions: - "[CONNECTED] == true" - name: Resolución DNS group: Interno url: "1.1.1.1" dns: query-name: "your_domain" query-type: "A" interval: 5m conditions: - "[DNS_RCODE] == NOERROR" - "[BODY] == your_server_ip" ``` Qué comprueba cada uno: | Endpoint | Tipo | Condiciones | |---|---|---| | Sitio web | HTTP | Código 200, tiempo de respuesta y caducidad del certificado | | API | HTTP | Además, el campo `status` del JSON devuelto debe valer `ok` | | Página de login | HTTP | El HTML debe contener el texto `Iniciar sesión` (`pat()` admite comodines `*`) | | PostgreSQL | TCP | El puerto acepta conexiones | | Resolución DNS | DNS | El servidor `1.1.1.1` resuelve `your_domain` a la IP esperada | `group` agrupa los endpoints en la página de estado. Otros placeholders útiles son `[IP]` (IP resuelta del host) y `len([BODY].items) > 0` para comprobar que un array no está vacío. Gatus detecta los cambios del archivo, pero reiniciar el contenedor tras cada edición es la forma más fiable de aplicarlos y ver los errores al momento: ```bash docker compose restart gatus docker compose logs --tail 20 gatus ``` Si hay un error de sintaxis, el contenedor se detiene y el log indica la línea o la clave con problemas. ## Paso 5: Configurar alertas en Slack Las alertas se definen en dos niveles: el proveedor en la sección global `alerting`, y en cada endpoint la lista de alertas que usa. Guarda la URL del webhook de Slack en `.env` para no dejarla en el YAML: ```bash nano /opt/gatus/.env ``` ```ini SLACK_WEBHOOK_URL=https://hooks.slack.com/services/your/webhook/url ``` Gatus sustituye las variables de entorno con la sintaxis `${VARIABLE}` en su configuración. Añade al principio de `config.yaml`: ```yaml alerting: slack: webhook-url: "${SLACK_WEBHOOK_URL}" default-alert: send-on-resolved: true failure-threshold: 3 success-threshold: 2 ``` Con esta configuración, un endpoint dispara la alerta tras 3 fallos consecutivos, la da por resuelta tras 2 éxitos consecutivos y avisa también de la resolución. Activa la alerta en cada endpoint que quieras vigilar, añadiendo el bloque `alerts`: ```yaml - name: API group: Público url: "https://api.your_domain/health" interval: 30s conditions: - "[STATUS] == 200" - "[BODY].status == ok" - "[RESPONSE_TIME] < 500" alerts: - type: slack description: "La API no responde correctamente" ``` Cada alerta puede sobrescribir los valores de `default-alert`, por ejemplo `failure-threshold: 5` en un servicio con picos de latencia ocasionales. Gatus soporta también otros proveedores en la misma sección `alerting`, como `email`, `telegram`, `discord`, `pagerduty` o `custom` (un webhook genérico), con claves propias de cada uno. Aplica los cambios con `--force-recreate`, necesario para que el contenedor lea el nuevo `.env`: ```bash docker compose up -d --force-recreate ``` Para probar la alerta, cambia temporalmente la URL de un endpoint a una ruta que devuelva 404, reinicia Gatus y espera los tres intervalos: recibirás el mensaje en Slack. Restaura la URL y recibirás el aviso de resolución. ## Paso 6: Personalizar la página de estado La página de estado muestra todos los endpoints con su historial reciente. Personaliza el título y los enlaces añadiendo una sección `ui` en `config.yaml`: ```yaml ui: title: "Estado de los servicios" header: "Estado de los servicios" description: "Disponibilidad en tiempo real de nuestros servicios" link: "https://your_domain" buttons: - name: "Web" link: "https://your_domain" - name: "Soporte" link: "https://your_domain/soporte" ``` Si algún endpoint es interno y no debe aparecer públicamente, no lo pongas en esta instancia: o usas una instancia distinta para la página pública, o proteges la página con autenticación en el proxy inverso. Activa también las métricas de Prometheus añadiendo esta línea al nivel superior del archivo: ```yaml metrics: true ``` Reinicia y comprueba que el endpoint `/metrics` publica series de Gatus: ```bash docker compose restart gatus curl -s http://127.0.0.1:8080/metrics | grep -m3 '^gatus_results_total' ``` ## Paso 7: Publicar la página con Nginx y HTTPS Instala Nginx y Certbot: ```bash sudo apt update sudo apt install nginx certbot python3-certbot-nginx ``` Abre los puertos web en el firewall: ```bash sudo ufw allow 'Nginx Full' ``` Crea el bloque de servidor: ```bash sudo nano /etc/nginx/sites-available/gatus ``` ```nginx server { listen 80; listen [::]:80; server_name status.your_domain; 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; } } ``` Actívalo, valida la sintaxis y recarga Nginx: ```bash sudo ln -s /etc/nginx/sites-available/gatus /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx ``` Obtén el certificado. Certbot modificará el bloque para servir HTTPS y redirigir el tráfico HTTP: ```bash sudo certbot --nginx -d status.your_domain ``` Abre `https://status.your_domain` en el navegador: verás la página de estado con los grupos `Público` e `Interno` y la barra de historial de cada endpoint. ## Solución de problemas **El contenedor se reinicia en bucle.** Casi siempre es un error en `config.yaml`: indentación, una clave desconocida o una condición mal escrita. Revisa `docker compose logs --tail 50 gatus`; el mensaje indica qué parte no se ha podido interpretar. **Un endpoint aparece siempre en rojo.** Haz clic en el endpoint en la página de estado para ver el detalle de cada comprobación y qué condición ha fallado. Si el servicio es interno, comprueba que el contenedor puede alcanzarlo: los checks salen desde la red de Docker, no desde el host. **Las alertas no llegan a Slack.** Comprueba que la variable está en el contenedor con `docker compose exec gatus env | grep SLACK` (si no aparece, recrea con `--force-recreate`) y que el endpoint tiene el bloque `alerts` con `type: slack`. Recuerda que la alerta solo salta tras `failure-threshold` fallos seguidos. **Los checks ICMP (`icmp://`) fallan siempre.** El ping necesita sockets raw, que el contenedor puede no tener permitidos. Usa un check TCP a un puerto conocido del host como alternativa. ## Conclusión Has desplegado Gatus con Docker Compose, has definido checks HTTP, TCP y DNS con condiciones sobre la respuesta, has configurado alertas en Slack y has publicado la página de estado con HTTPS. Como siguientes pasos, guarda `config.yaml` en un repositorio Git para revisar los cambios, añade Gatus como target en Prometheus usando `/metrics` y crea una segunda instancia en otra ubicación para detectar también las caídas del propio servidor de monitorización.