Job scheduling has always been an important part of any application where we want to make certain tasks automatically like sending emails to the subscribed user or anything like that.
In this article, we will cover that how we can make a cron job that takes DB backup automatically at a given time interval.
First, we will need to create a node project, Create node app with the following command.
npm init -y
The above command will make package.json file and -y will give all question-answer which asked during making a project.
We will be using express.js and to run the cron job we will be using a package called node-cron
npm i express node-cron
The above command will install express and node-cron package.
Let's create a file called index.js and import the following things.
index.js
const { spawn } = require('child_process');
const path = require('path');
const cron = require('node-cron');
Spawn process will help us to run command in a terminal, It also does many things but we only need it to run our command.
Path will be used to join the given path which will be provided along with the directory name.
The following command will dump a mongo DB backup in the format we will provide.
mongodump --db=<your db name> --archive=./<path>.gzip --gzip
//example
mongodump --db=users --archive=./userDBBackup.gzip --gzip
The above command will have a couple of arguments, first will be the command name which is mongodump, the Second one is DB name, the Third one is the path of the archive where we want to store the DB backup and the last one will be the compression which we want to use.
Now we will create a function that will be responsible to make DB backup.
const DB_NAME = 'users';
const BACKUP_PATH= path.join(__dirname, 'public', `${DB_NAME}.gzip`);
const backUpDB = () => {
const child = spawn('mongodump',[
`--db=${DB_NAME}`,
`--archive=${BACKUP_PATH}`,
'--gzip'
]);
child.stdout.on('data',(data)=>{
console.log('stdoup',data)
})
child.stderr.on('data',(data)=>{
console.log('stdoup',Buffer.from(data).toString())
})
child.on('error',(err)=>{
console.log(err);
})
child.on('exit',(code,signal)=>{
if(code){
console.log('process exit with code', code)
}else if(signal){
console.log('process killed with signal',signal)
}else{
console.log("back up success");
}
})
}
Let's understand the above code.
So path.join method will join the two-path, __dirname will return the current directory of our location, and also we can provide directory name and file name in the argument.
Spawn will execute the command in a terminal, It takes the first argument as a command name and another argument will be an array of all parameters of a command. Here we just wrote the command of DB backup.
Now we will need to handle the output as well as the error which comes from the terminal or from the file itself.
So stdout will return the output if our command has been executed successfully, It will return a callback function and in the argument, it provides the data.
stderr will return the error if the command is not found or something wrong related to the command or terminal.
Now the third thing is the simple error that can occur in our file. We will also check the code and signal if the process is failed due to some issue.
Let's create a job that can run at a certain time interval and we will call our function there.
If you want to learn more about job scheduling then click here, This link is from one of my articles on a cron job.
So following code will run the job at a given time.
// Scheduling the database backup every night
cron.schedule('00 00 00 * * *', () => backUpDB ());
Here schedule method expects arguments which is the time when we want to run the DB backup code.
To learn more about the combination of different times click here.
So the final code will look like this.
const { spawn } = require('child_process');
const path = require('path');
const cron = require('node-cron');
const DB_NAME = 'users';
const BACKUP_PATH= path.join(__dirname, 'public', `${DB_NAME}.gzip`);
const backUpDB = () => {
const child = spawn('mongodump',[
`--db=${DB_NAME}`,
`--archive=${BACKUP_PATH}`,
'--gzip'
]);
child.stdout.on('data',(data)=>{
console.log('stdoup',data)
})
child.stderr.on('data',(data)=>{
console.log('stdoup',Buffer.from(data).toString())
})
child.on('error',(err)=>{
console.log(err);
})
child.on('exit',(code,signal)=>{
if(code){
console.log('process exit with code', code)
}else if(signal){
console.log('process killed with signal',signal)
}else{
console.log("back up success");
}
})
}
// Scheduling the database backup every night
cron.schedule('00 00 00 * * *', () => backUpDB ());
So this was a simple article on how you can backup the database.
Note - You can backup any database by their corresponding commands, You just need to pass some arguments in the spawn.
Tip - You also can upload backup on any cloud like AWS S3 or google drive, cloudinary, or anything like that. You can check my another article to know more about uploading files in the cloud.https://blog.yashvant.in/uploaddownloaddelete-any-file-on-aws-s3-bucket-using-nodejs
Thanks :)
Top comments (5)
Hello, interesting! A couple of questions:
A. How to run this? Who/what will run index.js? Would there also be a systemd service to launch it or something like that?
B. express.js is a web application framework. Isn't it a bad idea to run a web server on a database host, just for the sake of making backups?
C. For this task, I would normally:
What's the added benefit of using the combination of JS script, express.js and node-cron for this?
Hey,
A. you can run index.js with node index.js command or you can specify the command in package.json file.
B. I think it is not bad idea to use express.js, I have seen many web apps which does it using express js. It would automate things like uploading to s3 server and anywhere you want it to save. The idea behind this is to how this process works.
C. Yeah you can but you are doing it manually If I am not wrong, By this process it will get job done for us without doing it repetitively.
There are some use cases where we need our back-end to do job for us. It doesn't matter what back-end you are using or what package to schedule job you are using.
Thanks for the comment, Hope it clears you doubts. If you still have then we can discuss more about this.
A. OK, then who/what runs "node index.js"? Would there also be a systemd service to launch it or something like that?
B. I didn't mean express.js itself is bad. But I do think it is a questionable practice to run a web server on a database host. Unless it is a developer machine where you run all services on the same machine for convenience.
C. You can script cron job creation. The "crontab -e" lets you edit cron job definitions interactively. From a script, you can run "crontab /path/to/my/cronjob.definitions" and it will replace user's current scripts with whatever is in
cronjob.definitions
.I see the value of node-cron – it could run some business logic on schedule, for example. I'm not sure I'd use it for backing up databases though!
Hi
A. Index.js can be launched by manually if you just want to learn something to want to run in local or want to do any task only once, In ideal scenario it will be run by system when web server starts and it will be constantly listening.
B. Yes you are right but some applications may have web server and db host on single instance and i haven't covered any production ready or best practices to get things done in this article, but surely it is not to hard to search i guess.
C. I haven't tried crontab but the goal is to run it in certein time after setting it one time in code and avoid manual task by user.
Hope my answer make sense :)
hi, in addition you have node-mongotools package that I've created which let you dump/restore a db with dropbox and rotation feature.