I've come up with a nice script and group of settings that allow you to easily duplicate a live Drupal site. This is very useful if you've got a development site that perhaps you want to "reset" to the current version of the live site after you've finished development of a feature or (more likely) borked the installation completely. The general strategy is to dump a copy of your live db, empty the dev db, and import the data from your live db, and finally follow the same procedure for the associated files. First off, you'll need to have a database and db user with appropriate permissions already set up for your development site. You'll also obviously need to have your web server / DNS set up for your development site. Got it? Good! Now go download and enable the backup_migrate module on your live site. Configure it to automatically dump a copy of the database to your files directory every night (or whatever schedule you prefer). Be sure to exclude the data from all of the cache tables, and from the notifications_queue table (if you are using the notifications module)- otherwise users might get duplicate notifications from your dev site. You could probably use a script to mysql_dump the database and exclude these tables instead of using backup_migrate- whatever works for you. Now you need to modify your settings.php to automatically pick the appropriate db settings based on the current virtual host. This is very important - otherwise, when you copy your live site to your dev directory, you'll still be modifying the live db! Use the following code to dynamically pick the appropriate db settings: if ($_SERVER['HTTP_HOST'] == 'devsite.example.com') { $db_url = 'mysql://db_dev_user:db_dev_pass@localhost/db_dev_name'; } elseif ($_SERVER['HTTP_HOST'] == 'example.com') { $db_url = 'mysql://db_user:db_pass@localhost/db_name'; }
Finally, this is the script that does the magic: drops all of the dev tables, imports the latest copy of the live db, deletes the dev directory, and copies the live directory (obviously you'll need to replace the parameters at the top of the script): #!/usr/bin/env bash MUSER="db_username" MPASS="db_password" MDB="db_name" MFILE="path_to_mysql_backup.sql" MLIVE="path_to_live_site" MDEV="path_to_dev_site" # Detect paths MYSQL=$(which mysql) AWK=$(which awk) GREP=$(which grep) TABLES=$($MYSQL -u $MUSER -p$MPASS $MDB -e 'show tables' | $AWK '{ print $1}' | $GREP -v '^Tables' ) for t in $TABLES do echo "Deleting $t table from $MDB database..." $MYSQL -u $MUSER -p$MPASS $MDB -e "drop table $t" done $MYSQL -u $MUSER -p$MPASS $MDB < $MFILE rm -rf $MDEV cp -RL $MLIVE $MDEV
Edit: I've since discovered that using $_SERVER['HTTP_HOST'] to determine whether the current site is live or dev may not be the best solution- specifically, it will fail when running drush commands. A better solution is to use getcwd() to determine the current Drupal root and thus whether the site is live or dev. Edit 2: I've updated the script to use the "-RL" parameters with cp, which copies symlinked files rather than the symlinks themselves. This prevents you from unintentionally editing a file symlinked to by both the live and development sites.
"One click" duplication of a live Drupal site to a development site
Comments