De un VPS comercial al salón de casa. Parte 4 – Copia de seguridad

De un VPS comercial al salón de casa. Parte 4 – Copia de seguridad

He dividido la copia de seguridad en dos partes. La primera comprende una copia de las carpetas donde se encuentra el contenido de las webs y las bases de datos. La segundo consiste en crear una imagen completa de la tarjeta MicroSD.

Depende de vuestro caso particular es posible que mi solución no os valga y tengáis que buscar alguna alternativa para la primera parte o simplemente descartarla.

Mi situación parte de que tengo un disco NAS con OpenWRT lo que me permite configurar una carpeta para mi copia de seguridad del server de forma muy sencilla.

Primera parte

                     ┌─────────────────────────┐
                     │        Red LAN          │
                     │     192.168.2.0/24      │
                     └───────────┬─────────────┘
                                 │
        ┌────────────────────────┴────────────────────────┐
        │                                                 │
┌───────────────────────┐                     ┌────────────────────────┐
│    Raspberry Pi       │                     │      NAS OpenWrt       │
│   192.168.2.160       │                     │     192.168.2.150      │
│                       │                     │                        │
│  Debian Bookworm      │                     │  OpenWrt 22.x          │
│                       │                     │                        │
│  Servicios activos    │                     │  Disco USB / SATA      │
│  - nginx              │                     │  /dev/sda3 1.8T        │
│  - php-fpm            │                     │                        │
│  - bases de datos     │                     │  Montaje real          │
│                       │                     │  /mnt/sda/backupRPI    │
│  Script backup        │                     │                        │
│  /usr/local/bin/      │                     │  Bind mount            │
│  backup_raspi.sh      │                     │  /backupRPI -> /mnt/sda│
│                       │                     │                        │
│  Punto NFS            │   NFSv4             │  Export NFS            │
│  /mnt/backupRPI ────────────────►           │  /backupRPI            │
│                       │                     │                        │
│  rsync (nice+ionice)  │                     │  FS ext4               │
│                       │                     │                        │
│  Backup resultante    │                     │  Datos almacenados     │
│  /etc                 │                     │  current/              │
│  /var                 │                     │  snapshot_YYYY-MM-DD   │
│  /home                │                     │                        │
│  /boot/firmware       │                     │                        │
└───────────────────────┘                     └────────────────────────┘

Configuración en el NAS

# Ver todos los discos y comprobar el disco grande
df -h

# Crear carpeta real de backups en el disco grande
mkdir -p /mnt/sda/backupRPI

# Ajustar permisos para que la Raspberry pueda escribir
chown -R 1000:1000 /mnt/sda/backupRPI
chmod 775 /mnt/sda/backupRPI

# Crear punto exportado independiente
rm -rf /backupRPI
mkdir /backupRPI

# Bind mount para que /backupRPI apunte al disco grande
nano /etc/fstab

Tip: Nano es un editor de archivos desde línea de comandos. Siempre que tengáis que modificar un archivo simplemente pegar el contenido que se indique y a continuación pulsar CTRL+O seguido de ENTER para guardar y CTRL+X para salir.

# contenido a pegar en /etc/fstab (Guardar y salir de nano)
/mnt/sda/backupRPI   /backupRPI   none   bind   0   0

# Aplicar mounts
mount -a

# Configurar export NFS
nano /etc/exports

# contenido de /etc/exports (Guardar y salir de nano)
/backupRPI 192.168.2.0/24(rw,sync,no_subtree_check,no_root_squash)

# Recargar exports NFS
exportfs -ra
/etc/init.d/nfsd restart

Configuración en la Raspi

# Crear punto de montaje local
sudo mkdir -p /mnt/backupRPI

# Montar el recurso NFS del NAS
sudo mount -t nfs 192.168.2.150:/backupRPI /mnt/backupRPI

# Verificar tamaño correcto del destino (Debe verse el tamanño real del disco (ej: 1.8T))
df -h /mnt/backupRPI

Automatizamos la copia de archivos mediante este script de shell

# Creamos el script
sudo nano /usr/local/bin/backup_raspi.sh
#!/bin/bash
set -euo pipefail

DEST="/mnt/backupRPI"
MIN_FREE_GB=20
LOCK="/tmp/backup_raspi.lock"

DATE=$(date +%F)
LOG="$DEST/backup_$DATE.log"

exec 9>"$LOCK" || exit 1
trap 'rm -f "$LOCK"' EXIT
flock -n 9 || exit 0

if ! mountpoint -q "$DEST"; then
  logger -t BACKUP_RPI "ABORTADO: destino no montado"
  exit 1
fi

FSTYPE=$(findmnt -n -o FSTYPE --target "$DEST")
if [[ "$FSTYPE" != nfs* ]]; then
  logger -t BACKUP_RPI "ABORTADO: destino no es NFS"
  exit 1
fi

FREE_GB=$(df -BG --output=avail "$DEST" | tail -1 | tr -dc '0-9')
if (( FREE_GB < MIN_FREE_GB )); then
  logger -t BACKUP_RPI "ABORTADO: espacio insuficiente"
  exit 1
fi

if [[ "$DEST" == "/" || "$DEST" == "/mnt" || "$DEST" == "/mnt/" ]]; then
  logger -t BACKUP_RPI "ABORTADO: destino inseguro"
  exit 1
fi

mkdir -p "$DEST/current"

nice -n 19 ionice -c2 -n7 rsync -a \
  --numeric-ids \
  --delete \
  --info=stats2 \
  --no-acls \
  --no-xattrs \
  --exclude={"/proc/*","/sys/*","/dev/*","/run/*","/tmp/*","/mnt/*","/media/*","/lost+found"} \
  /etc \
  /home \
  /var \
  /boot/firmware \
  "$DEST/current" >> "$LOG" 2>&1

if [[ "$(date +%u)" -eq 7 ]]; then
  cp -al "$DEST/current" "$DEST/snapshot_$DATE"
fi
# Permisos
sudo chmod +x /usr/local/bin/backup_raspi.sh

# Ejecutar backup manualmente (tarda unos minutos dependiendo del volumen del backup)
sudo /usr/local/bin/backup_raspi.sh

# Si el backup ha ido bien lo programamos
# Editar cron del root
sudo crontab -e

# Backup diario a las 03:00
0 3 * * * /usr/local/bin/backup_raspi.sh

Diagnóstico y comprobaciones

# Ver mensajes de aborto del script
journalctl -t BACKUP_RPI

# Ver logs del backup del dia
ls -lh /mnt/backupRPI/backup_$(date +%F).log
tail -n 20 /mnt/backupRPI/backup_$(date +%F).log

# Ver contenido del backup actual
ls -lh /mnt/backupRPI/current
du -sh /mnt/backupRPI/current

Comandos de recuperación ante fallo de la copia

# Parar una copia de seguridad colgada
sudo pkill rsync

# Desmontar NFS de forma segura
sudo umount -l /mnt/backupRPI

# Limpiar lock manualmente (solo si no hay backup activo)
sudo rm -f /tmp/backup_raspi.lock

Restaurar desde la copia de seguridad

PasoDescripcion
Parar serviciosEvitar escrituras
Restaurar /etcConfiguracion
Restaurar /varDatos
Restaurar /homeUsuarios
syncVaciar cache
rebootAplicar cambios
# Detenemos todo lo que escriba en disco
sudo systemctl stop nginx
sudo systemctl stop php8.2-fpm
sudo systemctl stop mariadb
sudo systemctl stop postgres
sudo systemctl stop smbd
sudo systemctl stop cron

# Restaurar en tres fases

# 1) Restaurar /etc (restaura usuarios, servicios y configuraciones)
sudo rsync -a \
  --numeric-ids \
  /mnt/backupRPI/current/etc/ \
  /etc/

# 2) Restaurar /var (restaura webs, bases de datos, logs y caches)
sudo rsync -a \
  --numeric-ids \
  /mnt/backupRPI/current/var/ \
  /var/

# 3) Restaurar /home (usuarios)
sudo rsync -a \
  --numeric-ids \
  /mnt/backupRPI/current/home/ \
  /home/

# Sincronizar
sync

# Reiniciar
sudo reboot

# Comprobar tras el reinicio
systemctl status nginx php8.2-fpm
df -h

Segunda parte

Si no dispones de otra máquina, el plan B consiste en crear una imagen completa de la tarjeta midroSD de forma manual. Este proceso se puede hacer tanto desde Linux como desde Windows con herramientas como Raspberry Pi Imager, Win32 Disk Imager o BalenaEtcher. La únicas pegas son que mientras creas la imagen dejas el servidor fuera de servicio durante unos minutos y que tienes que tener la disciplina para crear la copia semanalmente. Por lo demás, con este método puedes tener otra microSD gemela preparada ante desastre con un lapsus de datos de 1 semana como máximo.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Información básica sobre protección de datos
Responsable Garikoitz Martínez Moreno +info...
Finalidad Gestionar y moderar tus comentarios. +info...
Legitimación Consentimiento del interesado. +info...
Destinatarios Automattic Inc., EEUU para filtrar el spam. +info...
Derechos Acceder, rectificar y cancelar los datos, así como otros derechos. +info...
Información adicional Puedes consultar la información adicional y detallada sobre protección de datos en nuestra página de política de privacidad.