Migrating WordPress Websites

Website migrations can be stressful, but it doesn’t have to be. I’ll walk you through four different ways to migrate your site based on your unique situation.

  1. Automated migration to a new server
  2. Manual migration to a new server
  3. Automated migration to live server
  4. Manual migration to live server

Moving to a new server

It’s much easier to launch your site on a new server than to launch it on the one hosting your live site. With a new server launch there’s no downtime for your website.

You can take your time to make sure everything is working, and only then update your domain’s DNS settings. Users will begin to see the new site as the DNS change propagates, with most seeing it within a few hours.

With a new server, you can take your time to make sure everything is working, and then update your domain’s DNS settings to seamlessly transition with no downtime.

Automated migration to a new server

Many webhosts have automated tools to help you migrate your site.

If you’d like to use WPEngine as your new host (I recommend it), you can use their automated migration plugin.

I use WPEngine as my development server and migrate all my client sites using this plugin before starting work on their redesign. It works great, even for very large sites.

  1. Purchase your new hosting plan
  2. Log into My WPEngine, and click SFTP in the left sidebar
  3. Add an SFTP User and write down the Username, Password, Server Name, and Port Address.
  4. On your live site, install the WPEngine Automated Migration plugin.
  5. Click “WPEngine Migration” at the bottom of the admin bar menu and you’ll see this screen.
  6. Type in your email address, WPEngine URL (yoursite.wpengine.com), and your SFTP details
  7. If your WPEngine install is password protected, click “My site is password protected” and type in the username/password. All transferrable installs are password protected, and this can be found in My WPEngine on the Overview page (screenshot).
  8. Click “Migrate” and wait for the migration to complete! You can close this window if you’d like. They will email you when the migration is finished.

For hosts that don’t have an automated tool, you can use Migrate Guru. The steps are similar to the WPEngine ones listed above. You can also try the Duplicator plugin – see this tutorial by WP Beginner.

Once the site is on your new hosting environment, it should be accessible from an internal URL like yoursite.wpengine.com. You should confirm that the site looks and works correctly.

You’ll need to update the URLs in the site to match your live site. Either ask your host’s support to help you, or use one of these tools:

  1. Better Search Replace plugin
  2. wp cli on the server. Type wp search-replace clientsite.wpengine.com clientsite.comwith the first one being the temporary URL and the second one being your final URL. If you’re using WPEngine, you can click the “Advanced” tab to access wp cli (screenshot).

Finally, you should update your domain’s DNS settings with your domain registrar (ex: Godaddy) to point to your new host (more information).

Manual migration to a new server

A manual migration is pretty straightforward. Assuming WordPress is already installed on the server, you simply need to move all the site’s files (the wp-content directory) and the site’s database.

It’s easier to move one large file than lots of little ones. I like to package the wp-content directory into a tarball, then upload that to the server.

In my local copy of the site, I run tar pvczf wp-content.tar.gz wp-content. That compresses the entire wp-content directory into a single wp-content.tar.gz file. I then upload that directly to the server.

If I have SSH access, I’ll delete the existing wp-content directory, then run this to unpack the file: tar zxf wp-content.tar.gz. If I don’t have SSH access, I’ll ask the host’s support to unpack it for me. You might also need to ask them to update file permissions.

There’s a few ways you can migrate the database. You can log into phpMyAdmin on the server and manually upload it, but if it’s a large database it will time out before it’s fully uploaded.

If you have SSH access, you can upload the sql file to the server, then run mysql -p u username database_name < file.sql to import it. Tip: do the same tar compression shown above. SQL files compress super small.

Once uploaded, use Better Search Replace or wp cli to update the URL (see above).

I personally prefer using Migrate DB Pro to move databases. It works in all situations – I don’t need SSH access, and I don’t have to worry about the database size.

Install the plugin on your local copy and the new server’s WordPress install. Log into the new server, go to Tools > Migrate DB Pro > Settings and copy the Connection Info. On your local site, go to Tools > Migrate DB Pro, click “Push” and paste the connection. You can even tell it to update all the URLs before pushing to the server.

Once all the files and database are in place, test to make sure everything works, then update your domain’s DNS settings to point to the new server.

Migrating to your live server

This is more complicated. You need to have a solid plan in place – make a checklist so you don’t forget anything – and work fast. If you do it right, you can minimize the downtime.

Automated migration to live server

You could use the exact same tools shown above for the automated migration to a new server. But I’m personally afraid to let an automated tool start overwriting the database and files on my live server. If something goes wrong, there’s no “off” switch to stop those tools.

Any time I’m migrating a large site back to it’s original host, I speak with the host directly about setting up a staging environment. We then migrate to the staging environment, exactly like the new server approach above.

Once the site is setup (staging.clientsite.com), we ask the host to flip the switch. It usually takes about 30 seconds and they’ve swapped the files and databases for the two sites.

This depends upon having a high quality host who can provide this level of support. When working with lower tier hosts, I typically do a manual migration.

Manual migration to a live server

The goal here is to minimize downtime by getting all the pieces in place before making changes visible to users.

First, upload the wp-content directory to the server (same as the manual approach described above), but use a different name for the directory. I typically call it wp-content.new.

Determine how you’re going to migrate database: via phpMyAdmin (make sure the database is much smaller than the max upload size), SSH, or Migrate DB Pro. If SSH, upload it to the server so it’s ready for you.

Rename the current wp-content directory to wp.content.old, and wp-content.new to wp-content. There should be minimal disruption at this stage since all the themes, plugins, and uploads from the old wp-content directory should already be in the new one.

If possible, create a second database on the server and upload the new tables there. Toggling between old and new versions of the site is as simple as changing the database name in wp-config.php. If you can’t create a new database, make a backup of the live database so you can restore it if something goes wrong.

Change out the database and make sure everything looks good. If something looks broken, rename the wp-content directories again and quickly swap out the database so you’ve restored the “old” version, then figure out what went wrong.

Bill Erickson

Bill Erickson is the co-founder and lead developer at CultivateWP, a WordPress agency focusing on high performance sites for web publishers.

About Me
Ready to upgrade your website?

I build custom WordPress websites that look great and are easy to manage.

Let's Talk

Reader Interactions

Comments are closed. Continue the conversation with me on Twitter: @billerickson

Comments

  1. Boone Gorges says

    This is a good write-up. Thanks.

    When possible, I highly recommend using rsync to move files from one server to another, rather than sending a tarball. For one thing, it takes fewer steps (a single rsync, vs tar/send/untar). For another thing, it can pick up where it left off, while an enormous tar transfer could die on a crummy connection, and you’d have to start over again. Perhaps most importantly, rsync preserves file masks, including file permissions and any other security layer (like selinux), which can be especially important when your WP install has, eg, custom locations that must be web-writable (like /wp-content/cache or something like that). Of course, this means you’ve got to have SSH access, but I try to avoid working on any projects where I don’t 🙂

    • Bill Erickson says

      I agree, rsync via SSH is definitely preferable, but I estimate only 1-2% of my clients can give me SSH access. Most of my clients use WPEngine for hosting (they don’t provide SSH access), and the ones who do have hosting that allows it usually can’t figure out how to get it for me.

      On most of my projects, the additional work required in obtaining SSH access takes longer than an SSH-based migration would save.

      • Jeremie says

        Very cool article. Thanks Bill (for this and all your other resources).
        I’m just in the middle of setting up my whole WP dev set up and workflow (also using WP Engine) and thinking of using git push (instead of SFTP’ing the files).
        What do you think about this / do you use it at all since you’re also on WP Engine?
        (only downside I can think of is for content files not allowed in the WP Engine git push…)

        • Bill Erickson says

          While I love that they offer git push, it only makes sense if you’re already working on a large WPEngine-hosted site. My process of migrating from my dev server to a WPEngine account would be slowed down by git push (I’d have to set up git).

          But I am excited to try it next time I work on a large site that’s hosted with WPEngine.

          • jeremie says

            Got you, thanks. I’m only working on one WP site for a client, with lots of revisions planned so it makes sense for me to use git for managing my codebase. I love the fact that I can do a git push to staging, get the client to review and git push the same commit to prod once they’re happy with it.

  2. Ashley Isaacson says

    Hi Bill,

    I really liked this breakdown of steps. I believe I followed each step correctly, except when I enter in the url of my website, it tags on :8888 and doesn’t display. Do you know why this is? I ran the Search and Replace PHP script, even a couple of times, the first time searching for ‘localhost’ and the second time (and I think actually a third) searching for ‘localhost:8888’ to see if that would stop the browser from automatically appending the :8888 onto the url.

    Thank you again for this article.

    Ashley

    • Bill Erickson says

      Log into phpMyAdmin and go into your wp_options table (or xxx_options, where xxx is your custom table prefix). Look to see what URL is being stored in the database.

  3. Andy says

    Hi Bill.
    Above in 12. Go to Settings > Privacy and make sure you have the site visible to search engines.
    Do you not mean “invisible” to search engines? And, in the latest WordPress (as of this post 3.5.1) it is Settings > Reading > Site Visibility select “Discourage search engines from indexing this site”
    Or, am I missing something here?
    Cheers
    Andy

    • Bill Erickson says

      Correct, the setting has now moved to Settings > Reading.

      The reason I say “set it to visible” is because I use these instructions go from development site to production site. I have the development site “invisible to search engines”, and when I go back to the live I want to remember to make it visible.

      If you’re going from a live site to a development server, do the reverse – go to Settings > Reading and set it to invisible.

  4. Bryan Taylor says

    You saved my —! I was migrating a WordPress site, for the first time, for a big client and after the transfer all the pages except for the home page would go back to my dev site. Even the admin! In a frantic search I found the older version of this post and I will tell you, it still works! I added some ticks around column names and straight quotes around strings but other than that, it was the ticket I was looking for. Thanks so much for for that, not sure where I would be right now if I hadn’t found it.

  5. Andrew says

    Like one of the other commenters, I normally use a script to migrate from one site to another. For instance the script changes URL and full path (serialized) strings in the database dump. The path being something like ‘/home/username/public_html’.

    In the case of WPEngine, I don’t know what that is. Any ideas?

      • Johnny5 says

        That request for information took about a day, but I eventually got it from them. Turns out the full path (in my case) is /nas/wp/www/sites//.

        Therefore, when I run my script, I add source/destination URL’s and full path. It modifies the strings (including serialized ones) in my dumped database. For instance:

        client1.dev —-> client1domain.com
        /var/www/client1_dev —-> /nas/wp/www/sites/client1

        Once that was done, I imported the modified .sql file into WPEngine and overwrote the wp-content directory with my own and the site worked like a charm.

  6. Joe says

    Hi,
    I am probably doing something wrong but after moving the databse, searching and replacing url in it and copying the wp-content folder i still see the same old “just another wordpress site” instead of a copy of my actual site at the new server.
    Any suggestions on what i’ve missed?
    Thanks!

    • Bill Erickson says

      Look in wp-config.php and make sure all the database info is correct (host, username, password, and table prefix). It sounds like that site is looking at a different database that has a blank WordPress install in it.

  7. Roy Emory says

    I have used the Duplicator plugin to replicate a site from one host to another- very useful tool.

  8. Rakesh Pherwani says

    Hi,

    I just migrated a ‘WordPress-WooCommerce’ site from dev server to client’s server. Though all the posts etc transferred correctly, none of the product images show up – the media manager doesn’t seem to recognize the earlier files in the ‘uploads’ directory. As a test, a uploaded a image for a product and it shows up on the page

    I used ‘interconnectit/Search-Replace-DB’ to replace old URLs with new one. Will Steps 9 & 10 of your process resolve this issue or, do you have any other tip.

    Thanks

    • Bill Erickson says

      Did you follow all of these steps for your migration? It sounds like you didn’t. Instead of just doing Steps 9 & 10, I recommend you start over from Step 1.

  9. Neil says

    Hi,

    Would you recommend disabling my plugins when I attempt to migrate my site. I previously tried migrating and got errors caused by wptotal cache plugin.

    thanks

    • Bill Erickson says

      I don’t use caching plugins when I’m doing development since you have to continually rebuild the cache. But you shouldn’t have any issues migrating with the plugins active – just rebuild the cache once you get over there. Make sure you’re copying over the entire wp-content directory. W3TC adds some files to the top level of /wp-content, and if those don’t make it over then you’ll have errors.