Saltar al contenido

Backup del homelab: la regla 3-2-1 aplicada de verdad

Así aplico la regla 3-2-1 al homelab con Restic, disco local y copia remota. Incluye restauración real, errores y qué datos no copio.

11 min de lecturaGonzalo
En esta guía7 secciones
Backup del homelab con regla 3-2-1, Restic, disco local y copia remota

El 14 de agosto de 2026, la copia de seguridad terminó correctamente. Ese resultado tranquiliza, pero un trabajo terminado no demuestra que puedas restaurarlo. Por eso, antes de escribir esta guía, restauré un fichero del último snapshot y comparé su hash con el original.

La regla 3-2-1 cabe en una frase: tres copias de los datos, en dos soportes distintos y una fuera de casa. Aplicada a un homelab doméstico tiene más esquinas. Un snapshot en el mismo SSD no es otra copia; RAID tampoco. Y duplicar 20 TB de películas que se pueden volver a obtener quizá no sea la mejor manera de gastar disco y subida.

Aquí explico el sistema documentado el 14 de agosto de 2026: Restic crea snapshots cifrados en un SSD USB, y después Rclone replica el repositorio a OpenDrive. La restauración que aparece abajo corresponde a esa fecha, no a una comprobación diaria.

Actualización del 20 de octubre: añadido un ensayo descargable de restauración y el vídeo paso a paso. Usa archivos ficticios y no toca tus copias. Las salidas del servidor de agosto y el ensayo de Rclone de septiembre mantienen sus fechas y su alcance.

Ensaya una restauración

Antes de elegir otro disco, comprueba que entiendes el camino de vuelta. Este laboratorio crea tres archivos ficticios, guarda un snapshot con Restic, aparta el origen sin borrarlo y restaura los archivos en una carpeta nueva. Al final compara sus SHA-256, incluido un archivo vacío y otro con espacios y acentos.

Necesitas Linux, Python 3 y Restic instalado. No necesita sudo, una cuenta, conexión a la nube ni la contraseña de tus copias. Si falta Restic, sigue su instalación oficial.

Descargar el ensayo y la ficha de restauración (ZIP)

  1. Extrae el ZIP. Lee LEEME.md y el código de ensayo.py.
  2. En esa carpeta ejecuta python3 ensayo.py, sin argumentos ni rutas de tus datos.
  3. Abre la carpeta temporal que imprime. Revisa resultado.json: sólo debe decir PASS si los tres archivos restaurados coinciden con sus hashes originales.

Todo queda conservado para inspección; el sistema puede limpiar los temporales más adelante. El script no instala programas, no envía archivos y no acepta repositorios existentes. Puedes leer el código sin descargar el ZIP.

Este ensayo no es tu backup. Repositorio, origen y restauración están en el mismo equipo; no prueba la copia remota, un disco averiado ni la recuperación de Immich. La clave del laboratorio se guarda junto a sus archivos sólo para la demostración: no copies esa práctica a producción.

Ver la demostración y pasar a tus datos

Ver «Tu backup dice OK. Lo ponemos a prueba con Restic» en YouTube: el vídeo muestra el recorrido con un archivo de prueba, desde el snapshot hasta la comparación del contenido. El ZIP es un ejercicio separado para repetir la mecánica, no una descarga de la copia del servidor.

Después usa la ficha «Mi prueba de restauración» incluida en el ZIP: anota la copia elegida, un destino vacío, el resultado y lo que todavía no has probado. No pongas contraseñas en ella. Para tus datos, sigue el procedimiento de tu herramienta; no adaptes las rutas de este laboratorio a producción. Restic documenta cómo restaurar y cómo se elige el destino; restaurar encima de archivos existentes puede sobrescribirlos.

Matriz de pruebas del backup: snapshot reciente, restauración idéntica y réplica remota sin diferencias
Tres comprobaciones distintas. Cada una responde una pregunta concreta; ninguna, por separado, demuestra que pueda recuperar todo el homelab.

Qué merece una copia y qué no

Yo separo datos irrepetibles de datos voluminosos recuperables. En el primer grupo entran las fotos, bases de datos, configuraciones, claves y el contenido del blog. En el segundo están las cachés, imágenes Docker descargables y buena parte de la biblioteca multimedia.

Copiar todo sin seleccionar aumenta el tiempo de subida y el espacio necesario. Restic permite deduplicar, cifrar y recuperar archivos concretos, pero eso no evita decidir qué merece una copia. Las fotos irrepetibles y una caché descargable no tienen el mismo coste de pérdida.

Mi lista práctica queda así:

DatosCopia localCopia fuera de casaMotivo
Fotos y base de datos de ImmichSíSíSon irrepetibles y la base guarda el contexto
Configuración de serviciosSíSíReconstruir a mano es lento y propenso a olvidos
Documentos, proyectos y clavesSíSíPérdida de alto impacto con poco volumen
Películas y series recuperablesNo por defectoNo por defectoMucho volumen; priorizo los datos personales
Cachés y capas de DockerNoNoSe regeneran y solo inflan el repositorio

La copia previa de la base de Immich es importante. El servicio de Restic ejecuta primero un volcado de PostgreSQL. Copiar solo las carpetas de fotos mientras la base está escribiendo puede dejar piezas de momentos distintos; parece una copia hasta el día de restaurarla.

Si lo que quieres proteger es tu galería, sigue la lista de archivos y el ensayo de recuperación de Immich. Incluye las bibliotecas externas: no basta con guardar el volcado automático.

La implementación real

Galería, álbumes y datos de las fotografías en las aplicaciones de Immich
Las fotos no son lo único que hay que recuperar: álbumes y metadatos también importan. Imágenes de las aplicaciones publicadas en el repositorio oficial de Immich.

El temporizador del Beelink lanza el backup cada madrugada. El 14 de agosto vi esta ejecución en systemd:

restic-backup-beelink.service
Active: inactive (dead) since Fri 2026-08-14 03:35:30 UTC
Process: 1579488 ExecStartPre=/usr/local/bin/immich_db_dump.sh (code=exited, status=0/SUCCESS)
Process: 1582645 ExecStart=/usr/local/bin/restic_backup_beelink.sh (code=exited, status=0/SUCCESS)
CPU: 1min 14.478s

La palabra inactive aquí no significa avería: es un servicio oneshot. Arranca, hace el trabajo y termina. Lo que miro es el código 0/SUCCESS, la hora del snapshot y el resultado de una restauración.

El repositorio local está en /media/SDDEXT/backups/restic/beelink, sobre un SSD externo. Restic toma /, aplica un fichero de exclusiones y conserva siete copias diarias, cuatro semanales y tres mensuales. No publico el contenido de las exclusiones ni rutas con secretos; sí la forma del comando:

restic -r "$REPO" --password-file "$PWFILE" backup / \
  --exclude-file=/etc/restic-beelink-excludes.txt --exclude-caches

La contraseña no vive en el script. Está en un fichero legible por root. Parece un detalle menor, pero una copia cifrada con la clave pegada al lado y permisos alegres es una puerta con la llave puesta.

El último snapshot y su tamaño, consultados directamente al repositorio, dieron esto:

ID        Time                 Host          Tags        Paths
--------------------------------------------------------------
094175a2  2026-08-14 03:34:55  beelink-zalo              /
--------------------------------------------------------------
1 snapshots

Snapshots processed:  1
Total Blob Count:  553428
Total Uncompressed Size:  66.259 GiB
Total Size:  46.208 GiB
Compression Ratio:  1.43x
Compression Space Saving:  30.26%

Son datos del snapshot más reciente, no el tamaño total acumulado de toda la política de retención. Esa distinción evita vender el ahorro de deduplicación como si fueran gigabytes mágicamente desaparecidos.

La prueba que importa: restaurar

Elegí /etc/hostname porque es pequeño, no contiene secretos y existe tanto en la máquina viva como en la copia. Restauré el fichero a un directorio temporal, calculé SHA-256 en ambos y ejecuté cmp:

restoring <Snapshot 094175a2 of [/] at 2026-08-14 03:34:55.120406584 +0000 UTC by root@beelink-zalo> to /tmp/restic-restore-check.Mo6fdO
Summary: Restored 2 / 1 files/dirs (13 B / 13 B) in 0:00
live_sha256  9b62af763d4e4351f67a94f1702146e29cf4aae9fa8d14142462df14f916e3b0
restored_sha256  9b62af763d4e4351f67a94f1702146e29cf4aae9fa8d14142462df14f916e3b0
cmp  IDENTICAL

Esto demuestra que ese fichero se recupera idéntico desde el snapshot local. No demuestra por sí solo que podría reconstruir Immich entero. Para eso hace falta un simulacro mayor: base de datos, biblioteca y permisos. Mi manía es empezar con pruebas pequeñas frecuentes y reservar una restauración completa para una ventana en la que pueda parar servicios sin jugar con las fotos familiares.

La réplica fuera de casa y sus límites

En la configuración documentada en agosto, otro temporizador sincroniza el repositorio cifrado a OpenDrive después del backup local. Lo limita a una transferencia y 550 Kbit/s para contener la carga de la réplica. Esa configuración no acredita por sí sola el rendimiento ni la disponibilidad de Plex.

El 14 de agosto de 2026, el servicio de réplica terminó a las 05:29:06 UTC con status=0/SUCCESS. Además comparé el origen y el destino mediante Rclone:

2026/08/14 09:33:10 NOTICE: OpenDrive root 'backups/restic/beelink': 0 differences found
2026/08/14 09:33:10 NOTICE: OpenDrive root 'backups/restic/beelink': 23 matching files

Esa comprobación usó --size-only y profundidad limitada. Sirve para verificar la réplica inmediata de la estructura superior, no sustituye a restic check ni a una restauración desde el remoto. Escribir el límite de cada prueba resulta menos vistoso, pero evita convertir un «parece bien» en una garantía que el comando no ofrece.

Snapshot, RAID y sincronización no son sinónimos

Un snapshot protege muy bien contra un borrado torpe si sigue en el mismo sistema de almacenamiento. No protege contra la muerte física de ese sistema. RAID mantiene el servicio cuando falla un disco; si borras una carpeta, cifra los archivos un ransomware o un comando apunta donde no debe, replica el problema con eficacia impecable.

La sincronización remota también puede propagar un borrado. La retención de Restic no convierte esa réplica en una copia independiente. Si borras una foto del origen, un snapshot anterior puede conservarla. Pero si desaparecen los objetos del propio repositorio y después ejecutas rclone sync, el destino puede perderlos también. La documentación de Rclone explica que sync elimina archivos del destino para igualarlo al origen.

Para cubrir ese segundo fallo hace falta una separación que el servidor no pueda borrar con las mismas credenciales: un disco desconectado o retención inmutable del proveedor, si está disponible y comprobada. Estar fuera de casa resuelve la ubicación; no demuestra esa protección. Esta guía no acredita que el remoto descrito tenga inmutabilidad.

Dos archivos iguales de tamaño, distintos por dentro

El 23 de septiembre hicimos una prueba local con dos archivos ficticios: uno contenía AAAA y el otro BBBB, ambos con salto de línea y cinco bytes. Un tercer archivo existía solo en el destino. No se usó OpenDrive ni ningún repositorio de producción.

ComprobaciónResultado observadoQué permite concluir
rclone check --size-only --one-way0 differences found, salida 0Coincide el tamaño del archivo de origen; su contenido es distinto y el control no lo detecta
rclone check --download --one-waydato.txt: contents differ, salida 1La comparación del contenido sí detecta la diferencia
rclone sync --dry-run -vsolo-destino.txt: Skipped delete as --dry-run is setUna sincronización real intentaría borrar el archivo exclusivo del destino; la simulación lo conservó

Aquí --one-way deja fuera del cotejo los archivos que solo están en destino. Son extractos literales de una prueba pequeña, no una certificación del backup. Rclone documenta ambas opciones de comprobación.

Para revisar un repositorio Restic, restic check comprueba su estructura; leer y verificar también todos los datos requiere --read-data. La documentación de Restic advierte del tiempo y tráfico adicionales. Después queda el examen útil: restaurar desde la copia remota a una carpeta vacía, comparar archivos y, si guardas una aplicación, arrancarla aislada con su base de datos. Ninguno de esos pasos completos se ejecutó en este ensayo.

Para una casa normal, yo montaría las capas en este orden:

  1. Primero, una copia automática en otro disco. Un USB sirve si no se queda olvidado y si el trabajo genera alertas.
  2. Después, una restauración probada. Empieza por un fichero, sigue con una carpeta y termina con el servicio que más dolería perder.
  3. Por último, una copia fuera de casa. Puede ser nube, otro NAS en casa de un familiar o un disco rotado físicamente. Debe estar cifrada antes de salir.

No hace falta comprar un segundo NAS el primer día. Un disco externo bien automatizado es mejor que un diagrama perfecto pendiente de montar. Cuando el volumen crece, la guía de mejores NAS caseros ayuda a calcular discos y bahías; para saber lo que añade a la factura está la calculadora de consumo 24/7. RAID, capacidad y consumo son decisiones distintas, aunque las tiendas intenten meterlas en la misma caja.

Qué cambiaría mañana si empezara de cero

Mantendría Restic y reduciría antes el conjunto de datos. También documentaría la restauración el mismo día que creo el primer snapshot. Un disco conectado al servidor comparte riesgos físicos con él; estar en otro soporte no significa estar en otro lugar. La copia remota añade separación geográfica, con los límites de sincronización y credenciales explicados arriba.

La regla 3-2-1 no se cumple por tener tres carpetas llamadas backup. Se cumple cuando hay copias en soportes y lugares distintos, con historial, cifrado y una ruta de vuelta que has recorrido. La prueba del 14 de agosto recuperó un fichero idéntico. El siguiente examen serio es levantar la base de Immich en un entorno vacío; hasta hacerlo, no voy a llamarlo desastre resuelto.

Pruebas originales: 14 de agosto de 2026. Ensayo Rclone con archivos ficticios: 23 de septiembre. Laboratorio descargable Restic: 20 de octubre. No se ha repetido aquí una restauración del servidor ni se ha probado la recuperación completa de Immich.