Everyone has their own preferred way of doing things but I have found this method to work well for me. If your working in a standard LAMP environment then you can create a cron job that creates 30 or 31 days (depends on days in the month) of backups until it starts overwriting itself. Useful if a client wants to roll back to a particular day that week/month, they also find it comforting to know they have 30 days of backup. Of course if the website has a lot of image or video files this will use up a lot of space in which case you can create a single overwriting daily backup by removing the date from the end of the backup filenames I have suggested below (_`/bin/date +\%d`).
To start editing the cron type in:
> crontab -e
By default it will open with vi or pico, if you have a preferred editor, mine is emacs, you can type:
> export EDITOR=”emacs”
> crontab -e
You will notice that the e and r keys are scarily close to each other on the keyboard and if you happen to type in ‘crontab -r’ it will delete your entire cron file without warning. So be careful and back it up. I did do this in one of my first jobs. It was not a good moment.
Its a good idea to put the following line at the top of your cron so it emails you if any of the scripts fail.
[In emacs ctrl x ctrl s to save the file without closing. ctrl x ctrl c to close]
File system backup
You will have to create two directories in your backups location. For this example it would be:
> mkdir live_backup
> mkdir live_backup_tars
# This will sync files from your live web directory to your backups directory at 5.20 everyday.
20 5 * * * rsync -auCz –delete /var/www/<live directory>/. /var/backups/live_backup/
# This will tar the backups directory and append the day of the month to the filename, it then gunzips the tar, all at 6.10 everyday
10 6 * * * tar -cPf “/var/backups/live_backup_tars/backup_`/bin/date +\%d`.tar” /var/backups/live_backup/; gzip -f /var/backups/live_backup_tars/backup_`/bin/date +\%d`.tar;
Now for obvious reasons you want your backups folder to be in a different location to your live files, my server comes with separate backup partition that is then backed up by the provider which makes the rsync straight forward. If you need to backup from one server to another you need to do something more like this:
20 5 * * * rsync -auCz –delete -e “ssh -i /root/rsync/debian-dev-rsync-key” syncer@<ip address of live>:/var/www/live/. /var/backups/live_backup
For this to work you will need to setup a pass phrase so the rsync can happen without you manually having to enter the password for the server it is backing up:
On Machine to backup
> ssh-keygen -t rsa // no pass phrase
> chmod 600 ~/.ssh
On backup machine
> cd ~/.ssh/
> touch debian-sync-key.pub
> emacs debian-sync-key.pub -> paste key
> cat debian-sync-key.pub >> authorized_keys
> chmod 700 authorized_keys
Backing Up the Database
Assuming that the database is hosted on separate server to where your backup cron is running you need to give your database access to your backup server.
> emacs /etc/mysql/my.cnf
> bind-address = <server ip=”thebackupip”></server>
Then you want to create a user that can only select data from the tables, you can lock this down more by substituting the % for the IP address of your backup server:
> mysql -uroot -ppassword
mysql > CREATE USER ‘test’@'%’ IDENTIFIED BY ‘****************’;
mysql > GRANT SELECT , REFERENCES , LOCK TABLES ON * . * TO ‘test’@'%’ IDENTIFIED BY ‘****************’
Finally the cron entry will look like this:
# create a mysql dump of the database at 5.10am daily
01 5 * * * /usr/bin/mysqldump -hremoteip -utest -p***** livedb > “/var/backups/live_backup_db/backup_`/bin/date +\%d`”
Where remoteip is the IP address of your live database server, test is your newly create db username and ***** is the password for DB and livedb is the database name. If you need to restore from a backup, ftp or scp the backup file to a location your live db server can access and then:
> mysql -uroot -ppassword
mysql > source /tmp/backup_01
BE CAREFUL with this as it will completely overwrite your current database with the backup file.
Hopefully this has been helpful. Any questions just let me know.