Estrategias Automatizadas de Copias de Seguridad para VPS
Aprende a configurar copias de seguridad automatizadas para tu VPS. Cubre rsync, restic, copias de seguridad basadas en snapshots y estrategias de almacenamiento externo para mantener tus datos seguros.
Estrategias Automatizadas de Copias de Seguridad para VPS
Las copias de seguridad son lo que desearías haber configurado ayer. Esta guía cubre todo, desde scripts rápidos hasta sistemas de backup automatizados a prueba de fallos.
Por Qué Esto Importa
Tu VPS va a fallar. El hardware muere, los centros de datos tienen interrupciones, ejecutarás un comando incorrecto, o el ransomware te encontrará. La pregunta no es si necesitarás copias de seguridad, sino cuándo.
Qué puede salir mal sin copias de seguridad:
- Un
rm -rf /accidental en el directorio equivocado - Corrupción de base de datos durante una actualización
- El proveedor tiene una interrupción y pierde tus datos
- El malware cifra todo
- Años de trabajo, perdidos en segundos
La Regla 3-2-1:
- 3 copias de tus datos
- 2 tipos de almacenamiento diferentes
- 1 ubicación externa
Requisitos Previos
- Un VPS (recomendamos Hostinger VPS, que incluye copias de seguridad automáticas en la mayoría de los planes)
- Almacenamiento externo (S3, Backblaze B2, otro servidor, etc.)
- Conocimientos básicos de scripting en shell
Paso 1: Identificar Qué Hacer Copia de Seguridad
No todo necesita respaldo. Concéntrate en:
Obligatorio respaldar:
- Bases de datos (PostgreSQL, MySQL, MongoDB)
- Archivos subidos por usuarios y multimedia
- Archivos de configuración
- Certificados SSL
- Archivos de entorno (.env)
Opcional (se puede recrear):
- Código de aplicación (si está en git)
- Imágenes Docker (si están en un registro)
- Paquetes del sistema (reinstalables)
No respaldar:
- Logs (generalmente)
- Directorios de caché
- Archivos temporales
- node_modules, vendor, etc.
Paso 2: Configurar Copias de Seguridad Locales
Crea una estructura de directorios de backup:
sudo mkdir -p /backups/{daily,weekly,monthly}
sudo chown $USER:$USER /backups
Script de backup básico:
#!/bin/bash
# /usr/local/bin/backup-local.sh
set -e
DATE=$(date +%Y-%m-%d_%H-%M)
BACKUP_DIR="/backups/daily"
RETENTION_DAYS=7
# Create backup directory
mkdir -p "$BACKUP_DIR/$DATE"
# Backup PostgreSQL
echo "Backing up PostgreSQL..."
docker exec postgres pg_dumpall -U postgres | gzip > "$BACKUP_DIR/$DATE/postgres.sql.gz"
# Backup MySQL
echo "Backing up MySQL..."
docker exec mysql mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" --all-databases | gzip > "$BACKUP_DIR/$DATE/mysql.sql.gz"
# Backup application data
echo "Backing up app data..."
tar -czf "$BACKUP_DIR/$DATE/app-data.tar.gz" /home/deploy/apps/*/data/ 2>/dev/null || true
# Backup configurations
echo "Backing up configs..."
tar -czf "$BACKUP_DIR/$DATE/configs.tar.gz" \
/etc/nginx/sites-available \
/etc/letsencrypt \
/home/deploy/apps/*/.env \
/home/deploy/apps/*/docker-compose.yml \
2>/dev/null || true
# Remove old backups
echo "Cleaning old backups..."
find "$BACKUP_DIR" -type d -mtime +$RETENTION_DAYS -exec rm -rf {} + 2>/dev/null || true
echo "Local backup completed: $BACKUP_DIR/$DATE"
Hazlo ejecutable:
chmod +x /usr/local/bin/backup-local.sh
Paso 3: Configurar Copias de Seguridad Remotas con Restic
Restic es una herramienta de backup moderna con cifrado y deduplicación.
Instalar Restic:
sudo apt install restic -y
Opción A: Backblaze B2 (La Más Económica)
Crea una cuenta y un bucket en B2, luego:
# Set environment variables
export B2_ACCOUNT_ID="your-account-id"
export B2_ACCOUNT_KEY="your-account-key"
export RESTIC_REPOSITORY="b2:your-bucket-name:backups"
export RESTIC_PASSWORD="your-encryption-password"
# Initialize repository (only once)
restic init
# Run backup
restic backup /home/deploy/apps /etc/nginx /etc/letsencrypt
# Check snapshots
restic snapshots
Opción B: AWS S3
export AWS_ACCESS_KEY_ID="your-key"
export AWS_SECRET_ACCESS_KEY="your-secret"
export RESTIC_REPOSITORY="s3:s3.amazonaws.com/your-bucket/backups"
export RESTIC_PASSWORD="your-encryption-password"
restic init
restic backup /home/deploy/apps
Opción C: Otro Servidor vía SFTP
export RESTIC_REPOSITORY="sftp:user@backup-server:/backups"
export RESTIC_PASSWORD="your-encryption-password"
restic init
restic backup /home/deploy/apps
Paso 4: Script de Backup Completo
#!/bin/bash
# /usr/local/bin/backup-full.sh
set -e
# Configuration
export RESTIC_REPOSITORY="b2:mybucket:vps-backups"
export RESTIC_PASSWORD_FILE="/root/.restic-password"
export B2_ACCOUNT_ID="your-id"
export B2_ACCOUNT_KEY="your-key"
BACKUP_DIR="/tmp/backup-$(date +%Y%m%d)"
LOG_FILE="/var/log/backup.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# Create temp directory
mkdir -p "$BACKUP_DIR"
log "Starting backup..."
# Dump databases
log "Dumping PostgreSQL..."
docker exec -t postgres pg_dumpall -U postgres > "$BACKUP_DIR/postgres.sql" 2>/dev/null || log "PostgreSQL dump failed or not running"
log "Dumping MySQL..."
docker exec -t mysql mysqldump -u root -p"${MYSQL_ROOT_PASSWORD}" --all-databases > "$BACKUP_DIR/mysql.sql" 2>/dev/null || log "MySQL dump failed or not running"
# Backup Redis
log "Backing up Redis..."
docker exec -t redis redis-cli BGSAVE 2>/dev/null || true
sleep 2
docker cp $(docker ps -qf name=redis):/data/dump.rdb "$BACKUP_DIR/redis.rdb" 2>/dev/null || log "Redis backup failed or not running"
# Backup files with restic
log "Running restic backup..."
restic backup \
--verbose \
--exclude='*.log' \
--exclude='node_modules' \
--exclude='.git' \
--exclude='__pycache__' \
--exclude='.cache' \
"$BACKUP_DIR" \
/home/deploy/apps \
/etc/nginx \
/etc/letsencrypt
# Cleanup old snapshots (keep 7 daily, 4 weekly, 6 monthly)
log "Pruning old backups..."
restic forget \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 6 \
--prune
# Cleanup temp directory
rm -rf "$BACKUP_DIR"
# Check repository health
log "Checking repository..."
restic check
log "Backup completed successfully!"
# Optional: Send notification
# curl -X POST "https://api.pushover.net/1/messages.json" \
# -d "token=xxx&user=xxx&message=Backup completed"
Crea el archivo de contraseña:
echo "your-secure-password" | sudo tee /root/.restic-password
sudo chmod 600 /root/.restic-password
Paso 5: Programar con Cron
# Edit crontab
sudo crontab -e
Agrega:
# Daily backup at 3 AM
0 3 * * * /usr/local/bin/backup-full.sh >> /var/log/backup.log 2>&1
# Weekly integrity check on Sundays at 4 AM
0 4 * * 0 restic check --read-data-subset=10% >> /var/log/backup-check.log 2>&1
Paso 6: Procedimientos de Restauración
Aprende a restaurar ANTES de necesitarlo.
Restaurar desde Restic
# List snapshots
restic snapshots
# Restore specific snapshot
restic restore latest --target /restore-point
# Restore specific files
restic restore latest --target /restore-point --include "/home/deploy/apps/myapp"
# Mount backups (browse like filesystem)
mkdir /mnt/restic
restic mount /mnt/restic
# Browse at /mnt/restic/snapshots/
Restaurar PostgreSQL
# Drop and recreate database
docker exec -it postgres psql -U postgres -c "DROP DATABASE myapp;"
docker exec -it postgres psql -U postgres -c "CREATE DATABASE myapp;"
# Restore
cat backup/postgres.sql | docker exec -i postgres psql -U postgres
Restaurar MySQL
cat backup/mysql.sql | docker exec -i mysql mysql -u root -p"$MYSQL_ROOT_PASSWORD"
Paso 7: Probar tus Copias de Seguridad
Las copias de seguridad no probadas no son copias de seguridad. Programa pruebas de restauración mensuales:
#!/bin/bash
# /usr/local/bin/test-restore.sh
TEST_DIR="/tmp/restore-test-$(date +%Y%m%d)"
mkdir -p "$TEST_DIR"
echo "Restoring latest snapshot to $TEST_DIR..."
restic restore latest --target "$TEST_DIR"
# Verify database dump is valid
echo "Verifying PostgreSQL dump..."
head -20 "$TEST_DIR/tmp/backup-*/postgres.sql"
# Check file integrity
echo "Checking restored files..."
find "$TEST_DIR" -type f | wc -l
# Cleanup
rm -rf "$TEST_DIR"
echo "Restore test completed. Review output above."
Paso 8: Monitoreo de Backups
Recibe notificaciones cuando fallen las copias de seguridad:
#!/bin/bash
# Add to end of backup script
HEALTHCHECK_URL="https://hc-ping.com/your-uuid"
# On success
curl -fsS --retry 3 "$HEALTHCHECK_URL"
# On failure (add to trap)
trap 'curl -fsS --retry 3 "$HEALTHCHECK_URL/fail"' ERR
Usa Healthchecks.io (nivel gratuito disponible) para monitorear:
- Recibe alertas si el backup no se ejecuta
- Rastrea la duración del backup a lo largo del tiempo
- Visualiza el historial de backups
Paso 9: Estrategias Específicas por Base de Datos
Archivado Continuo de PostgreSQL (WAL)
Para pérdida de datos cero:
# postgresql.conf
archive_mode = on
archive_command = 'restic backup --tag wal %p'
Logs Binarios de MySQL
# my.cnf
log-bin = /var/log/mysql/mysql-bin.log
expire_logs_days = 7
MongoDB
# Use mongodump for consistent backups
mongodump --archive --gzip | restic backup --stdin --stdin-filename mongo.archive.gz
Comparativa de Estrategias de Backup
| Estrategia | RPO | Costo | Complejidad |
|---|---|---|---|
| Volcados diarios | 24h | Bajo | Bajo |
| Volcados por hora | 1h | Medio | Bajo |
| Archivado WAL | Minutos | Medio | Medio |
| Replicación | Segundos | Alto | Alto |
RPO = Recovery Point Objective (máxima pérdida de datos aceptable)
Buenas Prácticas
- Cifra todo - Los backups contienen datos sensibles
- Prueba las restauraciones mensualmente - Un backup que no puedes restaurar no vale nada
- Múltiples destinos - No pongas todos los backups en un solo lugar
- Monitorea los trabajos de backup - Entérate de inmediato cuando fallen
- Documenta los procedimientos - Escribe runbooks para restauraciones
- Automatiza todo - Los backups manuales se olvidan
- Versiona tus scripts de backup - Mantenlos en git
- Credenciales de backup separadas - Limita el impacto si se ven comprometidas
Errores Comunes a Evitar
❌ Solo backups locales - El servidor muere, los backups mueren con él
❌ Nunca probar las restauraciones - Descubrirás la corrupción cuando más necesites los datos
❌ Sin cifrado - El almacenamiento de backups es hackeado, todos los datos quedan expuestos
❌ Respaldar bases de datos en ejecución - Volcados corruptos que no se pueden restaurar
❌ Sin política de retención - El almacenamiento se llena, los backups se detienen
❌ Las mismas credenciales en todas partes - El atacante también borra los backups
❌ Sin monitoreo - Los backups fallan silenciosamente durante semanas
❌ Guardar la contraseña del backup junto con los backups - Anula completamente el cifrado
Lista de Verificación para Recuperación de Emergencia
Cuando ocurre un desastre:
- No entres en pánico - Una recuperación apresurada causa más daño
- Evalúa el daño - ¿Qué exactamente se perdió?
- Levanta un nuevo servidor - Hostinger VPS puede tener un nuevo servidor listo en minutos. Sigue nuestra guía de seguridad VPS al configurarlo
- Restaura el último backup - Usa tu procedimiento documentado
- Restaura las bases de datos - Verifica la integridad de los datos
- Actualiza el DNS si es necesario - Apunta al nuevo servidor
- Documenta lo que ocurrió - El post-mortem previene repeticiones
Preguntas Frecuentes
¿Con qué frecuencia debo hacer backups?
Depende de cuánta información puedes permitirte perder. La mayoría de los sitios: diariamente. E-commerce/financiero: por hora. Sistemas críticos: replicación continua.
¿Dónde debo almacenar los backups?
En un proveedor diferente al de tu VPS. Si Hostinger aloja tu servidor, usa Backblaze B2 o AWS S3 para los backups. Nunca el mismo proveedor para producción y backups.
¿Cuánto tiempo debo conservar los backups?
7 diarios + 4 semanales + 12 mensuales es un buen punto de partida. Ajusta según los requisitos de cumplimiento normativo y los costos de almacenamiento.
¿Son suficientes los snapshots del proveedor?
No. Los snapshots son convenientes pero están en el mismo centro de datos. Úsalos para reversiones rápidas, no para recuperación ante desastres.
¿Cómo hago backup de volúmenes Docker?
Si estás ejecutando un stack de Docker Compose, detén el contenedor brevemente, o usa herramientas de backup de volúmenes:
docker run --rm -v myvolume:/data -v /backups:/backup alpine tar czf /backup/myvolume.tar.gz /data
¿Es Restic mejor que duplicity/borg?
Todos son buenas opciones. Restic tiene el mejor soporte para almacenamiento en la nube. Borg es el más rápido para local/SFTP. Elige uno y quédate con él.
Próximos pasos: Configura el monitoreo para detectar problemas antes de necesitar esos backups.
Ready to get started?
Get the best VPS hosting deal today. Hostinger offers 4GB RAM VPS starting at just $4.99/mo.
Get Hostinger VPS — $4.99/mo// up to 75% off + free domain included
// related topics
// related guides
$1 VPS Hosting 2026: Cheapest VPS Servers Starting at $1/Month
Looking for $1 VPS hosting? Compare the cheapest VPS providers starting from $1-3/month. Real specs, no hidden fees, honest reviews of budget VPS options.
tutorialCaddy Reverse Proxy Guide 2026: Automatic HTTPS Made Easy
Set up Caddy as a reverse proxy with automatic HTTPS, zero-config SSL, and simple Caddyfile syntax. Complete VPS deployment guide.
tutorialCloudflare Tunnel VPS Guide 2026: Expose Services Without Opening Ports
Set up Cloudflare Tunnel on your VPS to expose web apps securely without opening ports or revealing your server IP. Complete guide with Docker and DNS config.
tutorialCoolify VPS Setup Guide 2026: Self-Hosted Vercel Alternative
Deploy Coolify on your VPS for a self-hosted Vercel/Netlify experience. Complete setup guide with Docker, SSL, and app deployments.
Andrius Putna
I am Andrius Putna. Geek. Since early 2000 in love tinkering with web technologies. Now AI. Bridging business and technology to drive meaningful impact. Combining expertise in customer experience, technology, and business strategy to deliver valuable insights. Father, open-source contributor, investor, 2xIronman, MBA graduate.
// last updated: February 6, 2026. Disclosure: This article may contain affiliate links.