Por qué la monitorización proactiva, y por qué las herramientas clásicas no son suficientes
La alerta reactiva — la que llega después de que el cliente ya ha llamado — no protege la relación. La repara. La diferencia entre ambos no es cuestión de suerte: es cuestión de cobertura.
Una herramienta de monitorización de disponibilidad como Uptime Kuma comprueba que un servicio responde en un puerto o URL. No sabe si PostgreSQL está funcionando fuera de ese puerto, si la memoria del contenedor está a punto de saturarse, o si el disco de logs se llena a 200 MB por hora. Por el contrario, una herramienta de métricas del sistema como Beszel monitoriza continuamente el consumo de recursos de cada host, pero no prueba los servicios de aplicación de extremo a extremo.
El caso documentado en Lemmy el 11 de octubre de 2026 (112 votos) ilustra exactamente esto: PostgreSQL se había detenido en un VPS sin disparar ninguna alerta de disco. No se había superado ningún umbral de espacio. Solo una verificación a nivel de aplicación habría detectado la parada — algo que el operador no tenía implementado.
La pila Beszel + Uptime Kuma v2 aborda ambos ángulos. Beszel monitoriza las métricas de cada host (CPU, RAM, disco, red, contenedores) desde un hub central. Uptime Kuma v2 verifica la disponibilidad de los servicios expuestos con canales de alerta configurables. Ambos son de código abierto, auto-alojados, y se instalan en un VPS dedicado a supervisar tu flota.
Lo que esta pila aporta concretamente a una agencia
- Vista unificada de todos los servidores de tus clientes en una sola interfaz Beszel, sin multiplicar los accesos SSH.
- Alertas de métricas (CPU, RAM, disco, red) con umbrales configurables por host.
- Verificaciones de disponibilidad HTTP(s), TCP, DNS y certificados SSL vía Uptime Kuma v2 — cada 60 segundos por defecto.
- Notificaciones por Telegram o SMTP operativas en la primera hora, sin suscripción a servicios externos.
- Detección de saturación de disco o fuga de memoria antes de que bloquee un servicio de aplicación.
- Páginas de estado públicas de Uptime Kuma compartibles con los clientes finales.
- Consumo total de la pila inferior a 150 MB de RAM en el VPS de supervisión.
- Despliegue reproducible mediante Docker Compose, versionable y redesplegable en minutos.
Requisitos de recursos
Para alojar el hub Beszel y Uptime Kuma v2 en un VPS dedicado a la supervisión:
Recursos mínimos. Un VPS de 1 vCPU con 1 GB de RAM es suficiente para supervisar alrededor de diez hosts con Beszel y unos cincuenta monitores con Uptime Kuma. En la práctica, Beszel hub consume alrededor de 50 MB de RAM y Uptime Kuma v2 alrededor de 100 MB — menos de 200 MB en total en reposo, según mediciones de la comunidad. Para una flota de 20 a 50 VPS, planifica 2 GB de RAM. Beszel almacena sus datos en SQLite; reserva 5 a 10 GB de disco para conservar varios meses de historial.
Software necesario. Docker y Docker Compose instalados en el VPS de supervisión. Un dominio o subdominio apuntando a este VPS (monitoring.your-domain.com) para el proxy inverso y SSL. Los puertos 80 y 443 abiertos para el proxy inverso, y el puerto 8090 o cualquier puerto de tu elección para el hub Beszel.
En los VPS supervisados. Cada host a supervisar recibe únicamente el agente Beszel — un binario ligero o contenedor Docker que consume unos 10 MB de RAM. No se requieren cambios en el firewall público: el agente inicia la conexión hacia el hub, no al revés.
Despliegue completo: hub Beszel, agentes, Uptime Kuma v2 y alertas
Crear la estructura Docker Compose en el VPS de supervisión
Conéctate al VPS dedicado a la supervisión. Crea un directorio de trabajo y el archivo Compose:
mkdir -p /opt/monitoring && cd /opt/monitoringCrea
docker-compose.ymlcon los dos servicios:services: beszel: image: henrygd/beszel:latest restart: unless-stopped volumes: - ./beszel_data:/beszel_data ports: - "8090:8090" environment: - DATA_DIR=/beszel_data uptime-kuma: image: louislam/uptime-kuma:2 restart: unless-stopped volumes: - ./uptime-kuma-data:/app/data ports: - "3001:3001" healthcheck: test: ["CMD", "node", "extra/healthcheck"] interval: 30s timeout: 10s retries: 3Observa el bloque
healthchecken Uptime Kuma: es indispensable para evitar el problema del crash-loop (ver sección Trampas).Arrancar la pila y crear las cuentas de administrador
Lanza los dos contenedores:
docker compose up -dVerifica que ambos contenedores estén en estado
healthyorunning:docker compose psAccede a Beszel en
http://<ip-vps>:8090y crea la cuenta de administrador en el primer acceso. Haz lo mismo con Uptime Kuma enhttp://<ip-vps>:3001. Ambas interfaces deben colocarse después detrás de un proxy inverso con SSL para no exponerlas en HTTP plano.Desplegar el agente Beszel en cada VPS a supervisar
En cada VPS cliente a supervisar, copia la clave pública generada en la interfaz de Beszel (Configuración → Clave SSH) y ejecuta:
curl -sL https://raw.githubusercontent.com/henrygd/beszel/main/supplemental/scripts/install-agent.sh | bash -s -- -p 45876 -k "<tu-clave-publica>"Alternativamente, usa Docker en el host supervisado:
services: beszel-agent: image: henrygd/beszel-agent:latest restart: unless-stopped network_mode: host volumes: - /var/run/docker.sock:/var/run/docker.sock:ro environment: - KEY=<tu-clave-publica> - PORT=45876En Beszel, añade cada host desde la interfaz (Sistemas → Añadir sistema) indicando su IP y el puerto del agente. La conexión la establece el hub hacia el agente: el host supervisado no necesita exponer ese puerto públicamente.
Configurar las alertas de métricas en Beszel
En Beszel, abre el detalle de un sistema y ve a la pestaña Alertas. Configura umbrales en las métricas críticas:
- Disco: alerta al 80% y crítica al 90% — cubre el caso PostgreSQL del escenario inicial.
- RAM: alerta si el uso supera el 85% sostenido durante 5 minutos.
- CPU: alerta si la carga supera el 90% durante más de 3 minutos.Beszel soporta Telegram, Discord, Slack, Gotify, Ntfy y webhooks genéricos. Para Telegram necesitas un token de bot (obtenido desde
@BotFather) y el ID de tu chat o grupo.Configurar los monitores Uptime Kuma v2 y las alertas SMTP o Telegram
En Uptime Kuma, comienza configurando un canal de notificación (Configuración → Notificaciones). Dos opciones habituales:
Telegram. Introduce el token del bot y el ID del chat. El mismo bot que para Beszel funciona — usa un solo bot para ambas herramientas y distingue con canales diferentes.
SMTP. Introduce el servidor SMTP, el puerto (587 con STARTTLS), las credenciales y la dirección de destino. Usa una cuenta dedicada al envío de alertas.
Crea después los monitores para cada servicio crítico: URL HTTP(s) para los sitios web, TCP para bases de datos y puertos de aplicación. Para el caso PostgreSQL, añade un monitor TCP en el puerto
5432de cada VPS que aloje una instancia — si PostgreSQL se detiene, el puerto deja de responder y la alerta se dispara en segundos.Poner todo detrás de un proxy inverso con SSL
Añade un servicio nginx o Caddy al Compose para exponer Beszel y Uptime Kuma por HTTPS:
caddy: image: caddy:alpine restart: unless-stopped ports: - "80:80" - "443:443" volumes: - ./Caddyfile:/etc/caddy/Caddyfile - caddy_data:/dataCon un
Caddyfilemínimo:monitoring.your-domain.com { reverse_proxy beszel:8090 } status.your-domain.com { reverse_proxy uptime-kuma:3001 }Caddy emite y renueva automáticamente los certificados Let's Encrypt. Elimina las secciones
portsde beszel y uptime-kuma en el Compose en cuanto estén proxificados — no deben ser accesibles directamente.Verificar el funcionamiento y configurar la retención
Prueba todo deteniendo manualmente un servicio en un VPS de prueba (
docker compose stop <servicio>) y verificando que la alerta de Telegram o SMTP llega en menos de dos minutos.Para Beszel, configura la retención de datos en Configuración → Retención: el valor por defecto es 7 días para datos de alta resolución y 30 días para agregados por hora. Ajusta según la capacidad de tu disco.
Para Uptime Kuma, la retención se configura en Configuración → Avanzado → Limpieza automática. Conserva al menos 90 días para tener tendencias mensuales de uptime que presentar a los clientes.
Trampas a conocer antes de pasar a producción
El crash-loop de Docker declarado como UP — issue de Uptime Kuma #7956. Sin healthcheck en el Compose, Docker puede reportar un contenedor de Uptime Kuma como running mientras está en un bucle de reinicios. El monitor de Uptime Kuma que se vigila a sí mismo (TCP en el puerto 3001) mostraría un falso positivo: el puerto responde durante el breve intervalo entre dos reinicios. La solución es exactamente el bloque healthcheck mostrado en el paso 1 — usa el script incluido en la imagen para probar el estado interno de la aplicación, no solo la presencia del proceso. Docker pasa entonces el contenedor a unhealthy si el check falla tres veces seguidas, y el monitor de Uptime Kuma lo detecta.
El agente Beszel con network_mode: host. Si los hosts supervisados ejecutan contenedores, el agente Beszel necesita acceso al socket de Docker (/var/run/docker.sock) para reportar métricas por contenedor. En modo de red bridge el socket es accesible pero la IP reportada por el agente puede ser la de la red Docker interna. Prefiere network_mode: host en el agente para garantizar que el hub Beszel ve la IP pública del servidor.
Las alertas de Beszel no reemplazan las verificaciones a nivel de aplicación. Beszel monitoriza los recursos del sistema y la disponibilidad de los contenedores Docker. No prueba que una aplicación responde correctamente a una petición HTTP o que PostgreSQL acepta conexiones. Estos dos niveles son complementarios: Beszel detecta la saturación que precede al fallo, Uptime Kuma confirma el fallo cuando ocurre.
Cobertura de alertas según la configuración de la pila
Desplace la tabla
| Escenario de fallo | Solo Beszel | Solo Uptime Kuma | Beszel + Uptime Kuma v2 |
|---|---|---|---|
| Disco lleno al 95% | Alerta en el umbral configurado | No detectado | Alerta Beszel antes del fallo |
| PostgreSQL detenido (puerto TCP caído) | No detectado (servicio fuera de Docker) | Alerta TCP en < 2 min | Alerta TCP de Uptime Kuma |
| Contenedor en crash-loop | Alerta si afecta a CPU/RAM | Falso positivo sin healthcheck | Detectado si healthcheck implementado |
| Fuga de memoria progresiva | Alerta en umbral de RAM | No detectado | Alerta anticipatoria de Beszel |
| Certificado SSL expirando en 7 días | No monitorizado | Alerta de expiración SSL | Alerta SSL de Uptime Kuma |
| VPS inaccesible (red o host caído) | Hub pierde el agente | Alerta TCP/HTTP | Señal doble, convergente |
Bastionado: aísla el VPS de supervisión
El VPS de supervisión es un activo crítico: si cae, pierdes visibilidad sobre todo lo demás. Tres reglas para bastionarlo.
Primero, no albergues aplicaciones de clientes en este VPS. Su carga debe ser predecible y su único rol es la supervisión.
Segundo, cierra todos los puertos innecesarios con el firewall del VPS. Solo 80, 443 y el puerto SSH (movido a un puerto no estándar) deben ser accesibles desde Internet. El puerto del agente Beszel (45876 por defecto) solo debe estar abierto desde las IPs de tus otros VPS, no desde toda Internet.
Tercero, añade un monitor externo de Uptime Kuma — por ejemplo desde un servicio de check HTTP gratuito — que verifique que tu propia instancia de Uptime Kuma responde. Sin esta capa externa, un fallo del propio VPS de supervisión pasa desapercibido.
Solución de problemas habituales
El agente Beszel aparece desconectado inmediatamente después de añadirlo. Verifica que el puerto del agente (45876 por defecto) sea alcanzable desde el hub. En el host supervisado, prueba con nc -zv <ip-hub> 8090 — si la conexión falla, el problema está en el firewall del hub. El propio agente no requiere ningún puerto de entrada abierto.
Uptime Kuma no recibe las alertas de Telegram. El motivo más frecuente es una desviación de reloj en el contenedor. Comprueba con docker exec uptime-kuma date que la hora coincide con la UTC real. Si no es así, añade /etc/localtime:/etc/localtime:ro en los volúmenes del servicio Uptime Kuma.
El hub Beszel no arranca o pierde datos tras un reinicio. Verifica que el volumen ./beszel_data pertenece al UID usado por el contenedor Beszel. Un error de permisos en el directorio de datos impide que SQLite escriba: chown -R 1000:1000 ./beszel_data resuelve el problema en la mayoría de los casos.
Uptime Kuma en estado unhealthy al arrancar. La imagen v2 puede tardar de 30 a 60 segundos en arrancar completamente antes de que el healthcheck pase. Es normal. Si el contenedor sigue en unhealthy después de dos minutos, consulta los logs: docker compose logs uptime-kuma.
Para ir más lejos
Esta pila cubre los dos niveles esenciales: métricas del sistema y verificación de disponibilidad. Para un tercer nivel — trazabilidad y análisis fino de tendencias de carga — la pila Grafana + Prometheus es el siguiente paso natural. Es más intensiva en recursos (planifica 2 GB de RAM dedicados), pero abre PromQL y los dashboards a medida. El artículo Monitorización de VPS con Grafana y Prometheus cubre ese despliegue paso a paso.
Para las copias de seguridad del propio VPS de supervisión — y evitar reconstruir toda la configuración en caso de pérdida — la estrategia 3-2-1 con Restic y almacenamiento S3 se aplica directamente a los volúmenes Docker de esta pila.
Si gestionas varios servidores de clientes desde una sola plataforma, la página /solutions/agences detalla cómo ServOrbit centraliza la supervisión de tu flota en un VPS Start.