Appearance
Backups automáticos en VPS y S3
Guía para configurar backups automáticos de la base de datos PostgreSQL en un VPS y su subida a AWS S3, sin involucrar al backend (cron + scripts en el servidor).
1. Requisitos en el VPS
En el servidor donde corre PostgreSQL (o desde el que tienes acceso a la BD):
| Herramienta | Uso |
|---|---|
| PostgreSQL client | pg_dump y psql (paquete postgresql-client en Ubuntu/Debian). |
| AWS CLI v2 | Para subir el backup a S3 (aws s3 cp). Instalación: AWS CLI v2. |
Crear directorio para backups locales (ej. retención 7 días):
bash
sudo mkdir -p /var/backups/despertares
sudo chown "$USER" /var/backups/despertares2. Variables de entorno
Definir en el entorno del cron (o en un .env que cargues antes del script):
Base de datos (PostgreSQL)
| Variable | Descripción | Ejemplo (prod) |
|---|---|---|
PGHOST | Host de la BD | localhost o IP del servidor de BD |
PGPORT | Puerto | 5432 |
PGDATABASE | Nombre de la base | despertares (prod) / despertares_staging |
PGUSER | Usuario con permiso de lectura | postgres o usuario dedicado |
PGPASSWORD | Contraseña (opcional si usas ~/.pgpass) | — |
S3
| Variable | Descripción | Ejemplo |
|---|---|---|
AWS_S3_BACKUP_BUCKET | Nombre del bucket donde se guardan los backups | despertares-backups |
AWS_S3_BACKUP_PREFIX | Prefijo (carpeta) dentro del bucket | backups/despertares o prod/db |
AWS_ACCESS_KEY_ID | Access key con permiso s3:PutObject en el bucket | — |
AWS_SECRET_ACCESS_KEY | Secret key | — |
AWS_REGION | Región del bucket (opcional) | us-east-1 |
Opcionales
| Variable | Descripción | Por defecto |
|---|---|---|
BACKUP_DIR | Directorio local donde se escribe el .sql | /var/backups/despertares |
BACKUP_RETENTION_DAYS_LOCAL | Días de retención de backups locales (borrar más antiguos) | 7 |
3. Script todo-en-uno: backup + subida a S3
En el repo está el script scripts/backup-db-and-upload-s3.sh, que:
- Ejecuta
pg_dumpy guarda el archivo enBACKUP_DIR(ej./var/backups/despertares/backup_YYYYMMDD_HHMMSS.sql). - Si
AWS_S3_BACKUP_BUCKETestá definido, sube ese archivo as3://BUCKET/PREFIX/backup_YYYYMMDD_HHMMSS.sqlcon AWS CLI. - Opcionalmente elimina backups locales con más de
BACKUP_RETENTION_DAYS_LOCALdías.
Dar permisos de ejecución y probar a mano:
bash
cd /ruta/al/repo/despertares-backend
chmod +x scripts/backup-db-and-upload-s3.sh
# Exportar variables (ajustar a tu entorno)
export PGDATABASE=despertares
export PGUSER=postgres
export PGPASSWORD=tu_password
export AWS_S3_BACKUP_BUCKET=despertares-backups
export AWS_S3_BACKUP_PREFIX=backups/despertares
export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=...
./scripts/backup-db-and-upload-s3.shComprueba que se crea el archivo en BACKUP_DIR y que aparece en S3:
bash
aws s3 ls s3://despertares-backups/backups/despertares/4. Cron en el VPS (backup automático diario)
Programar la ejecución diaria (por ejemplo a las 02:00).
Opción A: Variables en crontab
Editar crontab del usuario que ejecutará el backup:
bash
crontab -eAñadir (una línea; ajustar rutas y variables):
cron
0 2 * * * PGHOST=localhost PGDATABASE=despertares PGUSER=postgres PGPASSWORD=xxx AWS_S3_BACKUP_BUCKET=despertares-backups AWS_S3_BACKUP_PREFIX=backups/despertares AWS_ACCESS_KEY_ID=AKIA... AWS_SECRET_ACCESS_KEY=... /ruta/al/repo/despertares-backend/scripts/backup-db-and-upload-s3.sh >> /var/log/despertares-backup.log 2>&1Opción B: Script wrapper que carga .env
Crear /var/backups/despertares/run-backup.sh:
bash
#!/usr/bin/env bash
set -e
# Cargar secretos (no commitear este archivo)
source /var/backups/despertares/backup.env
cd /ruta/al/repo/despertares-backend
./scripts/backup-db-and-upload-s3.sh >> /var/log/despertares-backup.log 2>&1backup.env (permisos 600):
bash
export PGHOST=localhost
export PGDATABASE=despertares
export PGUSER=postgres
export PGPASSWORD=...
export AWS_S3_BACKUP_BUCKET=despertares-backups
export AWS_S3_BACKUP_PREFIX=backups/despertares
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...Crontab:
cron
0 2 * * * /var/backups/despertares/run-backup.sh5. Bucket S3 recomendado
- Nombre: por ejemplo
despertares-backups(o por entorno:despertares-backups-prod). - Permisos: bloqueo de acceso público; política que permita solo al usuario/rol de backup (y a cuentas de restore si aplica).
- Versionado (opcional): activar versionado para poder recuperar versiones anteriores.
- Ciclo de vida (opcional): regla para borrar objetos tras N días (ej. 30 o 90) o mover a otra clase de almacenamiento.
Estructura típica dentro del bucket:
s3://despertares-backups/
backups/despertares/
backup_20250226_020001.sql
backup_20250227_020002.sql
...6. Restaurar desde un backup en S3
Descargar el archivo desde S3:
bashaws s3 cp s3://despertares-backups/backups/despertares/backup_20250226_020001.sql /tmp/Restaurar con el script del repo (o
psql):bashPGDATABASE=despertares_restore ./scripts/restore-db.sh /tmp/backup_20250226_020001.sql
Ver también OPERACION_BACKUP_RESTORE.md para restauración y precauciones.
7. Resumen
| Paso | Dónde | Qué hacer |
|---|---|---|
| 1 | VPS | Instalar postgresql-client y AWS CLI v2; crear BACKUP_DIR. |
| 2 | VPS | Configurar variables (PG* y AWS_*); probar backup-db-and-upload-s3.sh a mano. |
| 3 | VPS | Programar cron (ej. 02:00) con las variables o con un wrapper que cargue .env. |
| 4 | AWS | Crear bucket privado; IAM user/rol con s3:PutObject; opcional: versionado y ciclo de vida. |
| 5 | Operación | Revisar logs (/var/log/despertares-backup.log) y listados en S3 de vez en cuando. |
El backend de la API no ejecuta estos backups ni accede a S3 para ellos; todo corre en el VPS vía cron y scripts.