Deploying a WordPress site to a staging or live server

Published 05 Dec 2014 in Development, Hosting, PHP & MySQL, WordPress by ZigPress

A WordPress developer’s workflow will at some point involve migrating a site that has been developed on a local computer to a live or staging server. The process for a particular project may look something like this:

  1. Install WordPress and develop site on local computer running MAMP or similar.
  2. When site is almost ready, deploy to a preview or staging server so the client can review it.
  3. When final tweaks are complete, deploy to the live server.

Within the above process there are two copying operations, where the WordPress code and database must be transferred from one server to another. And within the copying process there are two issues that must be handled in order for the site to work in its new home.

  1. Firstly, the site’s wp-config.php file must know how to load the site’s database on each server.
  2. Secondly, any references to internal URLs within the site’s database must be updated so that the site knows where it is. These URLs are often contained within serialized data (more on that later) which means they must be updated in a particular way.

In this article I will show you how to handle both these issues in the correct way so that after each deployment the site works as it should. I won’t go into detail about the actual copying process, since I assume that you know how to use FTP or maybe you have some kind of version control set up and know how to use it.

Editing wp.config.php to detect where it’s running

By placing some branching code in wp.config.php, we can ensure that it always connects to the right database no matter where it is running. We need to do this because in live hosting accounts the database host may be different to what it is on a local development machine.

Here is an extract from a typical wp-config.php file:

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'mydatabasename');
/** MySQL database username */
define('DB_USER', 'mydatabaseuser');
/** MySQL database password */
define('DB_PASSWORD', 'mypassword');
/** MySQL hostname */
define('DB_HOST', 'localhost');
/** Database Charset to use in creating database tables. */
define('DB_CHARSET', 'utf8');
/** The Database Collate type. Don't change this if in doubt. */
define('DB_COLLATE', '');

The first four ‘defines’ are the ones that may change depending on which server the site is running on. By using a switch statement we can account for these differences and avoid having to make changes every time we deploy. The updated code would look something like this:

// ** MySQL settings - You can get this info from your web host ** //
switch ($_SERVER['SERVER_NAME']) {
  case 'localhost' :
    define('DB_NAME', 'mydatabasename');
    define('DB_USER', 'mydatabaseuser');
    define('DB_PASSWORD', 'mypassword');
    define('DB_HOST', 'localhost');
  case '' :
    define('DB_NAME', 'stagingdatabasename');
    define('DB_USER', 'stagingdatabaseuser');
    define('DB_PASSWORD', 'stagingpassword');
    define('DB_HOST', '');
  case '' :
    define('DB_NAME', 'livedatabasename');
    define('DB_USER', 'livedatabaseuser');
    define('DB_PASSWORD', 'livepassword');
    define('DB_HOST', '');
/** Database Charset to use in creating database tables. */
define('DB_CHARSET', 'utf8');
/** The Database Collate type. Don't change this if in doubt. */
define('DB_COLLATE', '');

Bingo. You’ll probably never need to update this file again (unless of course you change your hosting company).

Updating the URLs in each database

Let’s assume that you’ve copied your WordPress site and database from your local development machine to the preview or staging server. The site files can be copied via FTP or via version control (e.g. Git), and the database can be copied via phpMyAdmin or a desktop MySQL manager such as Sequel Pro on a Mac or SQLyog on Windows.

At this point the site’s database will still be full of references to “localhost/” which were generated when you first installed WordPress. If these entries are left unchanged, the site on the staging server will not function.

However, if you simply run a database query to search for “localhost/” in all tables and replace it with ““, the site will almost certainly break in various ways. This is because of something called “serialization”. Here’s a nice article that sums up what serialization is all about, in a WordPress context:

Hopefully you can see that if you just replace the URLs in serialized data fields using a MySQL query, the numbers representing string length would be all wrong and the data could no longer be read.

In short, it’s a pain, and using JSON would be a much better solution. But hey, we work with what we’ve got, right?

Enter the Tool from Heaven

Of course, any task involving processing serialized data can be scripted, and that’s exactly what a developer working for a firm called interconnect/it did. They have released a tool called “Search Replace DB“, that does an ‘intelligent’ search and replace that correctly updates serialized URLs. It’s a PHP script and you can download it from this page:

After you have copied your site and database to the staging server, and before trying to load any pages or log in, copy the downloaded and extracted folder to the root folder of the site, so that it sits alongside the wp-content folder. You should name the folder something unguessable, e.g. Xj59gGYbk, so that no-one else can get to it and try to damage your database. Then browse to it at and you’ll see a screen like the one below.


So, you can enter localhost/ in the first box, in the second box, overwrite the database details with the right ones for your staging server, ensure the ‘All Tables’ box is clicked and then click ‘Live Run‘ (or maybe ‘Dry Run’ first so you can see what it will change).

That’s basically it. As soon as you’ve done the Live Run of the script, delete the script folder from your server and test the site. To test the site, first log in to WordPress Admin, go to the Settings Permalinks page and re-save the permalinks to update the site’s .htaccess file. Then browse more admin pages and browse the site’s front end pages as well, to ensure everything is OK.


If you follow the instructions in this article and something goes wrong, or your site is corrupted, or the world ends in spectacular fashion, I am not responsible. Always, always, always, take a backup of your site and database first, just in case you get confused and end up running the Search Replace DB script on your local copy instead of the newly-deployed staging version.

Not feeling confident about migrating your site or using the interconnect/it tool? Hire ZigPress to do it for you.


  1. On 07 Dec 2014 at 11:13, Hungama said:

    very nice and informative article.

  2. On 14 Dec 2014 at 14:06, adRuby said:

    Nice tool. I didn’t knew about it, so thanks. I’ll give it a try for my next project.

  3. On 13 Jan 2015 at 06:21, Ron Ford said:

    Thank God I found your blog! I am starting a new website and your input is very helpful. Thanks for sharing!

  4. On 17 Jan 2015 at 07:08, Tayyab said:

    Thank you for sharing this useful information. This post helps me alot. Wish you all the best.

  5. On 17 Jan 2015 at 18:39, Michael Wilson said:

    Great tutorial. Quite technical but very easy to follow (at least for me). Thanks.

  6. On 19 Jan 2015 at 11:01, Depresja said:

    Very good guide. Thank you for this!

  7. On 07 Feb 2015 at 12:19, Imogame said:

    Hi there.. I am running a gaming blog using wordpress as well. What is the best permission for wp-config file ?

  8. On 12 Jun 2015 at 12:30, Leon said:

    Thank you! Did not know about the serialisation thing… I recommend updating the article and add a .htpasswd protection to that folder;

  9. On 12 Aug 2015 at 21:10, Rene said:

    There is a new plugin called WP Staging which creates an entire staging site with just one click, even with authorization to the staging site only for admins. Its available on wordpress:

Add a Comment

If you have used this form and would like a copy of the information held about you on this website, or would like the information deleted, please email [email protected].