El problema#
Tengo varios contenedores corriendo en mi servidor doméstico con datos importantes. No puedo depender de backups manuales. Necesitaba algo que:
- Hiciera backups incrementales (no ocupar todo el almacenamiento remoto)
- Se ejecutara automáticamente sin intervención
- Permitiera recuperar datos puntuales
- Rotara snapshots antiguos automáticamente
Después de probar varias opciones, restic fue lo que mejor se adaptó.
¿Por qué restic?#
Es simple, rápido y soporta múltiples backends (S3, B2, SFTP, local). Los backups son incrementales por defecto, encriptados y deduplicados. Perfecto para mi caso de uso.
Instalación#
En mi servidor con Ubuntu/Debian:
curl -b /tmp/restic.bz2 https://github.com/restic/restic/releases/download/v0.16.0/restic_0.16.0_linux_amd64.bz2
bunzip2 /tmp/restic.bz2
sudo mv /tmp/restic /usr/local/bin/
sudo chmod +x /usr/local/bin/restic
restic versionConfiguración del repositorio remoto#
Uso Backblaze B2 por ser económico. Creas una clave de aplicación en el panel web y configurar las credenciales:
export B2_ACCOUNT_ID="tu_account_id"
export B2_ACCOUNT_KEY="tu_app_key"
restic init -r b2:nombre-bucket:/backups/dockerEsto crea el repositorio remoto. Guarda la contraseña en un lugar seguro (no en variables de entorno públicas).
Script de backup automatizado#
Creo /usr/local/bin/backup-docker-volumes.sh:
#!/bin/bash
set -e
# Credenciales y configuración
export B2_ACCOUNT_ID="${B2_ACCOUNT_ID}"
export B2_ACCOUNT_KEY="${B2_ACCOUNT_KEY}"
export RESTIC_REPOSITORY="b2:nombre-bucket:/backups/docker"
export RESTIC_PASSWORD="${RESTIC_PASSWORD}"
# Log
LOGFILE="/var/log/docker-backup.log"
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Iniciando backup de volúmenes Docker" >> $LOGFILE
# Volúmenes a respaldar
VOLUMES=("database_data" "app_config" "media_files")
for volume in "${VOLUMES[@]}"; do
MOUNT_PATH="/mnt/backup-temp/$volume"
# Montar volumen temporalmente
mkdir -p $MOUNT_PATH
docker run --rm -v $volume:$MOUNT_PATH -v backup-data:/backup \
alpine tar czf /backup/${volume}.tar.gz -C $MOUNT_PATH .
# Respaldar con restic
if restic backup /backup/${volume}.tar.gz \
--tag "docker-$volume" \
--hostname "servidor-docker" >> $LOGFILE 2>&1; then
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ✓ $volume respaldado correctamente" >> $LOGFILE
else
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ✗ Error en backup de $volume" >> $LOGFILE
fi
rm -f /backup/${volume}.tar.gz
done
# Limpiar snapshots antiguos
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Ejecutando rotación de snapshots" >> $LOGFILE
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune >> $LOGFILE 2>&1
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Backup completado" >> $LOGFILEAutomatización con cron#
Edito /etc/cron.d/docker-backup:
# Backup diario a las 2:00 AM
0 2 * * * root /usr/bin/env bash /usr/local/bin/backup-docker-volumes.shY creo /etc/default/docker-backup para las variables:
export B2_ACCOUNT_ID="valor_real"
export B2_ACCOUNT_KEY="valor_real"
export RESTIC_PASSWORD="contraseña_fuerte"Aseguré que solo root pueda leerlo: chmod 600 /etc/default/docker-backup
Monitoreo y recuperación#
Para listar snapshots disponibles:
restic snapshotsPara recuperar un volumen específico:
restic restore latest --target /tmp/restore --select "database_data"Resultados reales#
Después de 3 meses:
- Backups de ~15GB se comprimen a 3GB incremental
- Costo aproximado: 2-3 USD/mes en B2
- Tiempo de backup: 8 minutos diarios
- Recuperación de un volumen completo: ~2 minutos
Notas importantes#
- Validé que los backups sean recuperables (fundamental)
- Ajusté la política de retención según mis necesidades
- Monitoreo los logs regularmente para detectar fallos
- Las credenciales están en archivos protegidos, nunca en git
Es una solución sencilla que funciona. No es sofisticada, pero es confiable.