El problema#
Tenía PostgreSQL corriendo en Docker con volúmenes que contenían datos críticos. Los backups manuales no escalan y respaldar todo cada vez es ineficiente. Necesitaba algo automatizado, incremental y que verificara que los datos llegaran bien al NAS.
Por qué restic#
Restic maneja snapshots incrementales nativamente, comprime, cifra y permite verificar la integridad de los backups remotos sin descargar todo. Perfecto para un servidor doméstico donde el ancho de banda importa.
Prerequisitos#
- Docker con PostgreSQL corriendo
- NAS accesible por SSH o SMB
resticinstalado en el hostpg_dumpo acceso al contenedor PostgreSQL- Script de automatización (systemd timer o cron)
Paso 1: Preparar el volumen de datos#
Primero, identifico dónde está el volumen de PostgreSQL:
docker volume inspect postgres_dataEsto me muestra la ruta. En mi caso: /var/lib/docker/volumes/postgres_data/_data
Paso 2: Configurar acceso al NAS#
Monto el NAS en el host. Uso SSH con restic:
export RESTIC_REPOSITORY="sftp:usuario@192.168.1.100:/backups/postgres"
export RESTIC_PASSWORD="contraseña-fuerte"Guardo estas variables en un archivo seguro:
cat > /etc/restic/env.sh << 'EOF'
export RESTIC_REPOSITORY="sftp:usuario@192.168.1.100:/backups/postgres"
export RESTIC_PASSWORD="tu-password"
EOF
chmod 600 /etc/restic/env.shPaso 3: Crear script de backup#
El script hace tres cosas: dump de la BD, backup con restic y verificación:
#!/bin/bash
set -e
source /etc/restic/env.sh
POSTGRES_CONTAINER="postgres"
BACKUP_DIR="/tmp/pg_backups"
LOG_FILE="/var/log/restic-postgres.log"
# Crear directorio temporal
mkdir -p $BACKUP_DIR
# Dump de PostgreSQL
docker exec $POSTGRES_CONTAINER pg_dump -U postgres nombrebd | \
gzip > $BACKUP_DIR/db_$(date +%Y%m%d_%H%M%S).sql.gz
# Backup incremental con restic
echo "[$(date)] Iniciando backup..." >> $LOG_FILE
restic backup $BACKUP_DIR \
--tag postgres \
--tag incremental \
2>&1 >> $LOG_FILE
# Verificar integridad
echo "[$(date)] Verificando integridad..." >> $LOG_FILE
restic check --read-data 2>&1 >> $LOG_FILE
if [ $? -eq 0 ]; then
echo "[$(date)] Backup verificado correctamente" >> $LOG_FILE
rm -rf $BACKUP_DIR
else
echo "[$(date)] ERROR: Verificación fallida" >> $LOG_FILE
exit 1
fiLo guardo en /usr/local/bin/backup-postgres.sh y lo hago ejecutable:
chmod +x /usr/local/bin/backup-postgres.shPaso 4: Automatizar con systemd timer#
Creo un servicio y un timer para ejecutar diariamente:
cat > /etc/systemd/system/restic-postgres.service << 'EOF'
[Unit]
Description=Restic Backup PostgreSQL
After=docker.service
Wants=restic-postgres.timer
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup-postgres.sh
StandardOutput=journal
StandardError=journal
EOFcat > /etc/systemd/system/restic-postgres.timer << 'EOF'
[Unit]
Description=Restic PostgreSQL Timer
Requires=restic-postgres.service
[Timer]
OnCalendar=daily
OnCalendar=03:00
Persistent=true
[Install]
WantedBy=timers.target
EOFActivo los timers:
systemctl daemon-reload
systemctl enable --now restic-postgres.timerPaso 5: Monitorear y verificar#
Chequeo el estado:
systemctl status restic-postgres.timer
journalctl -u restic-postgres.service -n 50Para ver snapshots disponibles en el NAS:
restic snapshotsVerificación periódica#
Cada mes ejecuto una verificación completa de lectura:
restic check --read-data-subset=10%Conclusión#
Con esto tengo backups incrementales diarios, cifrados, verificados automáticamente y almacenados en el NAS. El overhead es mínimo porque restic solo sube lo que cambió. Si algo falla, systemd me avisa en el log y puedo investigar.
El punto crítico: restic verifica que los datos se escribieron bien sin descargar todo. Eso vale oro en un backup.