Llevo tiempo queriendo mejorar mi estrategia de backups en el servidor doméstico. Tener todo en Docker está bien, pero necesitaba algo más robusto que simplemente copiar archivos. Restic + MinIO resultó ser la combinación perfecta: backups incrementales, deduplicación y un S3 local sin depender de servicios en la nube.
Por qué esta combinación#
Restic es incremental por defecto, solo almacena lo que cambió. MinIO corre en el mismo servidor y expone una API S3 compatible, lo que evita dependencias externas. PostgreSQL se respalda en volúmenes Docker que también necesitan protección. Todo automatizado con cron.
Instalación base#
Primero, restic:
sudo apt-get install resticMinIO ya está corriendo en Docker. Si no lo tienes:
docker run -d \
--name minio \
-p 9000:9000 \
-p 9001:9001 \
-e MINIO_ROOT_USER=minioadmin \
-e MINIO_ROOT_PASSWORD=tupassword \
-v /data/minio:/data \
minio/minio server /data --console-address ":9001"Luego creo un usuario y bucket específicos para backups en la consola de MinIO (puerto 9001).
Configurar restic con MinIO#
Inicializo el repositorio:
export AWS_ACCESS_KEY_ID=backup-user
export AWS_SECRET_ACCESS_KEY=tu-clave-secreta
export RESTIC_REPOSITORY=s3:http://localhost:9000/backups
export RESTIC_PASSWORD=tu-password-restic
restic initGuardo estas variables en un archivo seguro que solo el usuario root puede leer:
# /root/.restic-env
export AWS_ACCESS_KEY_ID=backup-user
export AWS_SECRET_ACCESS_KEY=tu-clave-secreta
export RESTIC_REPOSITORY=s3:http://localhost:9000/backups
export RESTIC_PASSWORD=tu-password-resticchmod 600 /root/.restic-envBackup de PostgreSQL#
PostgreSQL en Docker requiere un dump antes de respaldar. Creo un script:
#!/bin/bash
# /root/backup-postgres.sh
set -e
source /root/.restic-env
BACKUP_DIR="/tmp/postgres-backup"
mkdir -p $BACKUP_DIR
# Dump de la base de datos
docker exec postgres-container pg_dump -U postgres -d tu_database > \
$BACKUP_DIR/database-$(date +%s).sql
# Backup con restic
restic backup $BACKUP_DIR --tag postgres
# Limpio
rm -rf $BACKUP_DIRBackup de volúmenes Docker#
Para los volúmenes de datos:
#!/bin/bash
# /root/backup-volumes.sh
set -e
source /root/.restic-env
# Respalda volúmenes específicos montándolos
docker run --rm -v mi_volumen:/data \
-v /root:/root:ro \
-w /data \
alpine/restic:latest backup /data --tag docker-volumesMejor aún, respaldo directamente la ruta donde Docker almacena los volúmenes:
restic backup /var/lib/docker/volumes/mi_volumen/_data --tag docker-volumesAutomatización con cron#
Creo un script maestro que ejecuta ambos backups:
#!/bin/bash
# /root/backup-all.sh
source /root/.restic-env
/root/backup-postgres.sh 2>&1 | logger -t restic-pg
/root/backup-volumes.sh 2>&1 | logger -t restic-vol
# Purgar snapshots antiguos (mantener 7 días)
restic forget --keep-daily 7 --keep-monthly 3 --prunechmod +x /root/backup-all.shEn crontab:
# Cron - ejecuta a las 2 AM diariamente
0 2 * * * /root/backup-all.shVerificación y mantenimiento#
Para ver el estado de los backups:
restic snapshots
restic statsPara probar una restauración (sin tocar nada):
restic restore latest --target /tmp/test-restoreLo que aprendí#
La deduplicación de restic es potente; después del primer backup, los incrementales son mínimos. MinIO ocupa poco espacio si configurás bien su limpieza de versiones antiguas. El dump de PostgreSQL debe hacerse antes del backup, no hay forma de respaldar la base activa sin riesgo de corrupción.
Este setup me da tranquilidad. Si algo falla en el servidor, tengo backups automáticos, versionados y recuperables en cuestión de minutos.