Moving WordPress To New Server (Faster)

During my recent WordPress-Nginx tutorials series, I posted how to setup a fresh wordpress but did not say anything about moving an existing wordpress setup. There are many ways to move a WordPress setup from one server to another. And the way you follow doesn’t have any impact on your Nginx config so I kept that topic for a separate post.

We generally use following workflow coupled with one of the 2-migration methods described later. Even though our job involves moving WordPress sites mosly, following can be used to move any type of sites/files from old-server to new-server.

Notes:

  • old-server: Server which has WordPress running before moving.
  • new-server: New destination server where we want to move WordPress. (Assuming PHP, Mysql already installed)
  • old-server-ip: IP Address of old-server
  • new-server-ip: IP Address of new-server
  • example.com: Public domain on which WordPress site/blog is running. Please check this for other conventions.

Workflow for moving WordPress/Websites:

To avoid downtime or disruption of service for site visitors, we generally follow following steps:

  1. Lower TTL value for relevant DNS-records for example.com. 
  2. Put old-server in frozen state so that people can read your articles but can not comment on them! We use code-freeze plugin for this.
  3. If old-server supports SSH access, take a mysqldump of database. Or download zipped sql dump via phpMyAdmin, cPanel, etc.
  4. Transfer WordPress stuff (files, database, etc) to new server. Using rsync or ncftp as explained below.
  5. Configure new server properly (wp-config.php changes, mysql import, file-system paths, etc)
  6. Cross-check if WordPress on new-server is running properly by making pointing IP address for example.com to new-server (by making changes to /etc/hosts file on local machine).
  7. Then remove code-freeze plugin on new server. Please note that its still running on old-server!
  8. Finally make changes to DNS entries for example.com (mostly A-record). You may need to update SPF-records if you are using them. Also, you may increase TTL values again.
  9. Setup old-server as transparent proxy to new-server.

If you are doing this for the first time, then its better to perform a dry-run. Otherwise you may end up freezing your old-wordpress for long time. 😉

Most steps are self-explanatory. Some depends on your old & new server environment/config/hosting-company. Below are some codes to help you.

Lowering TTL Values (step #0)

Please note that we need to lower TTL value only. This is NOT time to change IP address value or other things in DNS-records.

Only TTL-value.

(Thanks to Neal for reminding me to add this point here)

Using mysqldump to backup/restore database (step #3)

This is possible only if your old-server allows SSH access.

We use following command. Values of MYSQL_USER, MYSQL_PASS & DATABASE_NAME are replaces by values from wp-config.php.

mysqldump -u MYSQL_USER -pMYSQL_PASS DATABASE_NAME > DATABASE_NAME.sql

Once DATABASE_NAME.sql gets transfered to new-server, you can use following command to import it:

mysql -u MYSQL_USER -pMYSQL_PASS DATABASE_NAME < DATABASE_NAME.sql

If you do not have SSH access, then just download database dump using phpMyAdmin and upload/import it using normal FTP or phpMyAdmin again on new-server.

Methods of moving WordPress files, database dump, etc (step #4)

We generally follow one of two ways listed below and the choice depends on availability of SSH access.

Using ssh/rsync (fastest)

If SSH access is available on both, old and new server, we use rsync. Exact instructions are hard to provide but following is a recommended workflow.

  1. On old-server: take database dump using mysqldump command. (see example above)
  2. On new-server: Use rsync to move wordpress files & mysql backup to new server.
  3. On new-server: restore mysql from backup and make changes to WordPress wp-config.php (if needed)

Rsync Example:

rsync -avz --human-readable --progress [email protected]:/path/to/www-on-old-server /path/to/www-on-new-server

Using ncftp (fast enough)

If you do not have shell access to server, then most likely you will have FTP access only.

Mostly, I see people downloading from old-server to local-machine and then uploading from local-machine to new-server. This can be slow like hell depending on your Internet connection speed. We recommend using ncftp tool to move files from old-server to new-server directly!

On new-server, if you have SSH access…

Run following commands…

apt-get install ncftp 
cd /var/www/example.com/htdocs/
ncftpget –R –v –u "USERNAME" old-server-ip /path/on/old-server

If you do not like ncftp or face issues with it, you can try wget:

cd /var/www/example.com/htdocs/
wget -nc -r ftp://oldserver.com/path/on/old-server  --ftp-user=olduser --ftp-password=old-pass

On new-server, if you do NOT have SSH access…

You can use ncftp for recursive upload as well. Trick is to install ncftp on a third-server with SSH-access and then download/upload content from there. Unless you have a server hosted on your home-machine with average Internet speed, server-to-server file upload and download are very fast.

Sample commands are like below:

cd ~/tmp/example.com/
ncftpget –R –v –u "USERNAME" old-server-ip /path/on/old-server
ncftpput –R –v –u "USERNAME" new-server-ip /path/on/new-server

There is wput for wget but I never tried it. As we keep moving things all the times, it helps us to have ncftp in our toolbox!

Setup old-server as transparent proxy to new-server (Step #9)

Once your new-server goes live, you may still some traffic to old-server. Most common reason for user seeing old-sites is local DNS cache’s which you can not control or flush at will!

In such cases, we setup old-server to proxy entire traffic it gets to new-server. Codes/configuration for the same depends on web-server software running on old-server. Still, below are common code-snippets we use for 2 popular servers we deals with frequently:

Reverse-Proxy code-snippet For Apache:

Please change new-server-ip in following code. You may also need to make some more changes.

<VirtualHost *:80>
     ServerName  example.com
     ProxyPreserveHost   On
     ProxyPass   /   http://new-server-ip/
     ProxyPassReverse    /   http://new-server-ip/
</VirtualHost>

Reverse-Proxy code-snippet For Nginx:

Please change new-server-ip in following code. You may also need to make some more changes. If you’re using EasyEngine v4, you need to modify $nginx_config_root/conf.d/main.conf. You can find the location of nginx config root in site filesystem documentation.

    location / {
        proxy_pass http://new-server-ip ; 
    proxy_redirect      off;
    proxy_set_header        Host            $host;
    proxy_set_header        X-Real-IP       $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
   }

In all cases, do not forget to reload server-config on old-server. If you’re using EE4, you need to reload your site’s nginx. Also by altering your own /etc/hosts file, check if old-server is proxying traffic properly to new-server.

At this point, you will be shocked to see that old-server may get traffic even after 1 week since you have updated DNS records! Its fine. You can keep old-server proxy up and running as long as you wish. You can add caching layer e.g. nginx’s proxy_cache to cache response from new-server!

That’s All! If you find any mistake, please let me know.

Recommended: Try Nginx for your new WordPress setup

9 responses to “Moving WordPress To New Server (Faster)”

  1. For the database aspect of it, I find it easier to use phpmyadmin’s database synchronization feature. It works well, and it verifies the contents. This eliminates room for corruption. Although just checking the checksums before and after transferring the database dump could also eliminate corruption, it’s still an added step.

    You just have to make sure that you have both databases configured in your phpmyadmin environment. I typically have all my databases in one phpmyadmin environment for easy management, so that part is already setup for me. I do this often between my dev and prod environments for multiple clients.

    Great post though. Much appreciated. FYI: I love your nginx helper plugin.

    • @Vishal

      First, you don’t need phpMyAdmin for database synchronization. Its mysql feature and can be used without phpMyAdmin.

      Next, on cheap shared hosting, generally from where people move to virtual/dedicated-servers, I don’t think a user is allowed to tweak mysql config to allow synchronization.

      We use mysql synchronization only when we need to connect multiple machines in a cluster (most likely behind a load balancer).

      Glad to know you liked nginx-helper plugin. 🙂

  2. Nice articles — all of them. I’m just reading through, and would only point out that Step 7 in the Workflow above (updating DNS) can take a long time to complete, unless you reduce the TTL of your DNS records well beforehand. If you want your change to take effect quickly, put TTL to 60 secs or something less than an hour. Then, when you update DNS, your users will soon get the new address for the new server quicker. Then, afterwards, turn your TTL backup.

    If you don’t do this, you risk having new users hit your new server, while regular users may well hit your old server for awhile and make comments (or create other content) that will no longer be there once they start using the new site.

    Thanks again; I’ll be making use of these articles real soon for a big WPMU install we have that has a couple hundred blogs in it.

    • @Neal

      Thanks for great point. 🙂

      I personally modifies TTL values but forgot to add it here. Apart from that we proxy traffic from old-server to new-server (in case we have control over old-server’s config). That way, users with long intermediate/local DNS-caches, interact with new-server even though they hit old-server. I will add this point also.

    • Updated article with a new section: “Setup old-server as transparent proxy to new-server (Step #9)”

      Thanks for helping me improve this post! 🙂

  3. from last few days I was trying to move my blog to vps server which has virtualmin as cp . But every time i fail to do so , even my premium plugin backupbuddy was unable to migrate my blog . but using your technique i migrated my blog successfully thnaks

  4. There’s a much easier way to get the DB from the old server to the new – (requirements: both servers have SSH access, you created a new DB on the new server already)

    SSH to the new server and execute:

    ssh [email protected] mysqldump -u mysqlusername -pPASSWORD –opt olddatabasename | mysql -u mysqlusername -pPASSWORD newdatabasename

    Best, chris

  5. Hello,

    I’ve set up a wp site on quarantine server (for sanitation and up gradation) and i had to change the base url as this site is live from a different server and i pick the code from this server. Is it possible to set the website without changing its basic URL and without hampering the production?