Migrating a Drupal site between servers via Drush

As of Drush 4.5, migrating a Drupal site between servers became much easier. The new, little-known drush archive-dump and drush archive-restore commands make it an essentially three step process.


A basic Drupal site is made of two fundamental elements: the codebase and the database. When you migrate a Drupal site, you need to migrate both of these elements, often with a bit of re-configuration to boot.

The Old Way

Before using Drush to migrate a site, my standard procedure for site migration looked something like this:

Database Migration

  1. create a new, empty database
  2. create a new user
  3. associate the new user with the new database (with correct permissions)
  4. create a db dump from the source environment
  5. import the db dump to the target environment

Codebase Migration

  1. compress the codebase into a tar.gz file
  2. transfer files
  3. unarchive tarball
  4. edit the settings.php file to reflect the new database settings
  5. check file ownership, group membership, and permissions


The New Way (for me)

I'll run through the first iteration using psuedo [tokens] as placeholder for file and sitenames.

Open up the command line on the source machine (or SSH in) and cd to your Drupal installation.

  1. Create a Drush archive dump (code and db in one)
    drush archive-dump [site]
  2. Transfer the dump to your target machine (clearly, you could just FTP it)
    scp [new-backup-archive] [user]@[target-machine]:[target-folder]
  3. Now switch to the command line on your target machine, cd to the folder above your to-be-created Drupal installation and type:
    drush archive-restore [new-backup-archive] [site] --destination=./[new-folder-name] --db-url=mysql://[msql-user]:[mysql-password]@[target-server]/[db-name]

Drush will then create the new directory, unarchive your tarball into it, create a new database, populate it, and edit your settings.php file accordingly. Wow. Awesome.

Here's how the process looks for me when moving to my local MAMP stack (without tokens):

  1. drush archive-dump default
  2. scp /home/grasmash/drush-backups/archive-dump/20111256023713/grasmash.20116223_023613.tar.gz [email protected][my-ip]:/Applications/MAMP/htdocs
  3. drush archive-restore grasmash.20116223_023613.tar.gz default --destination=./grasmash --db-url=mysql://root:[email protected]/grasmash

Now it's important to note that you can use an existing directory or an existing database. If you'd like the contents of the existing directly overwritten, you can use the --overwrite flag. Likewise, you can grant Drush sudo MYSQL privileges to modify your dbs by adding a --db-su flag, followed by the correct credentials.

Furthermore, you don't need to use --destination or --db-url flags at all. If you leave these out, Drush will attempt to unarchive to the current working directory, and will attempt to use the database credentials defined in the settings.php file.

For more information on these commands, use drush's --help flag, e.g., drush archive-restore --help


Quick disclaimer:  There are many ways to migrate a Drupal site between servers. You should certainly be using SCM (like git), which can be used to move the codebase. You can use drush or backup_migrate to transfer the database. Or, you could simply move around Virtual Machines.

EDIT At present, it seems that the --db-url flag only works with Drupal 6. Please leave a comment and let me know if this is not the case!

It works with Drupal 7 and Drush 4.5 but the settings.php file does not get modified during the process as per the "drush help arr" :

Restore archive to a new database (and customize settings.php to point there).

(I don't know if it does with D6)

Thanks for the tip! Here's mine: both commands have aliases, ard and arr

For different sites in a multi-site setup to have their own modules, the code needs to reside under site/SITENAME/modules/ . This path is stored in the database in various tables (variables, menu_router, system).

How do people deal with SITENAME changing during transfer? For example, when transferring from dev.example.com to qa.example.com?

We automatically replace the strings directly in the DB-dump, and it almost works except where the altered string is inside output of PHP's serialize() function. In the above dev→qa example, the change must go from s:21:"sites/dev.example.com" to s:20:"sites/qa.example.com" — changing just the string is not enough in some cases, one also needs to change the string's length or else Drupal will be unable to unserialize() the value...

Automatically finding such cases in the MySQL dump is not easy at all, because mysqldump escapes special characters in the dumped strings... Does anyone have a ready solution?

Thanks for this. It's very interesting, and I will try it this WE.

The settings file gets copied from the source site with $db_url appended at the bottom.

Note, just for clarity due to unfortunate line breaks in the command line sample above, the db-url flag for drush is '--db-url=...' i.e. double dash, not a single dash.

Would this work also when moving one site under multisite to other server multisite setup. I mean does it copy also the default modules or only the selected site modules under /sites/site.com/modules ?

Add new comment

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.