Durante meses tuve la sensación tranquilizadora de "tengo backups" sin haber comprobado nunca si esos backups servían para algo. El servidor corre Home Assistant, el llamador de Bingo, el dashboard de monitoreo, este mismo blog y un par de cosas más, todo en Docker. Un cron corriendo restic cada noche contra un repositorio cifrado en almacenamiento remoto me daba la falsa sensación de que el problema de los backups ya estaba resuelto. No lo estaba: solo había resuelto la mitad, la de guardar. La otra mitad, la de recuperar, seguía siendo una hipótesis.
La diferencia entre esas dos mitades es la misma que separa un log de un sistema de observabilidad, o un firewall de una capa de seguridad real: tener el dato no es lo mismo que poder usarlo cuando de verdad lo necesitas. Ya me había topado con esa lección al descubrir que un ban de firewall no sirve contra tráfico que llega por un túnel. Con los backups pasó algo parecido: la sensación de seguridad y la seguridad real no siempre coinciden.
El ejercicio de restaurar en frío
Para probarlo de verdad, no alcanza con hacer restic restore sobre el mismo servidor: eso solo confirma que el snapshot existe, no que alguien sin contexto previo podría levantar todo desde cero. Así que armé un contenedor limpio, sin nada del setup original, y traté de reconstruir el stack completo solo a partir del backup y de lo que tuviera anotado.
Ahí aparecieron los huecos reales. El repositorio de restic tenía los volúmenes con datos —la base de configuración de Home Assistant, los datos de la app de Bingo, los assets del blog— pero no tenía el docker-compose.yml ni los archivos .env con las variables de cada servicio, porque vivían fuera de los volúmenes montados y nunca entraron al scope del backup. Tenía el contenido sin el plano de cómo volver a armarlo. Es el mismo tipo de error que casi me hizo abandonar Home Assistant cuando su configuración de red se regeneraba sola y perdía ajustes críticos: uno asume que lo importante está en un solo lugar hasta que la restauración —o el error— te muestra que estaba repartido en dos.
Dónde ayudó realmente la IA, y dónde no
Para escribir el script de restauración —el que reconstruye el árbol de directorios, restaura cada volumen en su ruta y levanta los contenedores en el orden correcto— usé Claude Code como par de revisión, no como autor. Le pasé el script y el docker-compose.yml y le pedí que buscara casos donde el orden de arranque importara: por ejemplo, que el contenedor de Home Assistant en modo --network host no dependiera de un healthcheck que nunca se resuelve si el volumen de configuración todavía no terminó de restaurarse. Encontró exactamente ese caso, algo fácil de pasar por alto cuando uno escribe el script pensando en el camino feliz.
Lo que la IA no resolvió —y no podía resolver— fue decidir qué merecía estar en el backup. Esa fue una decisión de criterio: revisar servicio por servicio qué es estado (recuperable desde un snapshot) y qué es configuración (debe vivir versionada, no solo respaldada). Ese trabajo de trazar el mapa completo de dependencias de cada servicio no se automatiza pidiéndole a un modelo que "revise el backup"; hay que conocer el sistema.
El backup bueno es el que ya restauraste una vez
Terminé con dos cambios concretos: el docker-compose.yml y los .env de cada servicio ahora entran al scope de restic explícitamente en vez de depender de que "estén por ahí", y agregué una restauración de prueba trimestral al mismo contenedor descartable, no como automatización completa sino como recordatorio de calendario para repetir el ejercicio a mano. Un backup que nunca se restauró no es un backup, es una copia con la esperanza puesta encima. La única forma de saber si sirve es necesitarlo antes de que lo necesites de verdad.