A geeky post: We have a small development server sitting in a corner of an office, now we need a backup solution for this server. Like many small home or office servers, it actually is a standard PC running Ubuntu Server 9.10, Apache web server and MySQL and PostgrSQL database servers. It has a 250 GB internal disk, about 8 GB of which are utilized. There is no built-in backup hardware.
In an ideal world we would now define and specify the risk of data loss, then come up with a strategy to mitigate these risks, and finally build a comprehensive solution for backup and disaster recovery, possibly including redundant hardware, off site backup, and other fancy things. This requires knowledge, time and money.
In reality we don’t have all that. Instead, we have an external USB drive. So we will set up the system to perform a nightly backup of important data to this external USB disk.
Prepare the backup drive
We connect the drive to the server via USB and power it up. By default, in Ubuntu Server disk drives do not auto-mount, so we don’t see it in the file system for now. We check the partition table:
sudo fdisk -l
This tells us it connects as as /dev/sdb1.
The drive comes NTFS formatted, and it actually is not a bad idea to leave it as NTFS – this way in case of an emergency we can plug it into a Windows PC and restore files there. To use NTFS on Ubunto we need to install an NTFS driver:
sudo apt-get install ntfsprogs
See www.linux-ntfs.org for details, we use this driver and toolset rather than the Ubuntu recommended ntfs-3g for no apparent reason.
We now can format the drive as NTFS:
sudo mkfs.ntfs /dev/sdb1
We create a mount point
sudo mkdir /media/backups
And allow access for root only
sudo chmod -R 700 /media/backups
A quick test to see if we can mount the drive and write to it:
sudo ntfsmount /dev/sdb1 /media/backups sudo touch /media/backups/test.file sudo ls -al /media/backups/* sudo rm /media/backups/test.file sudo umount /media/backups
The drive will generally stay unmounted and be mounted only for the duration of the backup operations, so we don’t need to create an fstab entry.
Install backup software
Our main concern are the PostgreSQL and MySQL databases running on the server: the database files cannot be backed up in operation, so we have to either stop the database servers during backup (not good!) or dump the databases and back up the dumps (better!).
After looking around a bit, it looks like Backupninja is a suitable tool to achieve this.
sudo apt-get install gawk rdiff-backup gzip hwinfo debconf-utils backupninja
Installation also creates a cron job for backupninja.
Configure backup options
Create config file from template:
sudo cp /usr/share/doc/backupninja/examples/backupninja.conf /etc/backupninja.conf
All settings in the config file are reasonable.
The actual backup procedure is a series of actions, defined by files in /etc/backup.d. Our first action in the backup process is to mount the backup disk. Therefore we create /etc/backup.d/10.sh, containing
ntfsmount /dev/sdb1 /media/backups
The second action is to backup the system. For this we use the backupninja template:
sudo cp /usr/share/doc/backupninja/examples/example.sys /etc/backup.d/20.sys
The third action is to backup the package list. For this we use the backupninja template:
sudo cp /usr/share/doc/backupninja/examples/example.sh /etc/backup.d/30.sh
The fourth action is to backup the MySQL databases. For this we use the backupninja template:
sudo cp /usr/share/doc/backupninja/examples/example.mysql /etc/backup.d/40.mysql
The fifth action is to backup the PostgreSQL databases. For this we use the backupninja template:
sudo cp /usr/share/doc/backupninja/examples/example.pgsql /etc/backup.d/50.pgsql
The sixth action is to backup the file system. For this we use the backupninja template:
sudo cp /usr/share/doc/backupninja/examples/example.rdiff /etc/backup.d/60.rdiff
The config and action files must not be readable by non-root users:
sudo sh chmod go-rwx /etc/backupninja.conf /etc/backup.d/*
The settings from the templates are very reasonable, only the rdiff action (/etc/backup.d/60.rdiff) requires a few edits to create a local instead of the default remote backup:
[dest]: type = local directory = /media/backups # host = backuphost # user = backupuser
Finally we need an action that unmounts the USB drive at the end of the backup procedure. We create /etc/backup.d/90.sh, containing
Now we test it:
sudo backupninja -t -n
If everything is okay we can now wait for the initial backup to happen tonight at 1am, or initialize it manually:
sudo backupninja -n
Let’s have a look at the log:
- We now have reasonable protection against data loss. However, other risks remain:
- Destruction of both the server and backup disk, e.g. by fire
- Theft of both server and backup disk
- Server hardware/software failure and the resulting downtime during restoration
- Technically our backup solution is way from perfect, e.g. it does not check if /etc/sdb1 is plugged in.
- At least I practiced my Linux skills
- Backupninja is a simple, yet powerful backup solution. In a case like mine a shell script might be more straightforward (mount disk, dump databases to disk, tar filesystem to disk, unmount disk), and easier to customize.
- I might change the backup process to run during daytime. This will allow the user to simply plug/unplug the backup disk and keep it offsite over night.