Hacer backups en AWS S3 con node
Tener un servidor, tanto administrado como VPS tiene siempre la problemática de que si estas haciendo backups estos se quedarán almacenados en el mismo disco. Un fallo de este será totalmente devastador para el sistema… y para ti.
Hace tiempo que pensaba en utilizar S3 de AWS para hacerle llegar los backups de la base de datos, o de cualquier fichero que quieras que se copie.
Verás que es muy sencillo y con un simple script de node puedes hacer una utilidad que te dejará dormir por las noches.
Contenido
¿Qué necesitamos para empezar?
- Tener instalado node y npm en el servidor (guía instalar vnm)
- Cuenta de AWS
- IAM
- S3
Primer paso, configurar permisos de usuario en IAM
Para ello accederemos desde la consola al espacio de IAM y tendremos que crear/modificar un usuario con permisos AmazonS3FullAccess

Si consideras oportuno también puedes crear un grupo de usuario.
Ahora accede a Credenciales de Seguridad y genera una nuevo ID de clave de acceso. Guárdalo.

Crear el bucket en S3
Una vez tengamos el usuario nos iremos a AWS S3 y crearemos nuestro primer bucket, por defecto no tendrá visibilidad para internet. Esto tienes que tenerlo en cuenta.

Ahora solo tendrás que tener en cuenta el nombre que le has puesto y con todos estos datos ya tienes todo lo necesario en AWS para hacer el backup

Script de node para subir a S3
El código siguiente te pemirte comprimir un directorio llamado DIR_TO_S3 y generar un fichero zip llamado ZIP_FILENAME. Para enviarlo necesitarás las credenciales AWS_ACCESS_KEY_ID y AWS_SECRET_ACCESS_KEY, y por supuesto el nombre del AWS_BUCKET_NAME. Las librerías que se han utilizado las encuentras en npm (aws-sdk y compressing).
Después solo tienes que configurar un crontab para que cuando tu quieras se ejecute.
const fs = require("fs");
const AWS = require("aws-sdk");
const compressing = require("compressing");
const AWS_ACCESS_KEY_ID = "";
const AWS_SECRET_ACCESS_KEY = "";
const AWS_BUCKET_NAME = "XXXXX-amedinadevs";
const DIR_TO_S3 = "files";
const ZIP_FILENAME = "bk/files.zip";
const s3 = new AWS.S3({
accessKeyId: AWS_ACCESS_KEY_ID,
secretAccessKey: AWS_SECRET_ACCESS_KEY,
});
// COMPRIME EL FICHERO
compressing.zip
.compressDir(DIR_TO_S3, ZIP_FILENAME)
.then(() => {
console.log("compress... succesfull¡");
const fileContent = fs.readFileSync(ZIP_FILENAME);
const params = {
Bucket: AWS_BUCKET_NAME,
Key: `${ZIP_FILENAME}`,
Body: fileContent,
};
// UPLOAD to AWS S3
s3.upload(params, (err, data) => {
if (err) {
console.log(err);
}
console.log(`Subido S3 en ${data.Location}`)
});
})
.catch((error) => console.log(error));