How to Move a WordPress Site
(0834) The widget issue is specific to the widget overrides in my RocketTheme theme. Otherwise, things are running smoothly. If you’re having difficulties, please get in touch me via the contact form and be specific about the issue you’re experiencing. As always, I’ll do my best to work with you.
I’ve had the good fortune of needing to move a WordPress installation so often that I’m discovering it to be nearly second nature. It’s not a difficult process, but it’s not intuitive either. Still, things will crop up during the process of moving WordPress from one hosting provider to another, or migrating a WordPress installation from my development environment to a production server. This tutorial will attempt to hit the high points.
Background
The first time I tried to migrate a WordPress site by brute force I made a royal hash of it. I’ve learned over the course of a number of WordPress moves that there’s a knack to doing it quickly and effectively. At this point I can transfer WordPress from one server to another, change the domain WordPress was installed under, fix the inevitable broken images in the posts, and have the site fully functional within a few hours – most of which is time spent copying files.
Before undertaking this endeavor, you should make sure that your new hosting arrangements are in place. Create an empty database at that location if necessary, and ensure that you have FTP access to the site’s final destination. For the sake of this tutorial I’m going to assume that you understand what this means and how to go about achieving it – if not, you should start by investigating your new hosting provider’s documentation in order to get up to speed.
If you are going to use Yahoo Small Business Web Hosting
Check out the post I wrote about Moving WordPress and Yahoo Small Business Hosting. I’ve had to do a few migrations of WordPress sites to or within Yahoo Small Business Web Hosting, and their administrative controls are so restrictive that it can turn into a total nightmare. Forewarned is forearmed.
WordPress Installation Migration Tutorial
Step 1: Make a Local Copy of the Existing WordPress Site Files
The first thing I do is connect to the FTP server which provides access to the files for the existing WordPress installation. In the case of a site I’ve developed locally and need to deploy I obviously have all the files already. Getting an entire site is time consuming and, with any decent FTP client, it’s automated, so I make this step one. Just connect via FTP and sync a directory on your local disk to the document root which contains your live WordPress install. Now, with files a-transferrin’, we can move on to other steps.
Step 2: Get a Dump of Your Current WordPress Database
The easiest tool to use here is going to be phpMyAdmin. Any hosting provider worth their salt is going to offer this to their users. Follow these steps to get your existing database exported:
- Connect to the instance of phpMyAdmin which provides access to the database for your current site. Enter your credentials to log in to the management interface.
- Select the database for your existing WordPress installation from the list on the left.

(Fig. 1) Select your WordPress database from phpMyAdmin's list of databases
- Click ‘Export’ at the top of the window.

(Fig. 2) Click the 'Export' tab at the top.
- Ensure that the radio button for the ‘Quick’ export method is selected. Click the ‘Go’ button to download a .sql file containing a dump of your current database table structure along with all of your existing data.

(Fig. 3) Check the 'Quick' export method radio button and click 'Go' to download your database dump.
Step 3: Import Your Database
Now you have to reverse the export process to populate your new database.
- Log in to the phpMyAdmin interface for the new database.
- Select the new database from the list on the left (see Fig. 1, above).
- This time, click the ‘Import’ tab at the top of the window.
- Now you’ll have to select the file you just downloaded containing your database dump so that you can upload it here. Click the ‘Choose File’ button and locate the .sql file downloaded during Step 2, above.

(Fig. 4) Click the 'Choose File' button and locate the .sql file you just downloaded.
- All that’s left for this step is to click the ‘Go’ button to import your data.
Step 4: Apply Database Migration Fixes
There are two primary fields which need to be modified in order for your migrated WordPress installation to even function.
- Rather than browsing the data in the wp_options table, let’s just click the ‘SQL’ tab up at the top and send the Database Server Ninja Assassin Monkey Troop off to do our dirty work:
- UPDATE wp_options SET option_value = 'http://www.craniumstorm.com' WHERE option_name IN ('siteurl', 'home')
UPDATE wp_options SET option_value = 'http://www.craniumstorm.com' WHERE option_name IN ('siteurl', 'home')Insert that SQL query in the giant ‘Run SQL query/queries on database…’ field and change the http://www.craniumstorm.com to reflect the root level of the site you’re transferring to (so, if you’re moving WordPress to www.domainfoo.com/bar make sure that the /bar is appended here).

(Fig. 5) First, click the 'SQL' tab at the top. Then, copy-paste the above SQL query into the appropriate field and modify it to reflect your new domain before clicking 'Go'.
- Click ‘Go’ to execute the query. You should see a green message box saying that two rows were changed.
- UPDATED: Things change, and I’d be remiss if I failed to update my most popular tutorial to reflect my present methods. At this point, you’re ready to update your image URLs. Do yourself a favor, save yourself some time, and use the Velvet Blues Update URLs Plugin, available from the WordPress Plugin Directory. This plugin is so handy, and works so smoothly, that it should be incorporated into the WordPress core. I can’t imagine why you’d want to perform this step by hand, but if you’ve got a hankering for some more SQL-executin’ action, read on…
If you’ve read some of my other stuff, you may have seen the post about fixing broken image links in WordPress posts when transferring domains. I’ll re-iterate it here to spare you having to read any more of my torturous bullshit. Now that our crack team of Database Server Ninja Assassin Monkeys has returned from their recent, successful foray, we’ve got another mission to which they’re ideally suited:
- UPDATE wp_posts SET post_content=(REPLACE (post_content, '{old url}','{new url}'))
UPDATE wp_posts SET post_content=(REPLACE (post_content, '{old url}','{new url}'))You’re already right where you need to be. Just paste this query over the last and modify the {old url} and {new url} to reflect whatever constitutes reality in your case and then click ‘Go’ again.
(Note: When I say ‘modify them to reflect reality’ I mean that you’ll want them to be the full significant portion of the url which needs changed. So, if you’re moving from http://www.oldfoo.com/blog to http://www.newfoo.com you’ll want {old url} to say ‘www.oldfoo.com/blog’ and {new url} to say ‘www.newfoo.com’.)
- Smile. You’re getting good at this.
Caveats
If you’re moving your WordPress install to the directory ‘/bar’, but you want visitors to get to it by going to ‘http://www.domainfoo.com’ (without the ‘/bar’), step 4.1 is going to be different for you. In such a case you need different values for ‘home’ and ‘siteurl’. From the WordPress Codex entry Changing the Site URL:
- The “Home” setting is the address you want people to type in their browser to reach your WordPress blog.
- The “Site URL” setting is the address where your WordPress core files reside.
This means that we’ve got to run two queries in the first step instead of one. The code you’re going to paste is going to look like:
- UPDATE wp_options SET option_value = 'http://www.domainfoo.com' WHERE option_name = 'home';
- UPDATE wp_options SET option_value = 'http://www.domainfoo.com/bar' WHERE option_name = 'siteurl'
UPDATE wp_options SET option_value = 'http://www.domainfoo.com' WHERE option_name = 'home'; UPDATE wp_options SET option_value = 'http://www.domainfoo.com/bar' WHERE option_name = 'siteurl'
‘You do not have sufficient permissions to access this page’
This will happen if you change the wp_ prefix on your WordPress database tables. Everything’s just starting to come together for you, but when you try to access your admin panels you get a box in the middle of the screen saying ‘You do not have sufficient permissions to access this page’. The WordPress Codex entry for Login Trouble has a bunch of things to try, but none of them apply to the issue you’re having. I’ll include the correct fix here:
- UPDATE `{new prefix}_usermeta` SET `meta_key` = REPLACE( `meta_key` , '{old prefix}_', '{new prefix}_' ); UPDATE `{new prefix}_options` SET `option_name` = '{new prefix}_user_roles' WHERE `option_name` = '{old prefix}_user_roles';
UPDATE `{new prefix}_usermeta` SET `meta_key` = REPLACE( `meta_key` , '{old prefix}_', '{new prefix}_' ); UPDATE `{new prefix}_options` SET `option_name` = '{new prefix}_user_roles' WHERE `option_name` = '{old prefix}_user_roles';Just replace {new prefix} and {old prefix} in the above query with the correct values for your situation. (Special thanks to Christian Schenk for his great write-up on this issue!)
Step 5: Upload the WordPress Site and Edit Your Configuration
If your files are still downloading at this point just make a cup of tea and relax for a while. Uploading the entire WordPress site is the next logical step here.
- When you’re ready, connect to the FTP host for the new site.
- Upload the entire contents of the site to its new home.
- Edit your /wp-config.php file to include the correct information for your new database:
- // ** MySQL settings - You can get this info from your web host ** //
- /** The name of the database for WordPress */
- define('DB_NAME', 'craniumstorm');
- /** MySQL database username */
- define('DB_USER', 'craniumlocal');
- /** MySQL database password */
- define('DB_PASSWORD', 'somePass');
- /** MySQL hostname */
- define('DB_HOST', 'localhost');
// ** MySQL settings - You can get this info from your web host ** // /** The name of the database for WordPress */ define('DB_NAME', 'craniumstorm'); /** MySQL database username */ define('DB_USER', 'craniumlocal'); /** MySQL database password */ define('DB_PASSWORD', 'somePass'); /** MySQL hostname */ define('DB_HOST', 'localhost'); - This has come up a couple of times now, so I’m going to say here in advance that you should try logging into the admin panel in the new location at this point. If you get in without any problems, go to Settings > Permalinks and click ‘Update Permalinks’ to make sure WordPress updates the .htaccess file. If it can’t for some reason, you should see a message reading something along the lines of ‘If your .htaccess file were writable, we could do this automatically, but it isn’t…‘ at the bottom of the admin panel. In that case, make sure that you edit your .htaccess file to reflect your current domain configuration:
- # BEGIN WordPress
- <ifmodule mod_rewrite.c>
- RewriteEngine On
- # RewriteBase must reflect the root of your WordPress installation
- # So, if you're running WordPress at http://www.domainfoo.com/bar
- # you'll need to set this to 'RewriteBase /bar'
- RewriteBase /
- RewriteRule ^index\.php$ - [L]
- RewriteCond %{REQUEST_FILENAME} !-f
- RewriteCond %{REQUEST_FILENAME} !-d
- RewriteRule . /index.php [L]
- </ifmodule>
- # END WordPress
# BEGIN WordPress <ifmodule mod_rewrite.c> RewriteEngine On # RewriteBase must reflect the root of your WordPress installation # So, if you're running WordPress at http://www.domainfoo.com/bar # you'll need to set this to 'RewriteBase /bar' RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </ifmodule> # END WordPressIf WordPress is unable to modify this file automatically it’s because of a permissions problem. The best means for fixing this depends on your hosting provider, but the .htaccess file needs to be writable by WordPress.
- That’s about it!
Aftermath
Naturally, you’re going to want to verify that your site is working correctly before moving on with life. The only variables we didn’t address here are plugins and templates. The primary offenders I’ve found are plugin authors who have elected to store literal URLs for files in the Media Library instead of using get_bloginfo(‘wpurl’) for the URL base (if you’re such a plugin author, fix your code please).
Stay Tuned…
If you enjoyed this post or found it otherwise useful, please support CraniumStorm by liking us on Facebook. We’re looking a little shabby over there, and if 1/10 of the people who came to this site just to view this page turned out in our support, we’d have 50 likes already this month!






[...] For the purpose of setting up a local environment for testing things out, this may not matter. But if you want to update all the links within blog posts as well, instructions can be found in some of the articles linked from here such as this one. [...]