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.
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