Backups for your linux server

In this guide I describe how to setup backups for your Linux server. We will backup both locally and remotely for extra security. We will backup…

  • MySQL-databases using automysqlbackup.
  • Normal files using rdiff-backup.
  • Special large folders per weekday using rsync.
  • To a remote server using rsync.

Setting up the folder structure

We start out with creating a folder structure like this:

mkdir /backup
chmod 755 /backup
mkdir /backup/local
mkdir /backup/local/mysql
mkdir /backup/local/files

The new root-level folder “backup” is the storage location we will use for any kind of backups. The folder “local” inside it is where we will save the backup-files for that computer itself. Later on we will add sibling folders that contain backups from other computers.

Note that the folder “/backup” not necessarily need to be a folder on your main storage device. It could for example be a mount point or a symlink to a folder on another storage device. This makes a lot of sense if you main storage device is an SSD. Do not backup to an SSD.

Backup MySQL-databases

For MySQL-databases we will use the tool automysqlbackup. This tool is in the Ubuntu repositories. The versions are Ubuntu 12.04 with automysqlbackup 2.5 right now when I write this.

apt-get install automysqlbackup

We need to make two changes in the config file “/etc/default/automysqlbackup”:

DBNAMES=`mysql --defaults-file=/etc/mysql/debian.cnf --execute="SHOW DATABASES" | awk '{print $1}' | grep -Ev '^phpmyadmin|test|information_schema|performance_schema|mysql|Database$' | tr \\\r\\\n ,\ `
 
...
 
BACKUPDIR="/backup/local/mysql"

The grep part in DBNAMES is to exclude databases. You may want to add additional databases there that you don’t want to backup. You should now run it once to make sure it works:

automysqlbackup

Look through the contents in “/backup/local/mysql” to verify it looks the way you want it to.

Question: When will these backups run?
Answer: When installing automysqlbackup the file “/etc/cron.daily/automysqlbackup” was created. Check the content of “/etc/crontab” to see when daily cron runs. In my case it looks like this:

# m h dom mon dow user    command
17 *    * * *    root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *    root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7    root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *    root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

So it seems daily cron-tasks run at 06:25 on my system (Ubuntu 12.04).

Backup normal files

For backing up normal files we are going to use a tool called rdiff-backup that creates incremental backups.

apt-get install rdiff-backup

Question: How often should I backup?
Answer: I personally enjoy backing up once a day.

Question: How long should I save the backups?
Answer: I personally enjoy saving the backups for three months.

Question: What files should I backup?
Answer: A good start is “/home”, “/etc” and “/root”. You will however often need to setup some special exclude and include rules.

With this in mind I should create the file “/etc/cron.daily/backupfiles” with the following content:

#!/bin/bash
 
rdiff-backup \
--include /home \
--include /etc \
--include /root \
--exclude / \
/ /backup/local/files
 
rdiff-backup --force --remove-older-than 3M /backup/local/files

Ensure that file has the right permissions:

sudo chmod 755 /etc/cron.daily/backupfiles

Say however that I would like to ignore all home-files for the user “derp” and only want the folders “a” and “b” from the user “herp”.

The file would then look like this instead:

#!/bin/bash
 
rdiff-backup \
--include /home/herp/b \
--include /home/herp/a \
--exclude /home/herp \
--exclude /home/derp \
--include /home \
--include /etc \
--include /root \
--exclude / \
/ /backup/local/files
 
rdiff-backup --force --remove-older-than 3M /backup/local/files

It is important to consider that:

Multiple include and exclude options take precedence in the order they are given.
http://www.nongnu.org/rdiff-backup/examples.html#exclude

I prefer looking at the include/exclude order like this:

  • The deeper the directory paths – the higher up in that cron-file they should be written.
  • We can visualize the end result by imagining we apply the includes/excludes from bottom up.

Backup normal files using crontab

I actually prefer having more fine grained control over when backups are run. For this we will use crontab. Start out with creating a folder for your cron-scripts:

mkdir /root/cron

And then create the file “/root/cron/backupfiles.sh” instead of the file “/etc/cron.daily/backupfiles”. Next we add a crontab entry as root:

crontab -e

If we want it to run the same time as automysqlbackup (06:25) the crontab entry would look like this:

#m      h       dom     mon     dow     command
25      6       *       *       *       /root/cron/backupfiles.sh

Backup special large folders per weekday

To be more precise I run a few minecraft servers. The map files are huge and change often because they are compressed natively. If we took incremental backups (rdiff-backup) those increments would be very large due to the compression. I prefer creating this setup instead:

mkdir /backup/local/server
mkdir /backup/local/server/1
mkdir /backup/local/server/2
mkdir /backup/local/server/3
mkdir /backup/local/server/4
mkdir /backup/local/server/5
mkdir /backup/local/server/6
mkdir /backup/local/server/7

Monday is “1” and Sunday is “7”. Next we create the script “/root/cron/backupserver.sh”.

#!/bin/bash
rsync -avz --delete /home/mc/files/server/ /backup/local/server/$(date '+%u')

Note that after the first week the old backups will start getting overwritten.
Lets add it to the root crontab as well:

#m      h       dom     mon     dow     command
25      6       *       *       *       /root/cron/backupfiles.sh
35      6       *       *       *       /root/cron/backupserver.sh

Backup to a remote server

For extra security it makes sense to backup to a remote computer as well. Lets call the local computer “torkel” and the remote computer “berit”. Let’s also assume entries for those are added to the file “/etc/hosts” so they resolve into actual ip-addresses.

For this we could simply rsync the folder “torkel:/backup/local” to “berit:/backup/torkel” but in our case the folder “torkel:/backup/local/server” will be huge. We thus only synchronize “torkel:/backup/local/1” (the monday server backup).

Create a user for torkel@berit and create the backup folder:

ssh root@berit
adduser torkel
* give it a password for now *
mkdir /backup/torkel
chown torkel.torkel /backup/torkel

Create a private key for root@torkel and transfer it to torkel@berit:

ssh root@berit
ssh-keygen
ssh-copy-id torkel@berit

Remove the password from torkel@berit:

ssh root@berit
passwd -d torkel

Create the script “/root/cron/backupremote.sh”.

#!/bin/bash
rsync -avz --delete \
--include server/1 \
--exclude server/* \
/backup/local/ torkel@berit:/backup/torkel

Note that the include/exclude syntaxes are different for rsync and rdiff-backup.
Lets add it to the root crontab as well:

#m      h       dom     mon     dow     command
25      6       *       *       *       /root/cron/backupfiles.sh
35      6       *       *       *       /root/cron/backupserver.sh
 0      7       *       *       *       /root/cron/backupremote.sh

Restoring MySQL-databases

TODO

Restoring normal files

TODO

Restoring special large folders

TODO

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *