Schedule backups for websites hosted on uberspace

tl;dr Use a cron and a shell script to backup a website hosted on uberspace automatically.

One of the most important things to set up in a website project is a working backup strategy.

If the project is static, without any user input, then it is sufficient to write a deployment script, which installs all required packages and content resources.

This notepad for example has a deployment command to install Composer, fetch all dependencies and copy the »content« from a private Git repository. I dont need to backup the blog, because I may rebuild it completely from scratch with just one command and no data loss.

But if the project stores user input, like a comment section, it needs a backup. Some hosts create backups automatically and store them aside of the original webfolder. This is good enough for disaster recovery of the webfolder, for example if a broken script deleted content or created an irrecoverable error. This is not good enough however in case of a complete data loss, for example if your hoster lost all data due to a broken disk, a natural hazard or simply because the script error wasnt noticed for as long as the automatic backups were scheduled. Thats why all these backups should exist on different physical locations.

Uberspace automatically creates a backup of every project every night. As explained before, and as recommended by uberspace itself, users should download these backups.

While searching for existing solutions I found a bash script by @gehaxelt, which pulls these backup files and a database dump from uberspace and stores them in a folder with the current date. I modified the script to reduce traffic and the remove the redundant mysqldump command.

Uberspace stores a database dump next to the backup of the webfolder. So no need to start a dump process again, just use the already existing one.

Instead of pulling the backup file from uberspace my script executes an rsync command, which syncs only changes to the uberspace project with a local folder. This ist much faster and less traffic is used.

The script finally creates a full copy of the webfolder and the database in a folder with the current date.

#!/bin/bash

USERLOCAL='johndoe' # Local Username
USERNAME='acme' # Uberspace Username
HOST='uberspace.de' # Uberspace Hostname
DATE=`date +%Y-%m-%d` # Current date

### Check if backup folder exists and create it
if [ ! -d /home/$USERLOCAL/rsync/$USERNAME ]
    then
        mkdir -p /home/$USERLOCAL/rsync/$USERNAME
    echo "Backup-folder created"
fi

### Check if backup file exists and exit
if [ -f /home/$USERLOCAL/rsync/$USERNAME/backup-$DATE.tar.bz2 ]
    then
        echo "Backup already exists"
    exit 1
fi

### Sync data backup
rsync -aze ssh --delete $HOST:/backup/current/var/www/virtual/$USERNAME/html/ /home/$USERLOCAL/rsync/$USERNAME/web/
echo "Data sync complete"

### Sync database dump
rsync -aze ssh --delete $HOST:/mysqlbackup/latest/$USERNAME/ /home/$USERLOCAL/rsync/$USERNAME/database/
echo "Database sync complete"

### Create backup file
tar cjf /home/$USERLOCAL/rsync/$USERNAME/backup-$DATE.tar.bz2 /home/$USERLOCAL/rsync/$USERNAME/web/ /home/$USERLOCAL/rsync/$USERNAME/database/
echo "Created backup file (backup-$DATE.tar.bz2)"

echo "Done"

Save this script to ~/rsync/, eg. /home/johndoe/rsync/backup-acme.sh. To run it automatically you may set up a cronjob. Execute crontab -e and add the following line to install a cron command which the starts the backup script every sunday at 18:15 and ignores error messages.

### backup website (sunday)
15 18 * * 0 /home/johndoe/rsync/backup-acme.sh > /dev/null 2>&1

If the machine on which the backup script is executed is not always powered, then Anacron is a better solution. Anacron is almost the same as Cron, but does not expect the system to be running 24/7 like a server. Instead it will be started even if running late. So if your local machine is not running on sunday, because went out playing football, but turn it up on monday, Anacron will recognize that it is running late and start the command subsequently.

Setting up an Anacron is very easy, because it requires only a symlink. There are four different intervals available in Anacron. Hourly, daily, weekly and monthly. These intervals are part of the directory name, /etc/cron.<interval>. So a weekly Anacron has to be placed inside of /etc/cron.weekly.

cd /etc/cron.weekly
sudo ln -s /home/johndoe/rsync/backup-acme.sh backup-acme

The scriptname may only consist of alphabetical characters, numerals, underscore and dash (technically ^[a-zA-Z0-9_-]+$) no special chars like dots or umlauts are allowed.

The exact time when a Anacron is started, is written in the file /etc/crontab. The default for the weekly Anacron is friday 06:47.

⌛ Warning! This post is old. The information may be outdated.

No comments on this notepad. If you would like to add something, then dont hesitate to contact me via E-Mail or Twitter.