El problema#
Tenía varios contenedores Docker corriendo servicios críticos en mi servidor doméstico. La idea de perder datos por un fallo de disco me mantenía despierto. Necesitaba una solución que:
- Fuera incremental (no copiar todo cada vez)
- Se ejecutara automáticamente sin intervención
- Permitiera rotación de copias antiguas
- Guardara los datos en almacenamiento remoto
Después de probar varias opciones, restic fue la respuesta. Es rápido, eficiente y se integra bien con cron.
Instalación de restic#
Lo primero es instalar restic en el servidor:
curl -sL https://api.github.com/repos/restic/restic/releases/latest | grep -oP '"browser_download_url": "\K.*linux_amd64\.bz2' | head -1 | xargs wget -O - | bunzip2 > /usr/local/bin/restic
chmod +x /usr/local/bin/restic
restic versionTambién necesito jq para procesar JSON en los scripts:
apt-get install jqConfigurar almacenamiento remoto#
Usé un servidor SFTP remoto, pero restic soporta S3, B2, Google Cloud, etc.
Primero creo el repositorio:
export RESTIC_REPOSITORY="sftp:usuario@servidor.remoto:/ruta/backups/docker"
export RESTIC_PASSWORD="contraseña_super_segura"
restic initGuardo las credenciales en un archivo protegido:
cat > /root/.restic_env << 'EOF'
export RESTIC_REPOSITORY="sftp:usuario@servidor.remoto:/ruta/backups/docker"
export RESTIC_PASSWORD="contraseña_super_segura"
export RESTIC_CACHE_DIR="/var/cache/restic"
EOF
chmod 600 /root/.restic_envScript de backup#
Creo el script principal en /usr/local/bin/docker-backup.sh:
#!/bin/bash
source /root/.restic_env
# Exportar volúmenes de contenedores específicos
CONTAINERS=("contenedor1" "contenedor2" "contenedor3")
BACKUP_DIR="/tmp/docker-backup"
mkdir -p "$BACKUP_DIR"
for container in "${CONTAINERS[@]}"; do
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Exportando $container..."
docker export "$container" | gzip > "$BACKUP_DIR/$container.tar.gz"
done
# Backup de directorios de volúmenes
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Iniciando backup con restic..."
restic backup "$BACKUP_DIR" \
--tag "docker-backup" \
--tag "$(date +'%Y-%m-%d')" \
--verbose
if [ $? -eq 0 ]; then
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Backup exitoso"
rm -rf "$BACKUP_DIR"
else
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Error en backup" >&2
exit 1
fiLo hago ejecutable:
chmod +x /usr/local/bin/docker-backup.shScript de rotación#
Creo otro script para limpiar backups antiguos en /usr/local/bin/docker-backup-prune.sh:
#!/bin/bash
source /root/.restic_env
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Iniciando limpieza de backups antiguos..."
# Mantener últimos 30 backups diarios y 12 mensuales
restic forget \
--keep-daily 30 \
--keep-monthly 12 \
--keep-yearly 2 \
--tag "docker-backup" \
--prune \
--verbose
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Limpieza completada"chmod +x /usr/local/bin/docker-backup-prune.shConfigurar cron#
Edito la crontab del root:
crontab -eAgrego las siguientes líneas:
# Backup diario a las 2 AM
0 2 * * * /usr/local/bin/docker-backup.sh >> /var/log/docker-backup.log 2>&1
# Rotación de backups cada domingo a las 3 AM
0 3 * * 0 /usr/local/bin/docker-backup-prune.sh >> /var/log/docker-backup.log 2>&1Monitoreo#
Para saber qué está pasando, reviso los logs regularmente:
tail -f /var/log/docker-backup.logTambién puedo verificar el estado del repositorio:
source /root/.restic_env
restic snapshots
restic statsResultado#
Después de una semana funcionando, tengo:
- Backups incrementales diarios sin intervención manual
- 30 días de historiales disponibles
- Rotación automática de copias antiguas
- Datos replicados en servidor remoto seguro
Esto me quitó la preocupación. Los contenedores están protegidos.