Copias de seguridad de una Raspberry Pi a un NAS con rsync (y los 3 días que fallaron sin que me enterase)
Mi script de copias nocturnas de la Pi a un Synology: espejo, histórico de 30 días y volúmenes de Docker. Y por qué falló sin que nadie se diera cuenta.
Mi Raspberry Pi hace de servidor para casi todo en casa: gestor de contraseñas, repositorio Git, una app de entrenamientos, paneles… Si la tarjeta o el disco se mueren, quiero poder reconstruirla. Así que cada noche, a las 3:30, un script copia todo lo importante a un NAS Synology.
Te enseño cómo está hecho y, sobre todo, cómo falló durante tres días sin que me enterase.
Qué se copia y adónde
El NAS solo tiene abierto SMB (las carpetas compartidas de Windows). Nada de SSH ni rsync en el NAS, así que la Pi monta la carpeta compartida y trabaja sobre ella como si fuera un disco local.
En el NAS la copia queda así:
Backups/pi/
├── actual/ ← espejo de hoy
│ └── volumenes/ ← volúmenes de Docker en .tar.gz
└── historico/
├── 2026-09-23/ ← lo que cambió o se borró ese día
└── 2026-09-24/
El script, por partes
1. Montar el NAS
SHARE="//nas-casa.local/Backups"
mount -t cifs "$SHARE" /mnt/nas-backups \
-o credentials=/root/.smb-nas,vers=3.0,uid=0,gid=0,file_mode=0600,dir_mode=0700
El usuario y la contraseña del NAS están en /root/.smb-nas con permisos 600, no en el script. Y en el NAS hay un usuario dedicado que solo puede escribir en la carpeta de copias. Si alguien entra en la Pi, no tiene acceso al resto del NAS.
2. Guardar el «estado» del sistema
Antes de copiar archivos, el script apunta cómo está montada la Pi: qué contenedores hay, qué volúmenes, qué paquetes, las tareas de cron y un .tar.gz de /etc. Si un día hay que reconstruirla desde cero, eso es la receta.
docker ps -a --format '{{.Names}}\t{{.Image}}\t{{.Ports}}' > estado/docker-ps.txt
dpkg --get-selections > estado/paquetes.txt
tar czf estado/etc.tar.gz /etc
3. Los volúmenes de Docker
Los datos de muchos contenedores viven en volúmenes de Docker, que no son carpetas normales. Para copiarlos, lanzo un contenedor mínimo (Alpine) que monta el volumen en solo lectura y lo empaqueta:
docker run --rm -v "$VOLUMEN":/v:ro -v "$DESTINO":/b alpine \
tar czf "/b/${CONTENEDOR}.tar.gz" -C /v .
Para bases de datos, mejor un volcado propio. Por ejemplo, el gestor de contraseñas tiene un comando de copia de su base de datos, y lo lanzo antes para que el archivo sea consistente.
4. El espejo con histórico
Aquí está lo bueno. rsync copia solo lo que ha cambiado, y con --backup-dir guarda en una carpeta con la fecha todo lo que ha sobrescrito o borrado ese día:
rsync -rlt --delete \
--backup --backup-dir="/mnt/nas-backups/pi/historico/$(date +%F)" \
--exclude='node_modules' --exclude='*.log' \
"${ORIGENES[@]}" /mnt/nas-backups/pi/actual/
--deletehace queactual/sea un espejo exacto.- Lo que se borra o cambia no se pierde: pasa al histórico del día.
- Una línea de
findborra los históricos de más de 30 días.
Como SMB no guarda propietarios ni permisos de Linux, no se los pido (-rlt en vez de -a).
5. Avisar de que ha ido bien
Al terminar, si todo fue bien, el script hace una petición a un monitor de tipo push de Uptime Kuma. Si una noche no llega esa llamada, Kuma marca la copia como fallida.
Los tres días que fallaron sin que me enterase
Del 20 al 22 de septiembre, el registro decía esto cada noche:
2026-09-20 03:30:07 ERROR: no se pudo montar //192.168.1.60/Backups
2026-09-21 03:30:07 ERROR: no se pudo montar //192.168.1.60/Backups
2026-09-22 03:30:07 ERROR: no se pudo montar //192.168.1.60/Backups
El NAS había cambiado de dirección IP. El router se la asigna por DHCP y, tras un reinicio, le dio otra. El script lo buscaba en la antigua, no lo encontraba y abortaba.
Lo peor no fue el fallo, sino que nadie se enteró en tres días. Uptime Kuma sí lo sabía: el monitor de la copia estaba en rojo. Pero no tenía ninguna notificación configurada. Una alarma sin sirena.
Arreglé dos cosas:
- Montar el NAS por su nombre (
nas-casa.local) en vez de por IP. La Pi lo resuelve por mDNS aunque cambie de dirección. - Configurar avisos en Telegram en Uptime Kuma, para que un fallo así me llegue al móvil esa misma noche. Lo cuento paso a paso en otro artículo.
La solución de fondo es darle al NAS una IP fija con una reserva DHCP en el router. Está en mi lista de pendientes.
Otra trampa: borrar algo que sigue en la lista
Hace poco desinstalé un programa de la Pi y borré su carpeta. Esa carpeta seguía en la lista de orígenes del script. Si no lo llego a ver, esa noche rsync habría terminado con error (un origen que no existe) y la copia habría salido como fallida.
Regla: cuando quites algo del sistema, quítalo también del script de copias. Y al revés: si instalas algo con datos importantes, añádelo.
Checklist rápido
- Credenciales del NAS fuera del script, con permisos
600. - Usuario del NAS que solo pueda escribir en la carpeta de copias.
- El NAS montado por nombre, o con IP fija.
- Volúmenes de Docker y volcados de bases de datos incluidos.
- Histórico de días anteriores, no solo el espejo.
- Un monitor que avise si la copia no llega. Y que avise de verdad.
- Probar a restaurar algo de vez en cuando. Una copia que nunca has restaurado es una esperanza, no una copia.
¿Te has quedado con la idea?
Tres preguntas rápidas. Cada acierto suma 10 XP.