How to create automated backups for your web server?

If you have a web server running one or many websites or applications and hosting a database server it may be a good idea to have an automated backup process.

Most (or all) Web Hosting providers will charge you for such service, but the good news is that you can create your own automated backup process. Do not wait until you wake up a morning and discover that your homepage has changed into this :

You have boon hacked

The following tutorial has been written and tested with the following configuration:

  • Operating System : Ubuntu Linux 14.04.4 with root access
  • Web Server : Apache2
  • Database Server : Mysql 5.5.49
  • Scripting tool : Unix Shell

You can adapt the script or paths to meet your configuration’s needs. I will not cover any  external file transfer process, the files will be stored on the same server, but it’s not a big deal to automate the transfer of files to an other server.

Before we start, I will summarize the backup strategy .

  1. Create folder structures that will contain the backup files;
  2. The backup program consists of a shell script (.sh) that runs everyday at a fixed hour using a CRON task. The logic of that script will be the following :
    • Rename the existing (yesterday’s files) backup files by prefixing them with the the current date;
    • Delete backups older than X days (in our case it will be 5 days);
    • Take backupa of databases and compress the files;
    • Take backup of the Apache www folder and compress it.
  3. And finally, create the CRON task and set the appropriate permissions.

 

Folder Structure

We will create two folders:

  • /bkp : will be used to store the backup files ;
  • /opt/backup/ : will contain the backup script (backup.sh) .

To create the two folder execute the following commands :

mkdir /bkp
mkdir /opt/backup

 

Backup Script

We start by creating the script and give it the right permissions. On the command line execute the following commands:

# create the script file
touch /opt/backup/backup.sh

# make the file executable
chmod +x /opt/backup/backup.sh

Then we will start editing the script using VI editor (or your preferred text editor):

vi /opt/backup/backup.sh

Since it’s a shell script, it must start with the following line :

#!/bin/sh

The following sections will cover content that will be added to the backup.sh shell script.

Rename the old backup files

The next steps of the script will consist of creating new backup files. We don’t want our backup files to be replaced by the new ones. We will prefix the last created backup files with the current day’s date.

Add these lines to the script:

# rename existing backup files

## Switch to the backups folder
cd /bkp

## get the current date
current_date=$(date +"%Y-%m-%d")
shopt -s extglob

## Rename the files not starting with a date
for file in !([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*.gz); do
  mv "$file" "${current_date}_$file"
done

 

Delete backups older than X days

Your server space may be limited. We have to make a decision about the number of days we want to keep. For this tutorial we will choose 5 days.

# delete backups older than 5 days under /bkp folder
find /bkp -type f -name '*' -mtime +5 -exec rm {} \;

 

Take database backups

We will use the mysqldump command to create backups of the databases. Lets say we have 3 mysql databases : db1, db2 and db3. The backups will consist of what we call mysql dumps .

In addition, we will compress these mysql dumps (or backup files) in order to save space on the server.

Add the following lines to the script (replace database names, usernames and passwords with you own values):

# take compressed backups of databases
mysqldump -u root yourPassword db1| gzip -9 > /bkp/db1.sql.gz
mysqldump -u root yourPassword db2| gzip -9 > /bkp/db2.sql.gz
mysqldump -u root yourPassword db3| gzip -9 > /bkp/db3.sql.gz

 

Take folders backup

Now we will add the commands to backup our website’s files and folders. For Apache web server, website files or commonly stored in /var/www, but it’s not a rule, configuration my change. For this tutorial we suppose that our files are located in /var/www folder .

To take a backup, we will simply use the tar command to create a compressed archive for the whole www folder.

Add the following lines to the script (Replace the paths with you own values) :

# take compressed backup of important folders
tar -zcf /bkp/www.tar.gz /var/www/

Note: you can also use the same command to take a backup of any important folders located on your server.

Save the backup.sh file. Here is the final structure of the script :

#!/bin/sh

# rename existing backup files

# Switch to the backups folder
cd /bkp

# get the current date
current_date=$(date +"%Y-%m-%d")
shopt -s extglob

# Rename the files not starting with a date
for file in !([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]*.gz); do
  mv "$file" "${current_date}_$file"
done

# delete backups older than 5 days under /bkp folder
find /bkp -type f -name '*' -mtime +5 -exec rm {} \;

# take compressed backups of databases
mysqldump -u root yourPassword db1| gzip -9 > /bkp/db1.sql.gz
mysqldump -u root yourPassword db2| gzip -9 > /bkp/db2.sql.gz
mysqldump -u root yourPassword db3| gzip -9 > /bkp/db3.sql.gz

# take compressed backup of important folders
tar -zcf /bkp/www.tar.gz /var/www/

 

Create the CRON task

Now that our script is ready, you can test the process by executing it and make sure it has the behavior you wanted. When satisfied with the results, you can automate the process using the CRON tasks.

For this tutotrial, we want our script be executed every day at 00:01 AM. On a shell command line execute the following command to start editing the crontab :

sudo crontab -e

Then add the following line and save the file :

01 0 * * * /opt/backup/backup.sh

At this point everything must be OK, you have to wait until 00:01 AM to see the results.

Restoring the files

If you need to use the saved backup files simply do the following:

MySQL dumps

  1. Uncompress the files usinng gunzip command ( ex: gunzip db1.gz)
  2. This will produce an SQL file.
  3. Import the SQL file using any importing tool (phpmyadmin, MySQL Workbench, MySQL Administrator, etc)
  4. Sometimes you will experience some problems with file encoding, in most cases you have to remove or change some parameters.

tar archives

  1. Just uncompress the tar archive and copy the files in their appropriate location which is /var/ww for this tutorial. (Example : tar xzvf www.tar.gz)