Tech Notes: Migrating WordPress Multisite Sites to Standalone Sites

Much as there are many benefits to using WordPress Multisite, sometimes you want to take a site hosted on a multisite and run it on a standalone WordPress install.  I’ve struggled to find detailed instructions on how to do this on the web, so here’s some notes from a migration that I’m doing.

Introductory Notes

I have used the following process to move sites several times now and I publish it for the benefit of the internet community, but I do so with no guarantee that it will work, and I can not take any liability for any loss or damages caused by following this process.  I recommend taking a full backup of your database and files before attempting migration – or any major change for that matter!  And I also recommend getting a professional to help you with this if you’re not sure what you are doing.

Also, I do not claim that this is the only or best method for doing this kind of migration and will happily take corrections or alternative ideas in the comments.

To export or not to export, that is the question

There’s no set way of doing this kind of migration and it will depend a lot on the nature of your site and its content.  Some people have advocated using WordPress’s export and import function.  This will work in some cases, but it really only exports and imports posts and pages.  It won’t recreate your entire blog with settings, plugins, widgets, etc.  To do that you need to be a bit cleverer.

This is quite a complicated process, but if you have lots of plugins, settings, and users, then it will save you a lot of time reconfiguring a new blog.

This article is not a primer on how to FTP or use MySQL, a certain level of technical knowledge is assumed.  What I hope to cover is the WordPress-specific aspects of this kind of migration.

A full migration

A full migration requires a fair bit of technical know-how. Here’s the overview of steps that I followed.

  1. Set up new hosting
  2. Install WordPress
  3. Install plugins and themes
  4. Copy files from blogs.dir
  5. Export/Import database
  6. Tweak database

The following sections explain those steps in more detail.

It should be noted that if you are using multisite domain mapping to make your blog appear at, say, http://yourdomain.com, and you want the new standalone site to also appear on http://yourdomain.com then you’ll need to do some clever stuff with hosts files to do this migration without any site downtime.

In all cases I’d recommend freezing the content on the website/blog for a day or so while you do the migration and make sure everything works.

Set up new hosting

This should be pretty normal. You will need to set up somewhere to host your standalone blog. This will require the usual things needed to run WordPress: currently PHP version 5.2.4 or greater and MySQL version 5 or greater.

If you’re using domain mapping and want your new site on the same domain as the old one then make your hosting is set up for the domain that you want to use.  Later on we’ll use a host file edit to get access to the new site without changing the DNS.

Install WordPress

At this point you only need to copy the WordPress files to your new hosting. It’s simplest if you do a full installation of a clean, empty WordPress blog/site.  If your host lets you do an automatic install then do that.  This sets up all the files and ensures that WordPress can talk to the database.  We will delete the database tables that it creates later on.

If you’re using domain mapping then bear in mind that you’re still seeing the old site on the site’s URL at this point.

Install plugins and themes

You will need to copy across any plugins and themes from the old multisite to the new.  You don’t need to copy ALL plugins and themes from the multisite, only those that are used by the site that you are migrating.

I do this using FTP to copy the exact files from the original site to a temporary local directory, and then FTP them to up to the new hosting.  This avoids the need to log in to the new site (which you don’t quite want to do yet) and makes sure you have the exact same versions of everything so that you’re compatible with the database entries that you will copy across.

Copy files from blogs.dir

You’ll then need to copy across the non-database content from the old site to the new: image files and other uploads, as well as any plugin-created directories.

In the default multisite these are stored in /wp-content/blogs.dir/X/files, where “X” is the site ID of the blog you’re migrating.  There are two ways to do this:

  1. Go to the Network Admin screen for your WordPress Network, go to the Sites section and edit the site you’re migrating.  The URL for the Edit Site screen will be something like: http://your-network.com/wp-admin/network/site-info.php?id=X – the X on the end is the ID of the site.
  2. In the WordPress MySQL database for the Network there is a table called wp_blogs and there is a column in this table called blog_id – you can use this to work out the ID of the site you are migrating.

Remember the site ID – you will need it later.

For now you will need to locate the files in /wp-content/blogs.dir/X/files and use FTP to copy them to the new host (usually via a temporary local space).

As an optional activity you can upload these files to /wp-content/uploads, where they would normally be for a WordPress site.  This makes the new install a bit tidier but involves some additional work that I will explain later.

Export/Import database

The next step is to export/import the database.  As I said earlier, you could just do a WordPress export and import, but this will only transfer your posts, pages and menus, it will not migrate settings or widgets.  A proper database export/import will preserve all your blog/site’s settings as well.

First of all, if you’ve already logged in and set up WordPress on the new host, or if you did an automatic install, you will already have database tables.  You will need to go to the database (usually using a tool like phpMyAdmin) and delete/drop all the tables.  MAKE SURE YOU DO THIS ON THE NEW HOST, NOT THE OLD!

Next, go to the old database in phpMyAdmin (or your admin tool of choice), and select the database for your network (you may not have to select a database).

You should see a list of tables.  Some of these tables will be prefixed with wp_ (e.g. wp_users) and some will be prefixed with wp_X_, where X is a site ID (e.g. wp_2_posts).

You will need to export all of the tables prefixed with your site ID. I also recommend exporting wp_users and wp_usermeta – more on this later.

Once you exported the SQL, you will need to import this into the new (and now empty) database.

Tweak Database

We’re nearly there.  You just need to tweak the database to make sure it’s right for the new site.

UPDATE: I recently came across the WordPress Move plugin which does an excellent job of making the database change for you.

  1. siteurl and home options.  Your old site will probably have been on a url like http://your-network.com/sitename or http://sitename.your-network.com – even if using domain mapping, a URL like this will have been used to set the site up.  You will need to tell WordPress that it’s on its shiny new URL.  To do this, go to the wp_options table and locate the ‘siteurl’ and ‘home’ options to be new URL of the site.
  2. Get access to new site. You will now need to gain access to the new site on its new URL.  While you’re sorting things out you won’t want to change DNS so EVERYONE can see it, so you’ll need to edit your local hosts file to make sure you’re using the new IP address – don’t forget to change this back at the end and be careful…some browsers cache IP addresses, so it can be hard to tell if you’re looking at the new site or the old!  One way to tell is to check if you have access to the other sites in the old network or not.
  3. Update database. You may be using a newer version of WordPress on the new host, if this is the case you will have to perform a Database Update – this should happen as soon as you visit the /wp-admin URL of your new site.  So the next step is simple to log in to the new site as an admin and, if prompted, perform the database upgrade.
  4. Remove users. Remember you exported the wp_users and wp_usermeta tables? Well, these will contain details of ALL users from the network, and so you will need to remove all the users that don’t need access to the migrated site.  For a large network with lots of users this could be a tedious job (a MySQL guru could write some queries to do it), but for smaller networks this is actually easier to perform from the Users section of the WordPress dashboard. Just delete the users that you don’t want to have access!
  5. Content URL updates.  This is the trickiest bit and, to be honest, it’s hard to guarantee results.  Some of your content and settings may have links to URL’s on the old site; that is, those that have the network URL in them: http://sitename.your-network.comI can’t think of a sure-fire way to catch ALL instances but here’s some tips:
    • Don’t update “serialised” content. Serialised content is a “flattened” version of a complex data structure.  This is most likely to exist in the wp_options table and looks likea:1:{s:12:”_multiwidget”;i:1;}Because this content is a representation of a more complex structure, any values in this format that contain the old site URL must be carefully updated. If you’re not sure then try to find the setting in the WordPress dashboard and update it there.You could use a SQL query to find instances of the old URL in wp_options, like:select * from wp_options where option_value like '%oldURL%'
    • Use the MySQL “replace” function to replace links in post/page content.  If you previously created internal links in your site’s content then these may still point to the old site URL. You may also find that links to media that you have inserted are of a slightly different format and will need correcting.  I use the following queries to update links in the post content:

      update wp_posts set post_content = replace( post_content, 'http://old-url.com/files/', 'http://new-url.com/wp-content/blogs.dir/X/files/' )

      update wp_posts set post_content = replace( post_content, 'http://old-url.com', 'http://new-url.com')
      Of course, make sure the URL’s are your own and that the X is replaced by the site ID from earlier.It’s worth noting that with these content changes the old site still exists on the old URL and so you will not see problems until the old site is deactivated.
    • Update GUID’s. Each post has a unique URL of its own.  These will all have to be updated also.  I use similar queries to the ones above for content.update wp_posts set guid = replace( guid, 'http://old-url.com/files/', 'http://new-url.com/wp-content/blogs.dir/X/files/' )update wp_posts set guid = replace( guid, 'http://old-url.com', 'http://new-url.com')
    • Global search: phpMyAdmin has a global database search that will allow you to search for the old URL throughout the whole database.  Use this to clear up any remining instances.

Tidy Up

Update permalinks: your permalink settings may not have been reflected in the .htaccess file of the new site so, for good measure, go to Settings->Permalinks, and click “Save”.

Revert your hosts file: once you are happy, remove the entry in your local hosts file.

Go live: then you can update DNS and wait for the change to propagate, at which point your new site will be “live”!

Tags: , , , ,

5 Responses to “Tech Notes: Migrating WordPress Multisite Sites to Standalone Sites”

  1. Nate January 5, 2012 at 2:09 am #

    Awesome writeup!!! Thanks so much! Just in time for my multi-site to single-site migration :0)

    • oikos_uk January 19, 2012 at 10:54 am #

      Thanks! It’s a bit of a long-winded process, but hope your migration worked OK.

  2. Nate January 5, 2012 at 3:32 am #

    It works just fine. It’s a bit of tedious work. The one thing you forgot to mention is that on wp-config.php we must update our table prefix from wp_ to wp_SITEID_ (such as wp_3_). Then it works perfectly!

    Thank you once again.

    Nate Parson
    Founder of Center For Confidence
    http://www.centerforconfidence.com

    • oikos_uk January 19, 2012 at 10:53 am #

      Thanks for the comment Nate – glad you spotted something I missed. I’m sure there’s more too!

  3. Andrew Peacock February 15, 2012 at 8:56 am #

    Thanks for sharing. I’m about to run through this process, so I’m very grateful for having the benefits of your experience right in front of me!

Leave a Reply