Synchronizing two instances of wordpress

by Olivier Thereaux

The TokyoArtBeat and NYArtBeat blogs use a fairly highly customized WordPress theme, with a number of php scripts and routines. For the longest time, this was one of the very few areas of the ArtBeat sites which were not fully duplicated on the staging and production servers.

Using subversion for the theme code itself did help us test changes to the theme scripts and style before pushing them to production, but the content itself was not duplicated: the development instance of the blog had some fairly antiquated content, while the production instance had all the latest article.

Synchronising the content from the production to the development server was not as easy as simply dumping and reimporting the whole SQL database. Be aware that if you import a whole WordPress database, you also import some field setup that will cause unwanted redirects.

Suppose you dump the wordpress database for http://www.myblog.example.com/ into a duplicate instance at http://dev.myblog.example.com/. Try accessing http://dev.myblog.example.com/ and wordpress will automatically redirect you to http://www.myblog.example.com/, which it thinks is the right URI for your blog. What to do? Go to the WordPress Dashboard and edit the settings? Not going to happen, since trying to access http://dev.myblog.example.com/wp-admin/ will also redirect you to http://www.myblog.example.com/.

The solution I found was to:

  1. Make sure you use separate databases for your production and development blog. This is much safer, anyway. Also, make sure your databases and files are properly backed up before attempting the following hack.

    Disable all plugins before the sync. Especially if you are using wp-cache, disable it. You’ve been warned.

  2. Dump the database from your production blog into the separate database for your development blog. With mysql, this will look like:

    mysqldump PROD_DATABASE_NAME -h PROD_DATABASE_HOST -u PROD_DATABASE_USER -p > wordpress_dump.sql

    then

    mysql DEV_DATABASE_NAME -h DEV_DATABASE_HOST -u DEV_DATABASE_USER -p < wordpress_dump.sql

    (You will be prompted for the database password both times. Make sure to replace the placeholders PROD_DATABASE_HOST with actual values for your setup.

  3. Edit the development database to tell wordpress the location of the dev blog. With MySQL again:

    echo 'update wp_options set option_value="http://staging.address.com/" where option_name="home";' | mysql DEV_DATABASE_NAME -h DEV_DATABASE_HOST -u DEV_DATABASE_USER -p

    and

    echo 'update wp_options set option_value="http://staging.address.com/wordpress" where option_name="siteurl";' | mysql DEV_DATABASE_NAME -h DEV_DATABASE_HOST -u DEV_DATABASE_USER -p

This worked for me, in two very distinct configurations last week. Any way this could have been done in a less hack-ish way? Tell me in the comments.