Last updated 21 November 2010. Created on 19 April 2006.
Edited by jp2020, joachim, cel4145, dale42. Log in to edit this page.

The two Bash shell scripts presented here work together automating the Drupal backup and restore process. They work "as is" for simple installations and can be customized for multisite or non-standard installations.

The scripts have two uses:

  1. Creating Drupal backups which can be restored to their original location
    e.g., restore from a failed upgrade attempt or recover from a disk failure
  2. Staging data between Drupal configurations
    e.g., backup a production instance and restore to a test instance

These scripts have been used successfully on and between Linux systems and on Windows systems using Cygwin.

Functional Overview

A full Drupal backup requires data backups from both the database and file system. These two backups must then be tied to each other.

The backup script performs a file system backup using the tar command and a database backup using the mysqldump utility. The two backups are then combined into a single tar file. The tar is compressed and its file name includes the backup date.

The restore script reverses the process by unpacking the file and database backups from the container tar file and applying them to their respective targets.

The Drupal instance backed up or restored is specified by variables defined in the backup and restore scripts.

Usage notes and cautions

Detailed usage notes are provided for each script. The following points bear highlighting:

  • The restore script has no safeguards against accidental restore. If you don't understand how it can destroy your system you are encouraged NOT to use it.
  • The backup script backs up every file and directory in the Drupal root directory. If you have a hosted site with subdomain websites contained in subdirectories a backup of the main website directory will include the subdomain websites. For backups this will only bloat your backup file. For restores this could be disastrous, since you would be restoring the file systems for ALL of the website. If you have this kind of configuration you must customize the tar command to make a selective backup.
  • These scripts make no provision to lock out users while the backup or restore is in progress.
  • This script does not understand Drupal multisite configurations
  • The backup script requires read access to all files/directories and the restore script requires read/write access. This is sometimes a problem in hosted configurations.
  • Because the backup and restore is done in stages enough temporary space must be available for the intermediate files
  • Some commands used in the scripts will vary between operating systems. You may have to tailor commands for your operating system.

Looking for support? Visit the forums, or join #drupal-support in IRC.


Ningbo1’s picture

Despite the fact that the scripts are presented as .sh files, in reality, the first line of each script is #!/bin/bash, making them .bash scripts instead. Be careful, otherwise you'll waste a lot of time trying to figure out why they won't work on a Solaris or BSD system.

nicholasThompson’s picture

I wrote an alternative script on my Blog which "intelligently" dumps certain tables as structure only. Tables such as cache, session and watchdog do not really need a full backup and can sometimes bloat a dump file by up to 100%. You can find it on my blog, how to backup a drupal database.

starkos’s picture

A script, like @nicholasThompson's, that skips temporary and cache tables, and also works around a MySQL issue that will corrupt the anonymous user record:

Update: Added a drupal 7 version. Same approach, but with updated patterns to pull the connection information from the new settings.php format.

jmuessig’s picture

Thanks for your contribution, starkos!

I tested these scripts on my site, but found a few issues you may want to look at.

The script searches for tables to exclude. In the SKIP search term, you look for tables that contain 'cache'. The problem is, there are modules (such as imagecache) that have the 'cache' name in them, but are not actual cache tables. Excluding these tables will break imagecache and modules that depend on them (i.e. Ubercart). I changed my cache term to "^cache". This seems to exclude only 'real' cache tables.

Also, the accesslog table isn't being excluded in the script, though it obviously intends to. The accesslog table is 'accesslog', not 'access_log'. Changing this appropriately will drastically reduce the size your database.

Anyway, I hope that helps other who found that when using this script their imagecache images suddenly disappear.

My final SKIP line is as below; YMMV.

SKIP="^accesslog$\|^cache\|^sessions$\|^statistics$\|^watchdog$\|Tables_in" - Ridesteady boat speed control for wakeboarders

starkos’s picture

Thanks for the info! I'll make these changes over the break.

starkos’s picture

I've made the changes you suggested and posted the new scripts. Thanks again!’s picture

Nice tool and ideas.

David Brown

toddgee’s picture


I have written a comprehensive suite of fully documented bash scripts for the maintenance of a collection of Drupal sites. See esp. the README file for some best-practices guidelines. All these scripts are in heavy use by multiple developers who run many, many drupal sites. Please let me know if you find them useful.

jp2020’s picture

Great scripts, and well organized. Very nice company site as well.

I am new to bash scripts. You scripts would be very helpful to me; I just do not know where to place them or how to use them. My main interest lies in backing up a site - you make it a point in another thread that one should back up the database and the site's files together (M&B and demo - does not provide a solution for both), and as the site starts to get bigger, then problems seem to be a threat when using those solutions. You do mention in your script that it back ups the entire user account with the host and that one should be aware that the entire user account would be restored when one wishes to restore, unless we exclude certain directories - One could make a mistake, excluding directories on a daily basis. I see an interest in being able to back up aliases (I have seen the instructions, but have not been able to configure it, since I do not know what to do with the scripts, instead of backing up the entire user host account - can that be done? And can I utilize your method to back up a directory of the user account - if so, could you provide me some pointers?

I am trying to adopt a solid back and restore option that can be manually triggered and later on an automated one. I would be up to help you create some video tutorials/documentation for any material you are covering, if you needed help with something of that nature. I return, I just want to get a grip on backing up and restoring and how should I structure my directories with my host.

I have the possibility of having a separate hosting credential or root for every domain. I am currently using a different and more common set up - I have one user account with a one webroot and many different subdirectories that contain different drupal installations (/home/webroot/drupal1 ... etc). Any suggestions as to which approach you would recommend.