Automatizar backups en un homelab: estrategias eficientes con Docker
La pérdida de datos en un entorno doméstico no es solo un inconveniente: puede significar horas de configuración reconfigurada desde cero. Afortunadamente, Docker facilita la automatización de backups de manera reproducible y aislada. Este artículo explora soluciones prácticas basadas en contenedores para respaldar bases de datos, archivos y configuraciones de servicios, con ejemplos concretos que funcionan en un homelab.
1. Backup de volúmenes Docker: el ABC del método
Los volúmenes de Docker son persistentes por defecto, pero no automáticos. Utilizando docker cp con un cron anfitrión o scripts personalizados, puedes crear backups de volúmenes específicos sin afectar a otros contenedores.
Ejemplo con SQLite:
# Backup de un volumen llamado "db_data"
docker run --rm -v db_data:/data -v $(pwd)/backups:/backup \
alpine tar zcvf /backups/db_$(date +%Y%m%d).tar.gz -C /data .
Este comando monta el volumen como fuente (/data), lo empaqueta con tar y lo guarda en ./backups del anfitrión. La fecha en el nombre evita sobrescrituras.
Automatización con cron (Linux):
0 3 * * * docker run --rm -v db_data:/data -v /home/user/backups:/backup alpine tar zcvf /backups/db_$(date +%Y%m%d).tar.gz -C /data .
Para Windows, usa el Task Scheduler con un script PowerShell que ejecute el mismo contenedor.
2. Contenedores para backups específicos: casos de uso
Algunos servicios requieren backups especializados. Docker permite encapsular estas acciones en contenedores dedicados.
Backup de MariaDB/MySQL:
Usa mariadb-backup en un contenedor temporal:
docker run --rm --network host -v mariadb_conf:/etc/mysql \
-v /backups/mysql:/backup mariadb:latest \
sh -c "mariabackup --backup --user=root --password=tu_pass \
--target-dir=/backup/mysql_$(date +%Y%m%d)"
Este backup es consistente (con almacenamiento transaccional) y evita problemas de corrupción.
Backup de Home Assistant: Home Assistant Community Store (HACS) tiene backups automáticos, pero un backup externo que incluya configuraciones y bases de datos es clave:
# docker-compose.yml (fragmento)
services:
backup_ha:
image: alpine
volumes:
- ha_config:/config
- /backups/ha:/backup
command: sh -c "tar zcvf /backup/ha_$(date +%Y%m%d).tar.gz -C /config ."
restart: unless-stopped
Ejecuta este servicio semanalmente con un cron externo.
3. Soluciones todo-en-uno: duplicati y restic
Para backups geográficos o cifrados, herramientas como Duplicati o Restic son ideales. Ambas funcionan perfectamente en Docker.
Duplicati (GUI + CLI):
# docker-compose.yml
services:
duplicati:
image: duplicati/duplicati:latest
ports:
- 8200:8200
volumes:
- duplicati_data:/data
- /mnt/backups:/backups
- /home/user:/source
environment:
- PUID=1000
- PGID=1000
restart: unless-stopped
Configura una tarea de backup en la interfaz web (puerto 8200) para fuentes locales, remotas (Backblaze, Wasabi) o un NAS.
Restic (cliente CLI):
docker run --rm -it \
-e RESTIC_PASSWORD=tu_clave_cifrado \
-e AWS_ACCESS_KEY_ID=tu_key \
-e AWS_SECRET_ACCESS_KEY=tu_secret \
-v /home/user:/backup \
restic/restic \
-r s3:https://s3.wasabisys.com/tu-bucket \
backup /backup
Para restauraciones:
docker run --rm -it \
restic/restic -r s3:https://s3.wasabisys.com/tu-bucket \
restore latest --path /backups/xml-restaurados --target /restaurados
4. Backup de Docker Compose: meta-backup
Los archivos docker-compose.yml definen tus servicios. Un backup que incluya toda la configuración (containers, networks, volúmenes) es esencial.
#!/bin/bash
compose_file="/home/user/docker-compose.yml"
backup_dir="/backups/docker_$(date +%Y%m%d)"
# Exportar estado actual
docker-compose -f $compose_file down || true # Para evitar conflictos
docker-compose -f $compose_file up -d
# Copiar archivo compose y redes/volúmenes
cp $compose_file $backup_dir/
docker inspect $(docker ps -aq) > $backup_dir/containers_info.json
tar zcvf $backup_dir/volumes.tar.gz -C /var/lib/docker/volumes/ .
Este script conserva el estado actual, incluyendo IDs de contenedores y configuraciones de red.
5. Buenas prácticas y verificación
- Rotación: Usa
logrotateo scripts para eliminar backups antiguos (ej: mantener solo los últimos 30 días). - Verificación: Restaurar al menos un backup cada trimestre. Ejemplo con Restic:
docker run --rm restic/restic -r /backups/test \ check --read-data-subset=1% - Seguridad: Nunca dejando credenciales en logs. Usa variables de entorno o Docker secrets.
- Almacenamiento externo: Combina locales (HDD) con remotos (Backblaze, AWS S3) para redundancia.
6. Ejemplo completo: flujo de backup en un homelab
- Servicio de backup diario (volúmenes de Nextcloud, MariaDB, Home Assistant):
# docker-compose-backup.yml services: backup_diario: image: alpine volumes: - nextcloud_data:/data/nextcloud - mariadb_data:/var/lib/mysql - ha_config:/backup/ha - /backups/local:/backup command: sh -c "tar zcvf /backup/diario_$(date +%Y%m%d).tar.gz /data/nextcloud /var/lib/mysql /backup/ha" restart: unless-stopped - Backup semanal a Backblaze (usando Duplicati):
- Configura la tarea en Duplicati para comprimir y cifrar en S3 compatible (Backblaze).
- Notificaciones: Integra con Gotify o ntfy para alertas de éxito/error:
status=$? curl -X POST "https://ntfy.sh/TuTopico" \ -H "Title: Backup Failed" \ -d "Salió mal el backup de $contenedor"