Ir al contenido
  1. Posts/

Automatizar comprobaciones tras actualizar: pruebas simples para saber si algo sigue vivo

Actualizar un homelab no termina cuando vuelve el prompt. Esa es la mentira cómoda.

El comando puede acabar bien, Docker puede decir que los contenedores están arriba, Proxmox puede enseñar todo verde y aun así tener una aplicación rota, un login que no entra, un DNS que resuelve mal, una automatización que ya no dispara o un backup que se ha quedado apuntando a ninguna parte.

Por eso me gustan las comprobaciones después de actualizar. No hablo de montar una plataforma enorme de testing en casa. Hablo de pruebas pequeñas, repetibles y bastante tontas que contesten una pregunta: ¿lo que usa la casa sigue vivo?

La idea es quitarme de encima la revisión manual más torpe. Después de actualizar un servidor, reiniciar una VM o tocar contenedores, quiero ejecutar una batería corta y ver si lo crítico responde. Si algo falla, prefiero enterarme en ese momento, no cuando alguien intenta abrir una app y me mira como si yo fuese el departamento de incidencias de la vivienda.

Primero defino qué significa “vivo”
#

El primer error es comprobar solo si el proceso está levantado. Un contenedor running no significa que el servicio funcione. Una VM encendida no significa que la aplicación esté bien. Un puerto abierto no significa que el login cargue.

Para cada servicio importante intento definir una señal mínima de vida. No perfecta. Mínima.

Ejemplos:

  • Un servicio web responde con HTTP 200 o 302.
  • DNS resuelve un nombre interno esperado.
  • El proxy devuelve el certificado correcto.
  • Una API de salud responde con estado correcto.
  • La base de datos acepta conexión.
  • Un backup reciente existe y no pesa cero.
  • Una automatización básica aparece habilitada.
  • Un recurso de red monta donde debe.

La comprobación buena no tiene que probar toda la aplicación. Tiene que detectar fallos obvios. Si después de actualizar el dashboard carga pero una función rara falla, eso ya es otro nivel. Lo que quiero aquí es evitar el clásico “estaba caído desde ayer y nadie miró”.

Esto encaja con la idea de alertas útiles en casa. Si alertas por todo, acabas ignorándolo. Si compruebas lo justo después de tocar algo, el ruido baja muchísimo.

Mi lista corta después de actualizar
#

Tengo una lista mental que casi siempre repito. Cuando el cambio afecta a un servidor o a un grupo de servicios, miro esto:

  1. Red básica.
  2. DNS interno.
  3. Acceso remoto.
  4. Reverse proxy.
  5. Servicios web críticos.
  6. Bases de datos.
  7. Backups.
  8. Domótica o servicios familiares.
  9. Logs recientes con errores groseros.
  10. Espacio en disco.

No todo aplica siempre. Si actualizo un contenedor aislado, no reviso media infraestructura. Si actualizo el nodo que lleva DNS, proxy o almacenamiento, sí me pongo más serio.

La clave es tener dos niveles: comprobación rápida y comprobación profunda.

La rápida debería tardar menos de un minuto. Es la que ejecuto después de un cambio menor. La profunda puede tardar más y la uso tras actualizaciones grandes, reinicios de nodos o migraciones.

HTTP: la prueba simple que detecta mucho
#

Para servicios web, una petición HTTP sigue siendo la prueba más barata. No necesito abrir diez pestañas. Necesito saber si responde algo razonable.

Un ejemplo simple:

1
curl -fsS https://servicio.tu-dominio.com/ >/dev/null

Si el servicio devuelve error, el comando falla. Si responde bien, sigue. Para algunos servicios un 302 al login es correcto. Para otros necesito una ruta /health, /api/health o una página concreta.

Lo importante es no quedarse en “el puerto 443 está abierto”. Eso solo dice que algo escucha. Yo quiero saber si el proxy llega al backend y si el backend no está muerto.

En servicios internos uso nombres genéricos, no IPs pegadas en scripts. Si el DNS interno está bien montado, https://paperless.home.local o el nombre que uses debería resolver. Si tengo que perseguir IPs después de cada migración, el problema no es el script. Es la arquitectura.

Para varios servicios, un archivo de endpoints es suficiente:

1
2
3
4
https://dns.home.local/
https://docs.home.local/
https://fotos.home.local/
https://monitor.home.local/

Y una vuelta simple:

1
2
3
4
5
while read -r url
do
  [ -z "$url" ] && continue
  curl -fsS "$url" >/dev/null && echo "OK $url" || echo "FAIL $url"
done < endpoints.txt

No es bonito. Funciona.

DNS: si falla, todo parece roto
#

DNS merece una prueba propia porque cuando falla suele disfrazarse de mil cosas. El servicio está vivo, pero el navegador no llega. El proxy funciona, pero el nombre interno no resuelve. Tailscale conecta, pero el nombre que usas fuera no apunta donde toca.

Después de tocar red, router, contenedores DNS o firewall, pruebo resoluciones concretas:

1
dig +short servicio.home.local

También pruebo contra el DNS interno directamente si sospecho algo:

1
dig @192.168.1.10 servicio.home.local +short

Uso una IP de ejemplo aquí. En mis notas reales evito dejar direcciones sensibles en contenido público. En tu casa, lo importante es que la prueba pregunte al resolver correcto y compare contra lo esperado.

Para mí hay tres niveles:

  • El cliente resuelve el nombre.
  • El DNS interno responde bien.
  • El nombre apunta al sitio correcto.

Si solo compruebas el primer punto, puedes perderte errores de split-horizon, caché o rutas raras. DNS es el fontanero del homelab. Nadie lo mira cuando va bien y todo huele fatal cuando falla.

Contenedores: no basta con running
#

Docker y Compose pueden engañar bastante. Un contenedor puede estar arriba y la app dentro estar rota. Aun así, mirar estado ayuda a detectar caídas evidentes.

Tras actualizar un stack, reviso:

1
docker compose ps

Y luego logs recientes:

1
docker compose logs --tail=80

No quiero leer literatura. Busco errores claros: migraciones fallidas, conexiones rechazadas, permisos, rutas que no existen, base de datos inaccesible.

Para automatizar, me gusta separar dos cosas. Primero, que los contenedores esperados estén arriba. Segundo, que la app responda desde fuera. Si la primera pasa y la segunda falla, el problema suele estar en proxy, red interna, configuración o salud real de la aplicación.

Con servicios serios intento usar healthchecks en Compose. No siempre son perfectos, pero ayudan:

1
2
3
4
5
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
  interval: 30s
  timeout: 5s
  retries: 3

Esto no sustituye a una prueba externa. El contenedor puede verse sano desde dentro y ser inaccesible desde la red. Pero como primera línea está bien.

Bases de datos: conexión y backup reciente
#

Si un servicio usa base de datos, la prueba web puede no bastar. Algunas aplicaciones cargan pantalla de login aunque tengan tareas internas rotas. Otras fallan solo al escribir.

No hago pruebas complejas en cada actualización, pero sí miro dos cosas:

  • La base de datos acepta conexión.
  • Hay backup lógico reciente.

Para PostgreSQL, una comprobación mínima puede ser pg_isready. Para MariaDB, una conexión simple. Para SQLite, que el archivo existe, tiene tamaño razonable y el servicio puede abrirlo.

Más importante que la prueba exacta es tenerla documentada. En el artículo sobre servicios self-hosted con base de datos cuento cómo decido entre SQLite, PostgreSQL y MariaDB. Después de actualizar, esa decisión se nota. Si cada app tiene su motor y nadie sabe cómo comprobarlo, la revisión se vuelve una gymkhana.

El backup reciente es mi red de seguridad. No quiero descubrir después de una migración mala que el último dump válido tiene tres semanas. Una prueba simple puede comprobar que existe un archivo de backup de las últimas 24 horas y que no está vacío.

1
find ./backups -type f -mtime -1 -size +1k | grep -q . && echo "backup reciente" || echo "sin backup reciente"

Cutre, sí. Mejor que rezar.

Espacio en disco: el fallo tonto que tumba servicios serios
#

Después de actualizar, sobre todo contenedores, miro espacio. Imágenes antiguas, capas, logs y backups pueden comerse más de lo esperado. Un disco lleno rompe bases de datos, colas, logs y servicios que parecían sanos hace cinco minutos.

La comprobación mínima:

1
df -h

Para automatizar, prefiero umbrales claros. Si una partición pasa del 85 por ciento, aviso. Si pasa del 95, paro y limpio antes de seguir. No hay heroísmo en actualizar con el disco al límite.

También reviso logs de Docker si un servicio crece mucho. Hay contenedores que convierten un error repetido en una trituradora de espacio. Si ves que un log crece sin parar después de actualizar, no lo ignores. Es el servicio gritando en burocrático.

Domótica y servicios familiares
#

Aquí entra la parte menos técnica y más importante. Si algo lo usa la familia, no basta con que esté “técnicamente operativo”. Tiene que funcionar desde el móvil, desde el salón o desde donde se use de verdad.

Después de tocar Home Assistant, DNS, proxy o red, pruebo una automatización sencilla o una entidad crítica. No hace falta encender media casa. Una comprobación básica de API o abrir el panel puede bastar.

Lo mismo con fotos, documentos, recetas o contraseñas. Si el servicio forma parte de la vida diaria, la prueba debe parecerse al uso real. Cargar una foto. Buscar un documento. Entrar al gestor. Ver que el móvil sincroniza.

Esta es la diferencia entre homelab como juguete y homelab como infraestructura doméstica. En el juguete, si falla algo, ya lo mirarás. En casa, si falla algo que otros usan, el SLA te lo explica tu pareja con una mirada bastante efectiva.

Un script pequeño gana a una memoria grande
#

No hace falta empezar con Ansible, Grafana, Prometheus y una liturgia completa. Puedes empezar con un script post-update-check.sh y un archivo de endpoints.

Mi versión mínima tendría:

  • Comprobación de DNS.
  • Comprobación HTTP de servicios críticos.
  • Espacio en disco.
  • Estado de contenedores importantes.
  • Backup reciente.
  • Salida clara con OK o FAIL.

Algo así:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/usr/bin/env bash
set -u

fail=0

check_url() {
  url="$1"
  if curl -fsS "$url" >/dev/null
  then
    echo "OK  $url"
  else
    echo "FAIL $url"
    fail=1
  fi
}

check_url "https://docs.home.local/"
check_url "https://monitor.home.local/"
check_url "https://fotos.home.local/"

df -h | awk 'NR==1 || $5+0 > 85 {print}'

if find ./backups -type f -mtime -1 -size +1k | grep -q .
then
  echo "OK  backup reciente"
else
  echo "FAIL backup reciente"
  fail=1
fi

exit "$fail"

En contenido público usaría nombres genéricos. En tu homelab, pon tus servicios reales. Lo importante es que el script falle cuando algo relevante no pasa la prueba.

Luego puedes mejorarlo. Añadir colores, JSON, notificaciones, integración con Uptime Kuma o lo que quieras. Pero el valor está en la primera versión que ejecutas después de actualizar.

Cuándo automatizo y cuándo miro a mano
#

No todo merece automatización. Si actualizo una app secundaria que casi no uso, una comprobación manual puede bastar. Si toco DNS, proxy, bases de datos, almacenamiento, backup o domótica, prefiero script.

Mi regla:

  • Cambio pequeño en servicio prescindible: prueba manual.
  • Cambio en servicio usado por casa: checklist corta.
  • Cambio en infraestructura compartida: script de comprobación.
  • Cambio grande o migración: script más runbook abierto.

El runbook importa porque el script te dice qué falla, pero no siempre qué hacer. Si falla DNS, quiero una nota con el orden de diagnóstico. Si falla backup, quiero saber cómo restaurar o dónde mirar. Automatizar detección sin documentar respuesta solo cambia el momento del pánico.

Mi conclusión
#

Actualizar sin comprobar es apostar. A veces sale bien. A veces te enteras del fallo al día siguiente, con menos tiempo y más mala leche.

No hace falta montar un sistema perfecto. Un puñado de pruebas simples ya mejora mucho la operación de un homelab: HTTP, DNS, contenedores, bases de datos, backups y disco. Lo justo para saber si lo importante sigue vivo.

La parte buena es que estas pruebas envejecen mejor que la memoria. Las escribes una vez, las ajustas cuando cambias servicios y las ejecutas cuando toca. No dan glamour, pero evitan tardes absurdas.

Y en casa, evitar tardes absurdas es una métrica bastante seria.