El problema#
Después de perder datos por un fallo de almacenamiento, aprendí que los contenedores Docker son efímeros. Los volúmenes que albergan bases de datos, configuraciones y archivos importantes necesitan protección. Backups manuales no escalan. Necesitaba algo automatizado, eficiente y verificable.
Elegí restic porque hace backups incrementales (solo guarda cambios), es agnóstico del destino (local, S3, B2, etc.) y verifica integridad con hash. Combinado con cron, tengo una solución sólida.
Instalación#
En mi servidor Debian, instalo restic:
sudo apt-get update && sudo apt-get install -y resticPara backups locales, creo el directorio de destino:
sudo mkdir -p /mnt/backup-storage
sudo chmod 700 /mnt/backup-storageSi usas almacenamiento remoto (recomendado), configura credenciales. Yo uso un bucket S3 local con Minio, pero la sintaxis es similar.
Inicializar repositorio#
Restic necesita un repositorio inicializado. Lo hago una sola vez:
restic -r /mnt/backup-storage initMe pide una contraseña. La guardo en un gestor seguro. Sin ella, los backups son inútiles.
Script de backup#
Creo /usr/local/bin/backup-docker-volumes.sh:
#!/bin/bash
# Variables
RESTIC_REPO="/mnt/backup-storage"
RESTIC_PASSWORD="tu_contraseña_aqui"
LOG_FILE="/var/log/docker-backup.log"
DOCKER_VOLUMES_PATH="/var/lib/docker/volumes"
# Timestamp
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
# Exportar variables para restic
export RESTIC_REPOSITORY="$RESTIC_REPO"
export RESTIC_PASSWORD="$RESTIC_PASSWORD"
# Función de logging
log() {
echo "[$TIMESTAMP] $1" >> "$LOG_FILE"
}
log "=== Iniciando backup de volúmenes Docker ==="
# Backup de volúmenes
restic backup "$DOCKER_VOLUMES_PATH" \
--tag docker-volumes \
--exclude='lost+found' \
--exclude='.git' \
>> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
log "✓ Backup completado exitosamente"
else
log "✗ Error durante el backup"
exit 1
fi
# Limpiar snapshots antiguos (mantener últimos 30 días)
restic forget --keep-daily 30 --prune >> "$LOG_FILE" 2>&1
log "=== Limpieza de snapshots antiguos completada ==="
# Verificar integridad
restic check >> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
log "✓ Verificación de integridad exitosa"
else
log "✗ Error en verificación de integridad"
exit 1
fiHago el script ejecutable:
sudo chmod +x /usr/local/bin/backup-docker-volumes.shProgramar con cron#
Edito la tabla cron del root:
sudo crontab -eAgrego esta línea para ejecutar backups diariamente a las 2 AM:
0 2 * * * /usr/local/bin/backup-docker-volumes.shPara backups cada 6 horas:
0 */6 * * * /usr/local/bin/backup-docker-volumes.shVerifico que se ejecute:
sudo grep CRON /var/log/syslog | tail -5Recuperación ante desastres#
Cuando necesito restaurar:
# Listar snapshots disponibles
restic snapshots
# Restaurar un snapshot específico
restic restore [snapshot-id] --target /mnt/restore-pointSi un contenedor se corrompió, detengo el stack, restauro el volumen y reinicio:
docker-compose down
restic restore [snapshot-id] --target /var/lib/docker/volumes/mi-volumen
docker-compose up -dBuenas prácticas aprendidas#
- Nunca guardes la contraseña en texto plano en cron. Yo uso un archivo
/root/.restic-passcon permisos 600. - Monitorea los logs. Configura alertas si los backups fallan.
- Prueba restauraciones regularmente. Un backup no probado es un backup que no funciona.
- Guarda backups fuera de tu servidor. La redundancia local no te protege de hardware fallido.
- Cifra los backups si los envías a cloud. Restic lo hace por defecto.
Resultado#
Ahora duermo tranquilo. Mis volúmenes Docker se respaldan cada 6 horas, solo guardo cambios (restic es eficiente), y puedo recuperar cualquier cosa en minutos. El destino de mis backups es un NAS en otra ubicación, así que aunque el servidor explote, mis datos están seguros.