I have a couple of Ubuntu and Centos VPS’s and I needed a solution to backup to a remote location. I wanted this backup location to be something I could trust, but also inexpensive. My main concern was keeping this backup separated from my VPS provider (Not that they have not been more than adequate). There is a saying, and I believe it goes “Don’t put all of your eggs in one basket”. I believe I first heard that saying with investing. I try to live by that rule whenever feasible. So I really had two choices. Back it up to my home server (and eat up my bandwidth at times) or attempt to back it up to Google Drive. I went with the ladder.
Google Drive is an optimal choice because it is included with my Business Apps account. Even a free Gmail account will include 15 GBs of Drive space. The problem is, Drive has no official support for Linux. However there is an open source solution. There always is, that’s why you have a Linux server right?
So, how did I accomplish this?
Well I went about this using some pretty simple tasks.
- I have multiple servers with multiple sites and databases on each server. I use a simple bash script that runs every night in a cron job to keep a local copy of both my databases and my web content. These files are automatically removed after being more than 5 days old. They are also compressed into a tar.gz file. This cuts down on storage size as well as transfer time.
- Because I manage multiple servers and I don’t want all of them to have full access to my Google Drive data, I have a VPS dedicated to backups. This server has the open source version of Google Drive installed as well as some other scripts targeted at syncing backup directories. These data syncs happens via SSH and RSync. The other responsibility of this server is to trust the other servers. This way none of the servers I am backing up have access to any of the data but their own.
- Then the data is synced hourly with Google Drive. Now, that may seem strange to make this sync run hourly, but I will tell you way. Google Drive for Linux is not supported and a bit buggy. I have seen it fail a few times and it constantly says there is an error, even though it works fine. I have found that running the script again after a failure eventually fixes it, usually the first time around. Plus, if there is no new data to sync, then the script is done running in seconds. This error I am seeing could possibly be a configuration issue on my end, but I don’t really care all too much because it has not failed to backup one night.
- I have had this in place for over a month now, and each time I check my Google Drive is in sync with my backup server. It is a thing of beauty. So not only are my backups being stored in the cloud, now I have the option to sync those backups locally with my machine. I especially like this because what if I screw up and forget to pay my Google apps bill? At least I will have the latest backup stored on my laptop (along with everything else on Google Drive). Thankfully I am setup with autopay, and don’t think that will be an issue. Another great feature is that I can share backup directories. Now that these files are in my Google Drive I just right click and share that directory with the customer this data belongs to. In my case I just run a server for a very close friend of mine. However, we both always have access to local or cloud backups at any time.
Having backups of your data is extremely important. You never know what may happen to your server. This is peace of mind that you just can’t afford to live without. I feel confident that I could spin up another VPS and have my sites back up and running before DNS would propagate (My TTL is 1 hour). Google also automatically keeps files that are deleted for 25 days. This means that even if I delete a line of code and I don’t realize the bad effect this has on my site, I can still find and restore that line I removed up to a month back.
Okay, so lets get started:
First you need to have a file or directory of files to backup. So let’s create your local backup files. I will paste my backup script below and explain it line by line. At some point I borrowed this script, if I can find the original creator I will link to your site.
#!/bin/sh
THESITE1="website_name"
THEDB1="website_db_name"
THEDBUSER="put_your_db_username_here"
THEDBPW="**************"
THEDATE=`date +%d%m%y%H%M`
mysqldump -u $THEDBUSER -p${THEDBPW} $THEDB1 | gzip > /var/backups/files/dbbackup_${THEDB1}_${THEDATE}.bak.gz
tar czf /var/backups/files/sitebackup_${THESITE1}_${THEDATE}.tar -C / var/www/$THESITE1
gzip /var/backups/files/sitebackup_${THESITE1}_${THEDATE}.tar
find /var/backups/files/site* -mtime +5 -exec rm {} \;
find /var/backups/files/db* -mtime +5 -exec rm {} \;
Line 1 is commented out, so that’s nothing to worry about. Just defining that this is indeed a bash script.
Line 3 is just calling out the website name. This will be used in the script below to name the files. The same goes for line 4, but this is for the database.
Lines 6 and 7 are asking for the MySQL database username and password. Line 8 you can leave alone, it just defines the format of the date.
Line 10 is the script that actually dumps the database. Here you will want to make sure that the file location above exists and is where you want everything to end up.
Lines 12 and 13 are backing up and compressing the site data. You will also want to make sure the website location and backup location are correct.
Lastly Lines 15 and 16 keep the files no more than 5 days old. You can certainly alter that number to keep more or less depending on your needs.
This script can handle multiple databases and websites. You just need to make sure that you create multiple variables for each site, database, user and password. Then you will need to duplicate the code below those variables and replace them so each site has its own set of instructions.
Now you need to test this script. Save it as backup.sh and make sure to make it executable.
Run this script in SSH and test to see if everything was created properly. If you have any errors along the way feel free to post a comment below. I will try to answer as soon as I can.
If this script ran and you now see your site files where they are supposed to be, everything worked! A big tip: you should attempt to restore that file eventually. You never want to assume everything is fine. I try to pull down a backup at least once a month and test to make sure its not corrupt.
Now, we want to setup a cron job. I would recommend just putting this newly created file in your daily cron directory (etc/cron.daily/). I have seen where they sometimes don’t like the .sh extension. Just remove that and make sure its executable. Let this run for a few days, and keep up with it. Maybe even try to restore a database and a few files. Once you are sure it is working as you want you will be ready for the next step.
As for me, I need to get some rest, so I am going to write that bit in Sunday’s blog post.
Thanks for reading!