… and why I haven’t been posting much content over the past few weeks.
It may seem strange to offer a “how-to-move-your-website” article when my own upgrade was less than seamless. Part of my trouble was that I was trying to do several things at once.
- Move webhost from a shared host to my own Virtual Private Server. Not being a webhost professional, configuring my various hosting tools was a learning experience in itself.
- Upgrade from WordPress 2.2.3 to 2.3.3.
- Change my site’s URI to get rid of the “/blog” in the title
Each one of these tasks is likely to cause disruption in itself, and I wanted to avoid three separate opportunities for mess-ups. So I opted to get it all over with at once (which probably an experienced project manager would always caution against), but I tried to minimise the risk by testing as much as possible in advance.
To be honest, I got a bit bored with poking around trying to figure out which plugins worked with the latest version of WordPress. So I only tested three or four and then went ahead anyway. Seeing that many of the bugs, when I finally moved, related to plugins which worked fine in the test site but not at the new webhost, I’m glad I cut that particular corner.
In outline, the process I followed for stepping from one place on the web to another was
- Install WordPress at the new webhost
- Transfer all images, files, plugins, theme templates over to the new webhost.
- Wipe the database of the new installation
- Export the complete database from the current blog and import it into the new database (with minor edits if necessary)
- Change the DNS settings
At this point, the standard plugin installation instructions read “… and you’re good to go”. But that’s never enough for me. Plus, those steps don’t include the WordPress upgrade and database cleanup.
So this article includes an intermediate step of trying all these things (except #5) on a test blog before making the final move. The test blog enabled me to ungrade the database and WordPress installation without disrupting the live site. I even tested step #5 on a much smaller live blog just to get comfortable that provided you complete steps 1-4 correctly, changing the DNS settings will do the job for you.
These notes assume that your existing webhost provides you with cPanel, and that you’re moving to a VPS with WHM and cPanel installed.
It also assumes you’ve got the PHP in your new VPS configured correctly, and that you have enough memory. For the full story, read this article, but in summary, you need PHP SuExec, with multibyte string support, and probably 512MB of minimum RAM.
The numbering of the sections on the following pages linked below do not match the outline 5-step process outlined above, because I go into more detail.
Now read on…
1. Create the new account at your new VPS
In Web Host Manager, go to the Account Functions > Create a New Account page
1.1 Domain information
- Enter yourdomain.com in the Domain box (without the www.)
- The username is automatically generated, though it can be changed. For the purposes of these notes, the username is myuserna.
- Input a password (or auto-generate a really secure one)
- Input a contact email address
- Select a package. I just selected the “default” one as I haven’t set up any particular packages as I’m not in the business of webhosting.
- Seeing that I only have one IP address for my different websites I leave the “Dedicated IP” box unchecked.
- Shell Access: checked
- FrontPage Extensions: Unchecked. I assume this refers to Microsoft Frontpage. As my sites are Microsoft-free zones I leave this unchecked
- Cgi access: checked
- cPanel theme: I don’t really care what the cPanel looks like so I left it at x3
1.4 Reseller priveleges
- unchecked. I don’t want to give this site (or any future owner after I lose interest in it) the right to start its own webhosting business on my virtual server.
1.5 DNS settings
- “Use domain registry nameservers (ignore locally configured ones)”.
If I check this box, the existing nameservers for the webhost where my blog is currently hosted are displayed (ns1.oldwebhost.com and ns2.oldwebhost.com). I bought my domain name from buyaname.com, and my account settings at buyaname.com point my domain name at my old webhost’s nameservers: ns1.oldwebhost.com and ns2.oldwebhost.com. I read in a support forum (if I understand the comment correctly) that this is a once-only lookup. So if you check this box my guess is you will forever be tied to ns1.oldwebhost.com and ns2.oldwebhost.com. Since you’re moving your account, that’s not a good idea. So I leave this box unchecked, and the default nameservers of ns1.mynewvpshost.com and ns2.mynewvpshost.com should be displayed, and that seems like a good idea.
- Overwrite existing dns zones. I left this unchecked because I don’t know what it does.
Then I clicked OK. WHM says it has emailed me the account settings.
2. Check it’s all working
2.1 Check the webspace itself
The WHM software sent an email to the top-level email address associated with my VPS account (not the email address I set up for the new blog account in 1.1 above). And it didn’t contain any info on how to use my new account. Fortunately I half knew the ropes from my previous experiences with cPanel at my old webhost.
To check that the account had been created, I logged on to
http://220.127.116.11/~myuserna/. (where of course that string of numbers is the IP address of the VPS). Bingo. I get to a screen which gives me a brief index of /~myuserna. Needless to say, there’s not much there, but at least there’s something.
2.2 Check your Control Panel
Then, to play around a bit more, I logged on to the control panel by entering http://18.104.22.168:2082/ using the username and password created in step 1.1 above. Success again.
2.3 Install WordPress
Next – I installed the latest version of WordPress supported by my cPanel’s Fantastico plugin: 2.3.3. I’ve tried installing WordPress manually before, but what’s the point when you’ve got a routine which does it all for you? I don’t like faffing around with configuration files. The Fantastico installation is a breeze.
Now if I go back to http://22.214.171.124/~myuserna/ . I get an error message:
The requested URL /~myuserna/ was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
That’s fine, because it shows that WordPress is trying to do something. WordPress is getting confused because, as of now, the blog’s domain name isn’t yet pointing to the right server. That should all be fixed when I update my DNS settings at my domain registrar.
But, to give you confidence for the move, it’s worthwhile playing around with a test installation of WordPress in a subdomain of your existing site. That way you can practice the steps of moving data to see how it all works. Once you’ve got comfortable with that process, all you have to do differently when trying it for real is the additional step of switching the DNS settings.
2.4 Configure your FTP software
I use CuteFTP Professional. I created a new ftp account in CuteFTP thus:
File > New > FTP Site, inputting
Label = My new blog
Host address = 126.96.36.199 (the VPS IP address)
Username = myuserna (generated when I set the new account up in WHM)
Password = the really strong password generated by WHM in 1.1 above.
Everything seems to work. I can see the WordPress files in public_html. Time for the next steps.
3. Prepare the move
3.1 Make sure your WordPress versions are consistent
If you’re running an older version of WordPress on your live site, you need to make sure what you’re transferring to your new site is going to work. You can do this two ways. Either upgrade your live site to the latest version of WP, or do it offline. Because upgrading a live site usually involves an hour or so of downtime and causes disruption to plugins and the like, I elected to upgrade offline. That way my readership only gets one disruption rather than two. (I suppose you could try a third way – send an old format database into a your brand new live site and hope for the best, but that’s not recommended).
3.2 Set up your test blog at your existing webhost
3.2.1 Set up the subdomain
You can do this by setting up a subdomain in cPanel. Say the subdomain is test.yourdomain.com.
3.2.2 Install WordPress
Install the latest version of WordPress in the subdomain’s root directory using the Fantastico plugin.
If you go to test.yourdomain.com in your browser, you’ll see the familiar “hello world” message in the default WordPress theme.
Go into phpMyAdmin and you’ll see the new database (with probably 10 tables).
3.2.3 Transfer the template files, images, plugins and other uploads
This is simply a matter of copying all the images from the old webhost onto the new one using the ftp account you set up in 2.4. Be careful to maintain the same directory structure.
In addition, make sure you copy over your active theme and all the plugins.
Don’t transfer over your WordPress files themselves (because they’re the old versions). Especially don’t transfer over your wp-config file. But if you use pretty permalinks you’ll probably find you need to transfer over your .htaccess file as it has the crucial redirect rules to make the permalinks work.
4. Transfer the data
This is the big complicated thing. I tried this out several times to make sure I half new what I was doing. I did this because as well as changing webhosts I was changing the directory structure of my installation to get rid of the /blog/ in my URI, and needed to clean some of the data as well.
4.1 Before you start
In your live site, delete all spam comments. This will reduce the size of the files you’re dealing with.
Log into your cPanel.
In phpMyAdmin, select your main WordPress database (probably called myuserna_wrdp1). Note the quantity and size of the tables, so that you can compare these with those in your new installation. I found that sometimes tables managed to lose some rows during the course of the process we’re about to go through, and if that happens you’re going to need to know about it so that you can reperform the process.
4.2 Export your database
Using phpMyAdmin, export your existing blog database as an sql file and download it onto your computer. If you are using plugins like Bad Behaviour or an RSS aggregator which stores loads of data, you may want to think about not exporting all this historical data. My own Bad Behaviour and BDP RSS tables were so massive that I elected to leave them behind.
4.3 Tweak your data
Open the sql file in your favourite text editor (maybe textpad) and make sure the name of the database agrees with the name that your wp-config.php in your new WordPress installation is expecting. If not, edit it. Your “live” database will likely be called something like myuserna_wrdp1. Your new test database might be called myuserna_wrdp2. (First time I tried this, I didn’t edit the name in the sql file, and when I went through the next step it looked like phpMyAdmin was trying to over-write my existing production database, which scared me.)
Next – and this is necessary (a) because I wanted my test installation to work properly which was in turn (b) because I was changing my URI anyway and I wanted to test the process – I replaced all instances of “www.mydomain.com/blog” with “test.mydomain.com”, using the text editor. If your existing blog is “www.mydomain.com” rather than “www.mydomain.com/blog” it’s of course “www.mydomain.com” that you will replace with “test.mydomain.com”. Without doing this change, when you click on any link in your test blog it will take you back to your live site. Which meads you won’t be able to test anything.
4.4 Clean up the data and check the collation
If you don’t think you’ve got a data issue, then you can skip this step. Alternatively, skip this step. You can always come back and do section 4 all over again. I did, several times.
A big challenge I had, because of the collation settings of my existing database (a complete mess, with fields, tables and the database as a whole set up seemingly randomly as either latin1_swedish_ci or utf8_unicode_ci), was that a lot of my non-standard characters got mangled at the export stage. So, when I looked at my test blog there were all sorts of strange characters. No amount of fiddling with the collation of the live database seemed to fix this, so I re-performed step 4.3 adding in a search and replace function to get rid of all the garbled characters. Be careful if one of the characters that has got garbled is a single apostrophe. If you replace your gibberish character with [ ‘ ] you will most likely find that the re-import of the database breaks down. Replace it with [ ” ] (that’s two apostrophes with no space in between), which mySQL seems to be happy with (or even better, use the relevant string which starts with a [ & ] and ends with a [ ; ]).
In addition, if there were any instances of “latin1” or “latin1-swedish-ci” in the sql file, I changed them to “utf8” and “utf8-general-ci” respectively (Note: those hyphens might in reality be underscores. You’ll need to check that). That will make sure that when you import the database into your new installation you don’t get a horrible confusion of collation settings. UTF8 is the way to go, not Latin, if like me you need to deal with Asian text.
4.5 Prepare your new database
Next, in phpMyAdmin, select the new test database (probably myuserna_wrdp2). It probably has 10 tables in it (probably much fewer than your existing database, which is likely to have additional tables created by your various plugins). Make sure the collation of the database is set at utf8-general-ci (or utf8-unicode-ci). If not, change it using the “operations” tab.
Select all tables from the new test database and “drop” them (ie delete them).
4.6 Import your data into your new database
Import the sql file you edited above. This may take a while. Check that the number of tables, and number of rows is the same as the numbers in the existing database. Hopefully it’s a carbon copy of your live database in terms of number of tables and number of rows in each table.
5. Playing with your test blog
5.1 Tweak the blog name
Try it all out by typing your test.mydomain.com in your web browser. Hopefully, because all the preferences are stored in the database – and because you’ve copied all your files over – your test blog will be working just fine and look just like your “live” site. Maybe so you won’t get confused, go to the Options >> General page and change your test blog name to “My TEST Blog”.
5.2 Upgrade the database to the latest version of WordPress
At this point I remembered that when you move from one version of WordPress to another you need to upgrade the database structure. This is done by going to test.mydomain.com/wp-admin/upgrade.php. I automatically got the prompt to upgrade the database when I logged in to wp-admin.
5.3 Check the data
Skim-read a few of your posts to make sure the data has transferred properly. If not, you may need to reperform section 4, including step 4.4. If any Asian characters are garbled, you’re on your own. I was.
5.4 Check plugin functionality
Log in to the plugin page in your new test blog, which is using your brand spanking new version of WordPress, to see whether the plugins work are compatible with the latest version. Upgrade to the latest version of the plugin and make any further template changes you need to make the upgraded plugin work with your theme. Or, if the plugin isn’t compatible with the latest WP version, consider finding another plugin which does a similar job.
This, I always find, is the most painful part in any WordPress upgrade.
6. Do the real thing
OK, so now you know how to get data from one WordPress installation to another, and you know which plugins will work in your new installation. You’ve also got your database collation cleaned up so that when you export again you won’t scramble your apostrophes or Asian characters.
6.1 Transfer the template files, images, plugins and other uploads
This is simply a matter of copying all the images from the old webhost (or test blog) onto the new one using the ftp account you set up in 2.4. Be careful to maintain the same directory structure.
In addition, make sure you copy over your active theme and all the plugins.
6.2 Transfer the database
Having tried this so many times already, you’re going to be a pro at this. But if you skipped the test blog part of this process, check section 4 for the expanded version of the instructions below.
- Export your clean database as an sql file onto your computer.
- If necessary, edit the database name in the file.
- If necessary, edit all internal URIs to make sure your new site is going to work properly. In my case I changed every instance of “test.mydomain.com” to “mydomain.com”. If I hadn’t done my intermediate testing using the test blog I would have changed every instance of “mydomain.com/blog” to “mydomain.com”. Clearly, if you have got your directory structure the way you want it from the start, then you won’t need to edit any of the URIs.
- Log on to your cPanel at your new webhost.
- In phpMyAdmin, select the WordPress database.
- Ensure the collation is set to utf8_general_ci or utf8_unicode_ci. If not, change it.
- Select all tables from the new database and drop them.
- Import the sql file you edited above. Check that the number of tables, and number of rows is the same as the numbers in your database.
At this point, you can do no more.
7. Final configuration
I needed to make sure that people using my existing URI could find my new site. As I was just losing the /blog/, I created a /blog directory in my new WordPress root and put a redirect in there in an .htaccess file.
RewriteRule (.*) http://yourdomain.com/$1 [R=301,L]
The text of the redirect I lifted from Blogging Tips. Kevin over there is a great help.
If you’ve got pretty permalinks on your existing site you need to make sure that your .htaccess file is copied over in 3.1. Pretty permalinks don’t work without that .htaccess file.
8.1 Prepare some “move” posts for your blog
If you’ve planned this well, you will have prepared two blog posts:
- one to announce your impending move, and
- another one to announce your arrival at the new host.
You’ll publish the “departure” post just before step 3.4, or maybe just before you change the nameserver in step 9, and schedule your “arrival” post to be published in a day’s time. Your “arrival” post will say something like “if you can read this, I’m at my new webhost. Please report any bugs by leaving a comment below”.
Before you change the nameserver (step 9 below), you’ll want to delete the “arrival” post from your old WordPress installation so that it doesn’t pop up there and confuse the hell out of everyone if the propagation of the DNS changes takes longer than a day.
8.2 Tweak your new header.php
Just so that I know when all the DNS stuff has propagated, using my FTP software (or cPanel file manager) I edit the header.php in the copy of my active theme which I’m going to send over to my new webhost: I add “(at new webhost)” after the < ?php bloginfo(‘description’); ?> tag. I’ll delete it once everything’s working satisfactorily.
The moment of truth…
Update the nameserver and hope for the best. Go and have a beer. You’re going to need to conserve your energy for cleaning up all the bugs.
For me, it took less than twelve hours before the proverbial hit the fan. A heavy-duty cleanup was required, but unfortunately the hit squad was just me…
10. Lessons learned
Maybe if I’d had my time again, my test blog would have been on my new VPS rather than at my existing host. I thought I’d minimised the risk by moving over another live blog before doing my big site. But the small blog used very few plugins and so did not really test the limitations of the default VPS configuration.
If, like me, you’re focused on the content rather than the infrastructure, you’ll know very little about server configuration. It’s strange when you have two apparently identical WordPress installations – including the same file permission settings – but on one website a plugin works and on the other it doesn’t…
So, maybe if I’d had my time again I’d have tried to run a parallel installation of my big website on the VPS before changing the DNS settings. But I’m guessing that if I did that, I’d have spent so long ironing out the problems on the test site that I would never have made the move. In a test environment, there’s no real time pressure to get things working, whereas when you crash land there’s immediate pressure to get the bugs fixed. I’d paid for about 6 months of VPS space before I started doing anything with it. I’d spent too long dithering and it was time to make a move. It’s been a learning experience.