Tenía un problema real: mis datos en volúmenes Docker estaban solo en el servidor local. Un fallo de disco y perdía todo. Necesitaba backups automáticos, incrementales y notificaciones cuando algo fallara. Aquí está lo que implementé.
El plan#
Usar rsync para copiar solo lo que cambió, ejecutarlo cada noche con cron, y recibir un email si algo falla. Simple y sin dependencias raras.
Paso 1: Preparar el almacenamiento remoto#
Acceso SSH al servidor remoto configurado sin contraseña (con claves). En mi caso, un NAS en la red.
ssh-keygen -t ed25519 -f ~/.ssh/backup_key -N ""
ssh-copy-id -i ~/.ssh/backup_key user@nas.localCrear el directorio destino:
ssh -i ~/.ssh/backup_key user@nas.local mkdir -p /backups/docker-volumesPaso 2: Crear el script de backup#
Archivo: /opt/backup/backup-docker-volumes.sh
#!/bin/bash
BACKUP_HOST="user@nas.local"
BACKUP_PATH="/backups/docker-volumes"
SSH_KEY="/root/.ssh/backup_key"
DOCKER_VOLUMES_PATH="/var/lib/docker/volumes"
LOG_FILE="/var/log/docker-backup.log"
EMAIL="admin@example.local"
# Función para registrar
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
# Función para enviar alertas
send_alert() {
local subject="$1"
local message="$2"
echo "$message" | mail -s "$subject" "$EMAIL"
}
log "Iniciando backup de volúmenes Docker"
# Listar y respaldar cada volumen
for volume in $(docker volume ls --quiet); do
VOLUME_PATH="$DOCKER_VOLUMES_PATH/$volume/_data"
if [ ! -d "$VOLUME_PATH" ]; then
log "ADVERTENCIA: No se encontró $VOLUME_PATH"
continue
fi
log "Respaldando volumen: $volume"
rsync -avz --delete \
-e "ssh -i $SSH_KEY -o StrictHostKeyChecking=no" \
"$VOLUME_PATH/" \
"$BACKUP_HOST:$BACKUP_PATH/$volume/" \
>> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
log "✓ Volumen $volume respaldado correctamente"
else
log "✗ ERROR respaldando $volume"
send_alert "FALLO: Backup Docker - $volume" \
"El backup del volumen $volume falló. Revisa $LOG_FILE"
exit 1
fi
done
log "Backup completado"
send_alert "OK: Backup Docker completado" "Todos los volúmenes se respaldaron correctamente en $(date)"Dar permisos:
chmod 755 /opt/backup/backup-docker-volumes.shPaso 3: Configurar cron#
Abre el crontab root:
crontab -eAñade esta línea para ejecutar cada noche a las 3 AM:
0 3 * * * /opt/backup/backup-docker-volumes.shPaso 4: Configurar el correo#
Instala un MTA ligero. En Debian/Ubuntu:
apt-get install msmtp msmtp-mtaArchivo de configuración: ~/.msmtprc
defaults
auth on
tls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
account gmail
host smtp.gmail.com
port 587
from docker-backup@example.local
user tu_correo@gmail.com
password tu_contraseña_app
account default : gmailPermisos restringidos:
chmod 600 ~/.msmtprcPaso 5: Prueba#
/opt/backup/backup-docker-volumes.shVerifica el log:
tail -f /var/log/docker-backup.logConsideraciones reales#
Espacio: Los primeros backups pesan. Monitorea el almacenamiento remoto.
Ancho de banda: rsync es eficiente, pero con volúmenes grandes nocturno es mejor.
Seguridad: La clave SSH sin contraseña funciona, pero está en el servidor. Usa permisos restrictivos (600 en la clave).
Rotación: Después de 30 días, los incrementales se acumulan. Considera crear snapshots mensuales completos.
Verificación: Una vez al mes, restaura algo de verdad. Un backup sin testar es un backup que no funciona.
He estado usando esto 8 meses. Solo ha fallado por timeout SSH (solución: aumenté el timeout en rsync). Los emails de confirmación diaria me dan paz mental.