Scriptless backup with cron

This post was published 9 years, 4 months ago. Due to the rapidly evolving world of technology, some concepts may no longer be applicable.

With the new release of WordPress, it is time to ensure that one has a good backup in place before upgrading. While many elaborate systems exist for creating backups, sometimes one just wants a quick and easy way to get the job done. As such, I present below, an easy procedure for a daily incremental file backup, with weekly full backups, and daily full database dumps, without writing any scripts.

(As a side note, before proceeding, taking a scripted approach to this has some advantages Рnotably:

  1. a sequential order of execution – the second task starts once the first task finishes
  2. avoiding some of cron’s peculiarities and
  3. better scalability for later on

however, that isn’t the objective here.)

Note: to include a date in the filename under cron, you can use the ‘date‘ command. You will need to enclose the entire command in backticks (`) and will need to escape (\) percent signs (%) as they represent new line characters in cron.

The database backup command is simple – it just requires executing mysqldump on the database. However, we would like to:

  1. save the output to a file and
  2. compress the file.

All of the above will be accomplished with the following:

mysqldump -h localhost -u USERNAME -pPASSWORD DATABASE_NAME | gzip > /path/to/mysite/backups/mysite_`date +%Y%m%d`.sql.gz

Essentially, we are performing a dump, piping the output through gzip, and outputting to a file. Note, if you are using shorthand options, as above, there is no space between -p and PASSWORD. If you prefer, the password can be provided as --password=PASSWORD.

For the file backup, we don’t want complete backups every day. The tar command supports incremental backups, and is quite easy to use. Data specific to the incremental backup is stored in a file, and can be referenced from multiple commands (so that we can create new files based on the same incremental backup). Once again, we want to compress the output to save some space. The command will resemble the following:

tar czfg /path/to/mysite/backups/mysite_inc_`date +%Y%m%d`.tgz /path/to/mysite/backups/mysite.info -C /path/to/mysite/ public_html

By excluding the dash(-) preceding the options, paths do not immediately need to follow the option – however, paths must be provided in the order the options are listed. The c option indicates file creation, the g option is for gzip compression. The ‘mysite.info‘ file is the one that will store the metadata for the incremental backups (the g option). The -C option is being used to change the directory and maintain relative paths.

In order to force a full backup, we simply add --level=0 to the above command.

Having the necessary commands, we can now put them together in cron:

If you don’t have a backups directory, create one, and set the correct permissions (user read/write should be sufficient)

Edit your cron (in this case, providing the username as well):

crontab -u USERNAME -e

Provide some global options for the cron, if you don’t already have them:

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin

(You might be able to eliminate these using full paths, etc, but they are a worthwhile convenience)

Pick a time of day – I like something obscure where other things are unlikely to be running and traffic is likely to be low, say 3:17 am each day for the file backup and 5 minutes later, 3:22 am for the database backup. Given that the file backup takes about 15 seconds to run on my setup, this is more than enough time to avoid over-taxing the server. The first (incremental) file backup will occur Mon-Sat (days 1-6) and the full backup will occur on Sun (day 0 or 7). The final crontab resembles the following (don’t forget to escape the percent signs!).

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
17 3 * * 1-6 tar czfg /path/to/mysite/backups/mysite_inc_`date +\%Y\%m\%d`.tgz /path/to/mysite/backups/mysite.info -C /path/to/mysite/ public_html
17 3 * * 0 tar czfg /path/to/mysite/backups/mysite_full_`date +\%Y\%m\%d`.tgz /path/to/mysite/backups/mysite.info --level=0 -C /path/to/mysite/ public_html
22 3 * * * mysqldump -h localhost -u USERNAME -pPASSWORD DATABASE_NAME | gzip > /path/to/mysite/backups/mysite_`date +\%Y\%m\%d`.sql.gz

On a small WordPress site (e.g. this site), it takes 10-15 seconds to complete a full backup of the files, and 1-2 seconds for an incremental file backup or database dump.

One thought on “Scriptless backup with cron

  1. Hi I stumbled upon your website by mistake when i was searching Yahoo for this concern, I must say your site is truly valuable I also like the layout, its superb!

Leave a Reply

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