MiTechBlog

Cómo programar backups automáticos con rsync y cron en Linux

Aprende a crear un script de backup robusto con rsync, manejo de errores, logs y notificaciones. Incluye configuración de cron para ejecución automática.

Los backups son el seguro de vida de cualquier sistema. No es cuestión de si fallará algo, sino cuándo. En esta guía creamos un script de backup profesional con rsync, logs rotativos, manejo de errores y notificaciones por email.

Por qué rsync + cron

  • rsync: Copia incremental, eficiente en ancho de banda, preserva permisos y ownership
  • cron: Programador nativo del sistema, sin dependencias externas
  • Costo: $0, funciona en cualquier Linux/Unix

El script de backup

Crea /usr/local/bin/backup.sh:

#!/usr/bin/env bash
# backup.sh - Backup incremental con rsync + logs + notificaciones
# Uso: backup.sh [origen] [destino]

set -euo pipefail

# ===== CONFIGURACIÓN =====
ORIGEN="${1:-/home/usuario/documentos}"
DESTINO="${2:-/mnt/backup/documentos}"
LOG_DIR="/var/log/backup"
LOG_FILE="${LOG_DIR}/backup-$(date +%Y%m%d-%H%M%S).log"
EMAIL="[email protected]"
RETENCION_DIAS=30
# ==========================

mkdir -p "${LOG_DIR}"
exec > >(tee -a "${LOG_FILE}") 2>&1

log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; }

log "=== INICIO BACKUP ==="
log "Origen: ${ORIGEN}"
log "Destino: ${DESTINO}"

# Verificaciones previas
[[ -d "${ORIGEN}" ]] || { log "ERROR: Origen no existe"; exit 1; }
[[ -d "${DESTINO}" ]] || { log "ERROR: Destino no existe"; exit 1; }
df -h "${DESTINO}" | awk 'NR==2 {print "Espacio libre: " $4}'

# Ejecutar rsync
log "Iniciando rsync..."
rsync -avh --delete --progress \
  --exclude='*.tmp' \
  --exclude='.cache' \
  --exclude='node_modules' \
  "${ORIGEN}/" "${DESTINO}/" \
  2>&1 | tee -a "${LOG_FILE}"

RSYNC_EXIT=${PIPESTATUS[0]}
if [[ ${RSYNC_EXIT} -eq 0 ]]; then
  log "✅ Backup completado exitosamente"
else
  log "❌ rsync falló con código ${RSYNC_EXIT}"
  echo "Revisa el log: ${LOG_FILE}" | mail -s "❌ Backup FALLÓ - $(hostname)" "${EMAIL}"
  exit ${RSYNC_EXIT}
fi

# Limpieza de logs antiguos
find "${LOG_DIR}" -name "backup-*.log" -mtime +${RETENCION_DIAS} -delete
log "Logs antiguos (>${RETENCION_DIAS} días) eliminados"

log "=== FIN BACKUP ==="

Hazlo ejecutable:

chmod +x /usr/local/bin/backup.sh

Configurar cron

Edita el crontab del usuario que ejecutará el backup:

crontab -e

Añade esta línea para ejecución diaria a las 02:30:

30 2 * * * /usr/local/bin/backup.sh /home/usuario/documentos /mnt/backup/documentos

Verificar que funciona

# Ejecutar manualmente
sudo /usr/local/bin/backup.sh /home/usuario/documentos /mnt/backup/documentos

# Ver logs
tail -f /var/log/backup/backup-*.log

# Ver próximos ejecuciones
crontab -l

Mejoras opcionales

  1. Notificaciones Telegram/Slack: Reemplaza mail por webhook
  2. Cifrado: Añade gpg --encrypt antes de subir a remoto
  3. Cloud: Sube a S3/Wasabi/Backblaze B2 con rclone sync
  4. Monitoring: Integra con Prometheus/Grafana via node_exporter

Conclusión

Este script cubre lo esencial: copia incremental, logs persistentes, limpieza automática y alertas. Es la base sobre la que construir tu estrategia 3-2-1 (3 copias, 2 medios distintos, 1 offsite).

¿Usas otra herramienta? Cuéntamelo en los comentarios.