Instalación de Gatus en un VPS: monitorización de sitios web, alertas SSL y notificaciones en Telegram
TL;DR
Gatus es un servicio ligero de monitorización self-hosted que comprueba regularmente la disponibilidad de sitios web, API, puertos TCP y la fecha de expiración de certificados SSL. En esta guía desplegará Gatus mediante Docker Compose en un VPS, lo protegerá con el proxy HTTPS Caddy y configurará notificaciones de fallos y recuperación de servicios en Telegram.
- Para la monitorización básica de 20–100 endpoints, bastan 1 vCPU, 1 GB de RAM y 10 GB de SSD.
- Gatus se ejecutará en Docker Compose con almacenamiento SQLite y reinicio automático.
- La configuración de los endpoints se guarda en YAML y el token de Telegram en un archivo independiente
.env. - Caddy emitirá y renovará automáticamente un certificado TLS de Let’s Encrypt para el panel de Gatus.
- Se configurarán comprobaciones HTTP, comprobaciones de API, alertas SSL, healthcheck y copias de seguridad.
- Al final encontrará diagnósticos de errores habituales: Telegram, TLS, Docker, firewall y panel inaccesible.
Qué configuramos y por qué
Gatus es una herramienta open-source de monitorización de disponibilidad escrita en Go. Es adecuada para propietarios de VPS que desean ver el estado de sus propios sitios web, REST API, paneles VPN, servidores de juegos, servicios Git, correo o dependencias externas sin entregar la lista de su infraestructura a un servicio SaaS de monitorización externo.
El servicio realiza comprobaciones según una programación. Por ejemplo, puede enviar una solicitud HTTP a https://example.com/health, asegurarse de que el servidor devolvió el código 200, comprobar un campo JSON de la respuesta, medir la latencia y avisar si el certificado SSL expira en 21 días. Para servicios TCP, Gatus puede comprobar un puerto abierto y, para ICMP, la disponibilidad del nodo mediante ping.
Como resultado, dispondrá de un panel web de estados en una dirección como https://status.example.com, historial de comprobaciones, tiempo de respuesta, porcentaje de disponibilidad y notificaciones de Telegram. Las notificaciones no se envían por un único timeout aleatorio, sino tras el número definido de errores consecutivos. Después de la recuperación, Gatus también enviará un mensaje independiente.
Qué se desplegará exactamente
- Ubuntu Server 24.04 LTS o 26.04 LTS en un VPS.
- Docker Engine 27+ o una versión estable más reciente.
- Docker Compose Plugin v2.
- Contenedor Gatus de la imagen oficial
twinproduction/gatus. - Contenedor Caddy 2.9+ para reverse proxy y HTTPS automático.
- Base de datos SQLite de Gatus en un Docker volume.
- Configuración de endpoints en YAML y secretos en el archivo
.env. - Copias de seguridad de configuraciones y de la base SQLite mediante restic.
Qué comprobaciones admite Gatus
| Tipo de comprobación | Ejemplo de uso | Condición de éxito |
|---|---|---|
| HTTP/HTTPS | Página principal del sitio web o endpoint de API | Código de respuesta 200, encabezado requerido o texto en el body |
| JSON API | /health, webhook de pagos, backend SaaS |
El valor de JSONPath es igual al valor esperado |
| TCP | SSH, PostgreSQL, Redis, Minecraft, SMTP | El puerto acepta conexiones |
| ICMP | Comprobación de disponibilidad de un host remoto | El nodo responde al ping |
| SSL/TLS | Sitio web con certificado Let’s Encrypt o comercial | El certificado es válido y no expira antes del umbral |
Gatus self-hosted o monitorización en la nube
Los servicios de monitorización en la nube son prácticos si necesita varios puntos de comprobación distribuidos geográficamente, informes SLA para clientes y una administración mínima. Sus desventajas son el pago mensual, el límite de comprobaciones en planes económicos y la transferencia de datos sobre sus dominios, endpoints e incidentes a un proveedor externo.
Gatus self-hosted en un VPS es más adecuado para infraestructura personal, un SaaS pequeño, un equipo de desarrollo o un conjunto de servicios internos. No requiere una base de datos independiente al inicio, consume pocos recursos y almacena el historial en su propia infraestructura. Es importante comprender la limitación: si Gatus está alojado en el mismo centro de datos que el sitio web comprobado, no detectará la indisponibilidad total de red de esa ubicación. Para servicios críticos, es útil mantener una segunda instancia en otra ubicación.
Qué configuración de VPS se necesita para esta tarea
Gatus no requiere un servidor potente. La carga depende del número de endpoints, el intervalo de comprobación, la cantidad de conexiones TCP y el tiempo de retención del historial. Para la mayoría de los proyectos personales y comerciales pequeños, el factor limitante no será la CPU, sino un almacenamiento razonable de la base SQLite y una red estable.
| Escenario | CPU | RAM | Disco | Red |
|---|---|---|---|---|
| Hasta 30 endpoints, intervalo de 1–5 minutos | 1 vCPU | 1 GB | 10 GB SSD | 100 Mbit/s |
| 30–200 endpoints, comprobaciones de API e historial | 1–2 vCPU | 2 GB | 20–30 GB NVMe | 100–300 Mbit/s |
| 200–1000 endpoints, varios grupos | 2–4 vCPU | 4 GB | 50 GB NVMe | 1 Gbit/s |
Una opción inicial práctica es 1 vCPU, 2 GB de RAM, 20 GB NVMe e IPv4 pública. Este margen es suficiente para Gatus, Caddy, Docker, fail2ban, copias de seguridad de la configuración y varias decenas de comprobaciones cada minuto. Como una de las opciones neutrales, puede elegir un VPS con las características indicadas, pero priorice sobre todo la proximidad de la ubicación, la calidad de la red y la disponibilidad de snapshots periódicos.
Cuándo necesita un dedicated en lugar de un VPS
Para un único Gatus, un servidor dedicado casi nunca es necesario. Un dedicated tiene sentido si la monitorización es solo parte de una gran plataforma de observabilidad: junto a ella se ejecutan Prometheus, Grafana, Loki, Uptime Kuma, un sistema CI y cientos de contenedores. También es útil cuando existen requisitos de aislamiento, un alto volumen de logs o miles de comprobaciones con intervalos cortos.
Si simplemente comprueba 10–200 dominios y servicios, un VPS es más sencillo, económico y rápido de escalar. Cuando aumenta la carga, migrar Gatus a un VPS más grande normalmente se reduce a restaurar los archivos de configuración y el volume de SQLite desde una copia de seguridad.
Cómo elegir la ubicación
La ubicación influye en la latencia de las comprobaciones y en los problemas de red que detectará. Si los usuarios de su sitio web están en Europa, es lógico alojar la monitorización en un centro de datos europeo. Si la infraestructura está ubicada en un país y necesita verla «desde fuera», elija una ubicación y red independientes.
No instale Gatus en el mismo host que monitoriza: si el servidor falla, la monitorización también desaparecerá. El esquema mínimo razonable es un VPS independiente. Para proyectos importantes, utilice dos instancias independientes en distintos países o con diferentes proveedores y envíe las notificaciones a distintos chats de Telegram.
Preparación del servidor
A continuación se asume un servidor limpio con Ubuntu 24.04 LTS o Ubuntu 26.04 LTS, IPv4 pública, el dominio status.example.com y un registro DNS de tipo A que apunta a la IP del VPS. Antes de emitir el certificado, asegúrese de que el DNS ya se ha propagado: Caddy debe ser accesible externamente en los puertos 80 y 443.
Actualice el sistema
Conéctese al servidor con el usuario proporcionado durante el provisioning o como root. Primero instale las actualizaciones de seguridad y las utilidades básicas.
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl ca-certificates gnupg ufw fail2ban nano jq unzip
sudo reboot
Los comandos actualizan los paquetes, instalan las utilidades necesarias, el firewall y la protección contra intentos de contraseña, y después reinician el servidor.
Cree un administrador independiente
No trabaje permanentemente como root. Cree un usuario, añádalo al grupo sudo y agregue previamente la clave pública SSH. En el ejemplo, el nombre de usuario es deploy.
sudo adduser deploy
sudo usermod -aG sudo deploy
sudo install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
sudo nano /home/deploy/.ssh/authorized_keys
sudo chmod 600 /home/deploy/.ssh/authorized_keys
sudo chown deploy:deploy /home/deploy/.ssh/authorized_keys
En el archivo authorized_keys, inserte una línea con su clave pública, por ejemplo, el contenido del archivo ~/.ssh/id_ed25519.pub en su equipo local. Antes de cerrar la sesión SSH actual, asegúrese de comprobar el acceso en una nueva terminal.
ssh deploy@SERVER_IP
Este comando comprueba que el acceso mediante clave funciona realmente para el nuevo usuario.
Desactive el acceso SSH mediante contraseña
Después de comprobar la clave, prohíba la autenticación por contraseña y el acceso de root. Esto reduce drásticamente la probabilidad de comprometer el servidor mediante ataques automáticos de brute-force.
sudo nano /etc/ssh/sshd_config.d/99-hardening.conf
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
X11Forwarding no
MaxAuthTries 3
sudo sshd -t && sudo systemctl restart ssh
El comando comprueba la sintaxis de la configuración SSH y reinicia SSH solo si no hay errores.
Configure UFW y fail2ban
El panel de Gatus debe ser accesible mediante HTTPS, y Caddy necesita HTTP para la comprobación inicial del dominio y la redirección a HTTPS. Mantenga SSH abierto solo después de asegurarse de que puede volver a conectarse.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
Los comandos activan el firewall y dejan abiertos únicamente SSH, HTTP y HTTPS. No es necesario abrir externamente el puerto 8080 de Gatus: solo estará disponible para el contenedor Caddy en la red interna de Docker.
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
Esto activa fail2ban al iniciar el sistema y muestra el estado de la protección SSH. Si restringe el acceso al servidor a IP fijas, cree además reglas UFW que permitan SSH únicamente desde su red.
Instalación del software, paso a paso
Para el despliegue utilizamos Docker Engine y Compose Plugin del repositorio oficial de Docker. Para 2026, se recomienda utilizar la rama estable actual de Docker Engine 27+ o una versión disponible más reciente, en lugar del paquete antiguo docker.io del repositorio estándar de Ubuntu.
Añada el repositorio oficial de Docker
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
Este bloque crea un directorio para las claves APT y añade la clave de firma del repositorio oficial de Docker.
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
El comando añade el repositorio correspondiente a la versión de Ubuntu y a la arquitectura del servidor, y después actualiza el índice de paquetes.
Instale Docker Engine y Compose
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
sudo usermod -aG docker deploy
Este bloque instala Docker, activa su inicio automático y permite al usuario deploy ejecutar Docker sin sudo. Después de ejecutarlo, salga de la sesión SSH y vuelva a conectarse para actualizar la pertenencia a los grupos.
exit
ssh deploy@SERVER_IP
docker version
docker compose version
Compruebe que Docker Engine y Compose Plugin estén disponibles. Si el comando docker ps muestra un error de acceso al socket, vuelva a conectarse una vez más o ejecute newgrp docker.
Cree la estructura del proyecto
Todos los archivos de Gatus se almacenarán en /opt/gatus. Este directorio es conveniente para realizar copias de seguridad, migrarlo y revisarlo mediante un sistema de control de configuración sin secretos.
sudo mkdir -p /opt/gatus/{config,caddy,data,backups}
sudo chown -R deploy:deploy /opt/gatus
cd /opt/gatus
umask 077
touch .env
chmod 600 .env
Los comandos crean los directorios de trabajo, transfieren la propiedad al usuario deploy y crean un archivo protegido para los secretos de Telegram.
Cree un bot de Telegram y averigüe el chat ID
Abra el bot oficial @BotFather en Telegram, ejecute el comando /newbot y establezca un nombre y username. BotFather devolverá un token del tipo 123456789:AA.... No lo publique en Git, tickets, capturas de pantalla ni configuraciones accesibles para otros usuarios.
Cree un chat personal con el bot y envíele cualquier mensaje, por ejemplo /start. Para un chat grupal, añada el bot al grupo y envíe un mensaje en él. Obtenga el identificador del chat en el servidor sustituyendo el token:
curl -s "https://api.telegram.org/botВАШ_ТОКЕН/getUpdates" | jq
En el JSON, busque el campo message.chat.id. Para los grupos de Telegram, el chat ID suele comenzar con un signo menos, por ejemplo -1001234567890. Guarde el token y el identificador en /opt/gatus/.env.
cd /opt/gatus
nano .env
TELEGRAM_TOKEN=123456789:REPLACE_WITH_REAL_TOKEN
TELEGRAM_CHAT_ID=-1001234567890
GATUS_DOMAIN=status.example.com
[email protected]
Este archivo contiene secretos y parámetros de entorno. No debe tener permisos de lectura para otros usuarios ni incluirse en un repositorio público.
Configuración de Gatus, Telegram y HTTPS
En este esquema, Gatus escucha el puerto 8080 únicamente dentro de la red Docker. Caddy acepta solicitudes externas en los puertos 80 y 443, obtiene automáticamente un certificado TLS y reenvía el tráfico a Gatus. Esto evita publicar el puerto de servicio y elimina el mantenimiento manual de Let’s Encrypt.
Cree la plantilla de configuración de Gatus
Gatus utiliza YAML. Almacenamos la plantilla config.yaml.template, y al iniciar Compose sustituye las variables de Telegram mediante envsubst. Así, el token no terminará en un archivo YAML permanente que pueda confirmarse accidentalmente.
cd /opt/gatus
nano config/config.yaml.template
storage:
type: sqlite
path: /data/gatus.db
caching: true
ui:
title: "Infrastructure Status"
description: "Availability and SSL monitoring"
default-sort-by: group
metrics: true
alerting:
telegram:
token: "${TELEGRAM_TOKEN}"
id: "${TELEGRAM_CHAT_ID}"
endpoints:
- name: Main website
group: Public sites
url: "https://example.com/"
interval: 1m
timeout: 10s
conditions:
- "[STATUS] == 200"
- "[RESPONSE_TIME] < 3000"
alerts:
- type: telegram
failure-threshold: 3
success-threshold: 2
send-on-resolved: true
description: "The main website is unavailable or too slow."
- name: API healthcheck
group: Public sites
url: "https://api.example.com/health"
interval: 1m
timeout: 10s
headers:
Accept: "application/json"
conditions:
- "[STATUS] == 200"
- "[BODY].status == UP"
- "[RESPONSE_TIME] < 2000"
alerts:
- type: telegram
failure-threshold: 2
success-threshold: 2
send-on-resolved: true
description: "API healthcheck did not return status UP."
- name: SSH server
group: Infrastructure
url: "tcp://203.0.113.10:22"
interval: 2m
timeout: 5s
conditions:
- "[CONNECTED] == true"
alerts:
- type: telegram
failure-threshold: 3
success-threshold: 1
send-on-resolved: true
description: "SSH port is unreachable."
- name: External HTTPS certificate
group: SSL certificates
url: "https://example.com/"
interval: 12h
conditions:
- "[STATUS] == 200"
- "[CERTIFICATE_EXPIRATION] > 336h"
alerts:
- type: telegram
failure-threshold: 1
success-threshold: 1
send-on-resolved: true
description: "SSL certificate expires in less than 14 days."
Sustituya example.com, api.example.com y la dirección IP de SSH por valores reales. La condición [CERTIFICATE_EXPIRATION] > 336h significa que deben quedar más de 14 días antes de que expire el certificado. Para certificados críticos, puede establecer 720 horas, es decir, 30 días.
No añada tokens, contraseñas ni parámetros query privados a las URL. Si la API requiere autorización, utilice un token técnico independiente con permisos mínimos y páselo mediante variables de entorno o una plantilla protegida. Para endpoints internos sensibles, es mejor restringir el acceso al panel de Gatus mediante Caddy Basic Auth, VPN o firewall.
Cree la configuración de Caddy
cd /opt/gatus
nano caddy/Caddyfile
{
email {$ACME_EMAIL}
}
{$GATUS_DOMAIN} {
encode zstd gzip
reverse_proxy gatus:8080
header {
-Server
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
}
}
Caddy solicitará el certificado automáticamente. Para ello, el registro A del dominio debe apuntar al VPS y los puertos 80 y 443 deben estar accesibles desde el exterior. Si el dominio utiliza proxy a través de CDN, asegúrese de que el modo TLS no interfiera con la validación ACME.
Cree el archivo Docker Compose
cd /opt/gatus
nano compose.yaml
services:
gatus:
image: twinproduction/gatus:latest
container_name: gatus
restart: unless-stopped
env_file:
- .env
entrypoint:
- /bin/sh
- -ec
- |
envsubst < /config/config.yaml.template > /tmp/config.yaml
exec /gatus --config-file=/tmp/config.yaml
volumes:
- ./config:/config:ro
- ./data:/data
networks:
- monitoring
healthcheck:
test: ["CMD", "/gatus", "--config-file=/tmp/config.yaml", "--version"]
interval: 30s
timeout: 10s
retries: 3
start_period: 15s
caddy:
image: caddy:2-alpine
container_name: caddy-gatus
restart: unless-stopped
env_file:
- .env
depends_on:
gatus:
condition: service_started
ports:
- "80:80"
- "443:443"
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
networks:
- monitoring
networks:
monitoring:
name: monitoring
volumes:
caddy_data:
caddy_config:
El uso de la etiqueta latest es conveniente para el primer inicio, pero para actualizaciones predecibles en producción es mejor fijar una versión probada de Gatus, por ejemplo twinproduction/gatus:v5.x.y, después de comprobar la versión actual. Del mismo modo, puede fijar la versión menor de Caddy. Después de actualizar la versión, compruebe siempre los cambios en el formato de configuración en las release notes.
Compruebe el YAML e inicie los contenedores
cd /opt/gatus
docker compose config
docker compose pull
docker compose up -d
docker compose ps
El primer comando combina el archivo Compose y las variables, comprobando la sintaxis. Después, Docker descarga las imágenes, inicia la pila en segundo plano y muestra el estado de los contenedores. Ambos contenedores deben tener el estado Up.
docker compose logs --tail=100 gatus
docker compose logs --tail=100 caddy
No debe haber errores de YAML en los logs de Gatus, y en los logs de Caddy aparecerá un mensaje sobre la emisión correcta del certificado. Si el certificado no se emite, compruebe primero el DNS, los puertos de UFW y la ausencia de otro servidor web en los puertos 80 o 443.
Compruebe el funcionamiento del panel y del endpoint
curl -I http://127.0.0.1
curl -I https://status.example.com
curl -s https://status.example.com | head
La primera solicitud puede devolver un error, ya que Caddy espera el encabezado Host correcto. La comprobación principal es la segunda solicitud: espere el estado 200 o una redirección de HTTP a HTTPS. Abra el dominio en el navegador y asegúrese de que la interfaz muestre los grupos, los endpoints, el historial de comprobaciones y el estado actual.
Compruebe la notificación de Telegram
La prueba más segura consiste en indicar temporalmente una URL deliberadamente inaccesible en un endpoint independiente. Tras dos o tres intervalos, Gatus debe enviar un mensaje de Telegram. Después, restaure la dirección correcta: tras el success-threshold establecido, llegará una notificación de recuperación.
docker compose restart gatus
docker compose logs -f gatus
El primer comando aplica los cambios de la plantilla de configuración, y el segundo muestra los logs en tiempo real. Después de finalizar la prueba, elimine el endpoint temporal para no recibir alertas falsas.
Importante: Gatus comprueba los servicios desde la IP de su VPS. Si el recurso comprobado bloquea solicitudes desde centros de datos, utiliza restricciones geográficas o Cloudflare WAF, añada la IP de monitorización a la allowlist o configure un endpoint permitido independiente
/health.
Copias de seguridad y mantenimiento
Gatus se puede volver a desplegar rápidamente, pero sin una copia de seguridad perderá la configuración de las comprobaciones, el historial de incidentes, la base de datos SQLite y los datos de certificados de Caddy. La estrategia mínima consiste en respaldar diariamente el directorio /opt/gatus en almacenamiento externo y comprobar periódicamente la restauración en un servidor de pruebas.
Qué se debe respaldar
/opt/gatus/config/— plantillas de endpoint y lógica de monitorización./opt/gatus/.env— token de Telegram, chat ID, dominio y email de ACME./opt/gatus/data/gatus.db— historial SQLite de comprobaciones y eventos.- Docker volume
caddy_data— certificados, claves y estado de Caddy. - Archivo
/opt/gatus/compose.yamly Caddyfile.
No guarde la única copia de seguridad en el mismo VPS. Puede usar almacenamiento compatible con S3, un servidor independiente mediante SFTP o un segundo VPS por SSH. Si el backup contiene .env y la private key del certificado, el repositorio debe estar cifrado.
Instale restic
sudo apt install -y restic
sudo mkdir -p /root/.config/restic
sudo chmod 700 /root/.config/restic
Restic crea copias de seguridad cifradas con deduplicación. A continuación se muestra una opción con almacenamiento compatible con S3. Los valores de acceso deben ser proporcionados por su almacenamiento de objetos.
sudo nano /root/.config/restic/gatus.env
export RESTIC_REPOSITORY="s3:https://s3.example.net/gatus-backups"
export RESTIC_PASSWORD="REPLACE_WITH_LONG_RANDOM_PASSWORD"
export AWS_ACCESS_KEY_ID="REPLACE_WITH_ACCESS_KEY"
export AWS_SECRET_ACCESS_KEY="REPLACE_WITH_SECRET_KEY"
sudo chmod 600 /root/.config/restic/gatus.env
sudo bash -c 'source /root/.config/restic/gatus.env && restic init'
Los comandos protegen el archivo de variables e inicializan un repositorio cifrado vacío. Guarde la contraseña RESTIC_PASSWORD por separado: sin ella, la restauración es imposible.
Cree el script de copia de seguridad
sudo nano /usr/local/sbin/backup-gatus.sh
#!/usr/bin/env bash
set -euo pipefail
source /root/.config/restic/gatus.env
cd /opt/gatus
docker compose stop gatus
trap 'docker compose start gatus' EXIT
restic backup \
/opt/gatus/config \
/opt/gatus/caddy \
/opt/gatus/compose.yaml \
/opt/gatus/.env \
/opt/gatus/data \
--tag gatus
docker run --rm \
-v caddy_data:/source:ro \
-v /opt/gatus/backups:/backup \
alpine sh -c 'tar czf /backup/caddy_data.tar.gz -C /source .'
restic backup /opt/gatus/backups/caddy_data.tar.gz --tag caddy
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
El script detiene brevemente Gatus para obtener una copia SQLite coherente y luego lo inicia de nuevo incluso si se produce un error gracias a trap. Caddy sigue funcionando, por lo que el panel web puede mostrar la última página, pero las comprobaciones nuevas se detendrán durante unos segundos.
sudo chmod 700 /usr/local/sbin/backup-gatus.sh
sudo /usr/local/sbin/backup-gatus.sh
sudo bash -c 'source /root/.config/restic/gatus.env && restic snapshots'
Primero ejecute el backup manualmente y asegúrese de que aparezca un nuevo snapshot en la salida. Solo después añada la ejecución automática.
sudo crontab -e
15 3 * /usr/local/sbin/backup-gatus.sh >> /var/log/backup-gatus.log 2>&1
La tarea ejecuta la copia de seguridad todos los días a las 03:15 según la hora del servidor. Una vez al mes, compruebe la restauración: descargue un snapshot en un directorio temporal independiente, verifique la presencia de gatus.db y la validez del YAML.
Actualizaciones y control del estado
Para una instalación pequeña, es mejor realizar las actualizaciones durante una maintenance window: durante este tiempo, las alertas pueden dejar de llegar brevemente y es más fácil revertir el cambio de versión. Antes de actualizar, cree una copia de seguridad, lea el changelog y compruebe si ha cambiado el formato de configuración de Gatus.
cd /opt/gatus
sudo /usr/local/sbin/backup-gatus.sh
docker compose pull
docker compose up -d
docker image prune -f
docker compose ps
Gatus no está diseñado para rolling updates como un servicio de clúster con failover automático. Si la monitorización es crítica, despliegue una segunda instancia en otro VPS con un canal de Telegram independiente o con distintos prefijos de mensajes. Esto es más fiable que intentar actualizar una única instancia sin una breve interrupción.
Compruebe semanalmente df -h, docker system df, el estado de los contenedores y el tamaño de /opt/gatus/data/gatus.db. Con una alta frecuencia de comprobaciones, la base de datos crecerá. Reduzca el período de retención del historial usando la versión actual de Gatus o exporte periódicamente las métricas a Prometheus y elimine los datos antiguos mediante el procedimiento documentado de la versión que utiliza.
Solución de problemas y FAQ
¿Por qué Gatus no se abre por HTTPS y Caddy muestra un error al obtener el certificado?
Primero compruebe el DNS: el comando dig +short status.example.com debe devolver la IP pública del VPS. Después, asegúrese de que UFW permite los puertos 80 y 443, y que Docker los publica mediante docker compose ps. Compruebe que los puertos no estén ocupados por otro Nginx o Apache: sudo ss -ltnp | grep -E ':80|:443'. Si utiliza una CDN, desactive temporalmente el proxy o configure el modo TLS correcto para el ACME challenge.
¿Por qué no llegan las notificaciones de Telegram?
Compruebe que el bot haya recibido al menos un mensaje del usuario o que se haya añadido al grupo. Después ejecute la solicitud getUpdates y asegúrese de que TELEGRAM_CHAT_ID coincide con message.chat.id. En los grupos, el ID suele ser negativo. Revise el archivo .env para detectar comillas adicionales, espacios y un token incorrecto; luego reinicie Gatus con docker compose restart gatus y examine los logs del contenedor.
¿Por qué el contenedor de Gatus se reinicia constantemente?
La causa más frecuente es un error de YAML o un campo de configuración no compatible después de actualizar la imagen. Ejecute docker compose logs --tail=200 gatus: la línea de error normalmente contiene el número de línea YAML. Compruebe las sangrías, use espacios en lugar de tab y asegúrese de que los caracteres especiales de las URL estén entre comillas. Si el problema apareció después de una actualización, vuelva temporalmente al tag de imagen que funcionaba anteriormente y compare la configuración con la documentación de esa versión.
¿Por qué el endpoint muestra un error aunque el sitio se abra en el navegador?
El navegador y el VPS pueden usar DNS, rutas IPv4/IPv6, geolocalización y encabezados diferentes. Compruebe la solicitud directamente desde el contenedor: docker exec -it gatus wget -S -O /dev/null https://example.com. Es posible que haya bloqueo de centros de datos por parte del WAF, un Host-header obligatorio, una redirección a otro dominio, un requisito de autorización o un timeout demasiado bajo. Configure una allowlist para las IP de monitorización, aumente el timeout a 15–20 segundos y compruebe un endpoint especial /health.
¿Por qué la alerta SSL llega demasiado tarde o no llega en absoluto?
Compruebe el intervalo del endpoint: con el valor 12h, Gatus detecta el cambio de certificado solo dos veces al día. Para dominios importantes, use un intervalo de 1–6 horas. Compruebe la condición [CERTIFICATE_EXPIRATION]: 336 horas equivalen a 14 días y 720 horas a 30 días. Asegúrese también de que el endpoint realmente utiliza HTTPS y no HTTP. Después de cambiar la condición, reinicie el contenedor y consulte el estado del endpoint en el panel.
¿Qué configuración mínima de VPS es adecuada?
Para 10–30 sitios y API endpoint con comprobaciones cada 1–5 minutos, bastan 1 vCPU, 1 GB de RAM, 10 GB de SSD y una conexión de 100 Mbit/s. Es más práctico elegir 2 GB de RAM y 20 GB de NVMe: quedará margen para Docker, Caddy, actualizaciones e historial SQLite. Son imprescindibles una IPv4 pública, la posibilidad de abrir 80/443 y una red estable. Si planea cientos de endpoint, comience con 2 vCPU, 4 GB de RAM y 30–50 GB de NVMe.
¿Qué elegir para esta tarea: VPS o dedicated?
Para Gatus, casi siempre basta con un VPS. Es más económico, se despliega más rápido y se escala fácilmente a medida que aumenta el número de comprobaciones. Se necesita dedicated si Gatus forma parte de un gran sistema de monitorización con Prometheus, Grafana, logs y miles de comprobaciones frecuentes, o si la política de seguridad requiere hardware físicamente dedicado. Para mejorar la fiabilidad, es mejor invertir el presupuesto no en dedicated, sino en un segundo VPS pequeño en otra red y ubicación.
¿Se puede cerrar el panel de Gatus al acceso público?
Sí. La forma más sencilla es dejar público solo el acceso mediante VPN, por ejemplo WireGuard, y cerrar 80/443 en UFW para todos excepto la subred VPN. Si el panel debe estar disponible para varios empleados, añada Basic Auth en Caddyfile con una contraseña hasheada. No bloquee las comprobaciones ACME si Caddy sigue emitiendo un certificado público. Como alternativa, use DNS challenge o un dominio interno independiente con TLS corporativo.
Conclusiones y próximos pasos
Ahora Gatus funciona en un VPS independiente con un panel HTTPS, comprobaciones de sitios y API, control de certificados SSL y notificaciones en Telegram. La configuración está separada de los secretos, los datos se guardan en SQLite y los backups se envían a almacenamiento externo cifrado.
- Añada un endpoint para todos los sitios públicos, API, dependencias DNS, SSH y servicios TCP críticos.
- Cree grupos independientes para production, staging y proveedores externos, para que sea más fácil clasificar las alertas de Telegram.
- Para sistemas críticos, despliegue un segundo Gatus en otra ubicación y compare los incidentes desde redes independientes.