Automate your backups with Bash and Mega
I’ve been running a web server on my Raspberry Pi 2B for more than 3 years now and fortunately, no problem pertaining to data loss has occurred yet. One does never know when something like that could happen, though, therefore it is good to have some contingencies, in this case, having a backup plan.
When deciding what storage type and backup software to go for, I weighed several options. I wanted the backups to be as low budget as possible, preferably free. Another thing to consider was the safety of the data, nobody wants a bad actor accessing their web application’s files, server configuration files, and databases now, do they? I decided to go for Mega as it offers 15 GB of storage for free, this being paired with the saved data being encrypted, it was a clear choice. Alternatively, you could go for Oracle Cloud or AWS object storage (the first is free with up to 10 GB of archive data, the second one insanely cheap at the cost of some $0.004 per GB and month for S3 Glacier storage), but I'm certain there are more cheap object storage services for storing backups out there. I would recommend going for object storage if you back up bigger files or store these files for a longer period of time. As per my original objective, setting up backups to these object storage services wouldn't be as simple as my Mega solution (and I was going for the simplicity here).
Starting with Mega and its command-line utilities
It should be pretty obvious that you’d need to register for a Mega account in order for this to work. After the registration, there are several ways to up your storage limit, though for a limited time (as far as I know).
With your account set-up and ready to go, it is time to get Mega’s own CLI — megacmd. It is available for Linux, Windows, and macOS, but in this article, I’m going to be focusing on the Linux side of things, more precisely Debian-based distros.
You may install megacmd by cloning their GitHub repo and building it yourself, or you can get the binary package from Mega’s website by downloading it directly or with your command line utilities like wget or curl. In that case, it could be installed like this:
cd ~/Downloads sudo dpkg -i megacmd-*
The binary’s filename to install ultimately depends on your distribution and its version.
After the installation is complete, you may try to login to mega through your terminal with the following command:
mega-login email password
If you’ve successfully logged in, you’re good to go to the scripting part.
Creating the backup script
As you most likely want to backup more than one folder at a time, it is best to put this all into one bash script. You could also write this in Python, Rust, or any other scripting language, but for simplicity's sake, I built the script in Bash.
A quick overview of what the script actually does:
- Login to Mega
- Check if a backup exists for the current month (or week/day if you prefer more frequent backups)
- Backup directories where website files are saved
- Tar these directories into one archive
- Upload the files to Mega
- Upload previously created database dumps to Mega
- Remove temporary files and logout
A sample of the backup script:
There are lots of options for how to build on top of the base script shown above. You may add more directories to backup, you may do daily or weekly backups. Maybe you want the script to be more verbose, you remove discarding megacmd messages to /dev/null. There's quite a lot of possibilities.
Needless to say, this script does its best when you run it as a cron job, after all, it is supposed to be an automated backup script. I run it monthly, so my cron looks like this:
0 12 1 * * /home/pi/scripts/backup_to_mega.sh
In my case, it runs on the first day of every month at noon, simply enough. If you run it like this on default cron settings, you may get all the output of the script right into your email inbox every month though which can get pretty annoying pretty fast. For this use case, I would recommend decreasing the verbosity of the script by suppressing the echo commands or sending the cron job’s output to /dev/null altogether.
So that’s it, a simple, yet highly functional solution. If you’ve made it this far, thank you. And if you liked this article, make sure to drop a comment with some feedback, it is much appreciated.
This article was originally posted over as my very first post over at Medium.