Backing up files and storing them in a remote location should be done on regular basis. Backups are vital. They ensure your code and assets are available if your server is hacked, destroyed and when your data is lost or corrupted.
In WordPress you could us a plugin like BackupBuddy to manage your backups. However, not everyone uses WordPress or wants to use a plugin to manage their backups.
You do not need to be a server guru to manage your own backups. All you need is one shell script on your Linux installation and one cron job to run it and an Amazon S3 bucket.
If you don't feel comfortable managing your own backups I would use a plugin, system admin or service. Backups are too important to shortcut.
In this tutorial
Use a basic Ubuntu server. I'm using root at my own risk but you should use your own su
.
- Install AWS CLI so we can upload your files to S3
- Create a shell script to automate backups
- Create a server cron job to backup your site every day
Installing AWS CLI
To install the AWS CLI make sure you have python
and pip
installed, Python 2 version 2.6.5+ or Python 3 version 3.3+.
Here are the simple steps:
- Install the AWS CLI via pip:
sudo pip install awscli
- Configure AWS with your credentials:
aws configure
AWS Access Key ID [None]: AKI3IOSF3DNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtn4MI/K7MDGENG/bPxRfiCY4EXAMPLEKEY
Default region name [None]: us-west-2
Default output format [None]: ENTER
To test if you can access your buckets run aws s3api list-buckets
. this will list your buckets in json format if you have permissions.
AWS CLI Path
Now, get the aws cli location.
Run,
which aws
Returns,
/usr/local/bin/aws
Use this is your script to access aws
.
Backing Up Files
To backup the website or app files on the server we will use tar
. Everything will be on S3 so we will only keep only the last 4 days on the server by running some basic cleanup. Take a Look at the shell script located at /root/bck_files_script.sh
:
#!/bin/bash
BCKTIME=$(date +"%y-%m-%d-%H%M%S")
BCKFILE="full_backup_$BCKTIME.tar.gz"
echo "backup to file: $BCKFILE"
echo "backing up files..."
cd /var/www/
tar czf "$BCKFILE" html --exclude='.git'
echo "moving backup..."
find /var/www/full_backup_* -type f -exec mv {} /root/bck/ \;
echo "moving to safe place..."
cd /root/bck/
echo "cleanup old backups..."
find /root/bck/full_backup_* -type f -mtime +3 -exec rm {} \;
echo "uploading new file to S3..."
/usr/local/bin/aws s3 cp "/root/bck/$BCKFILE" s3://your-bucket/
echo "finished!"
Remember make the script executable, chmod +x /root/bck_files_script.sh
.
Crontab
Crontab or cron jobs are really easy if you know what the 5 asterisks (*) are for.
minute hour day month day-of-week [command]
* * * * *
For the files backup we want the cron job to run at 11:30 everyday. You can access your users crontab with crontab -e
.
30 11 * * * /root/bck_files_script.sh >/dev/null
Allow cron access to AWS CLI
Now you need to inform cron of your AWS credentials. Locate your AWS config
file and edit the cron.
crontab -e
Add the env
to the top of your crontab.
AWS_CONFIG_FILE="/root/.aws/config"
30 11 * * * /root/bck_files_script.sh >/dev/null
Backing Up PostgreSQL
Backing up the database is also important. Since I'm using PostgreSQL ill use pg_dump. These backups will stay on the server a 2 days and then cleanup will remove them. Take a look at the shell script located at /root/bck_db_script.sh
:
#!/bin/bash
BCKTIME=$(date +"%y-%m-%d-%H%M%S")
BCKFILE="db_backup_$BCKTIME.sql"
GZFILE="db_backup_$BCKTIME.tar.gz"
echo "backup db to file: $BCKFILE"
pg_dump -U username database -f "/root/db_bck/$BCKFILE"
echo "compressing..."
cd /root/db_bck/
tar czf "$GZFILE" "$BCKFILE"
rm "/root/db_bck/$BCKFILE"
echo "cleanup old backups..."
find /root/db_bck/db_backup_* -type f -mtime +1 -exec rm {} \;
echo "uploading new file to S3..."
/usr/local/bin/aws s3 cp "/root/db_bck/$GZFILE" s3://your-bucket/
echo "finished!"
Again make the script executable, chmod +x /root/bck_db_script.sh
.
Edit the cron job one last time to run on the hour every hour backups. Again, crontab -e
.
AWS_CONFIG_FILE="/root/.aws/config"
30 11 * * * /root/bck_files_script.sh >/dev/null
0 * * * * /root/bck_db_script.sh >/dev/null
To check your final cron results list your crontab.
crontab -l
Backing Up MySQL
If you want to backup MySQL as well replace:
pg_dump -U [username] [database] -f "/root/db_bck/$BCKFILE"
With,
mysqldump -u [username] -p[root_password] [database] > "/root/db_bck/$BCKFILE"
Note that there is no space after -p in the MySQL command.
Backup Security
If your backups includes credit card numbers, email addresses or passwords you will want to encrypt your backup before sending it to a remote destination. However, local backups need no encryption if your server is secure.
Cleanup S3 Backups
Chances are you will not want to keep your backups forever. On the local server we have already set a removal date for the old backups. On S3 we need to do the same.
Within S3 locate your bucket properties and find the "Lifecycle" option. Then just create a rule and you can delete old backups any number of days after they were created.
Here I created a rule called "Delete Old Backups" that runs on the whole bucket and permanently deletes items created 3 days ago.