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 user@example.com:/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