How to Move or Clone a Single Site or Multi Site WordPress Installation

If you ever have the need to move a WordPress site or a network of WordPress sites to a new server, it can be an outright frustrating task due to all of the settings and data that get accumulated over time. This article is written to be a quick reference for this seemingly daunting task. Eventually I may turn this article into a script to automate the process [EDIT: I have done this successfully] – and/or maybe even a WordPress plugin. If you think this would be useful, feel free to let me know.

Follow through these steps and you might have WordPress up and running on a different server in 30 minutes depending on the size of your data.

Back Up Database

In order to move your database to the new server, you’ll want to do a database dump. A database dump is a file where all of the information from a database is stored into multiple queries. When you import the dump file into the new database server, these queries are executed one by one until the database is built.

Dump the database

mysqldump -v -u root -h database.blog.com --database my_wp_db --skip-lock-tables > my_wp_db.sql

Copy the database dump to the new web server

Because this article is not intended to help you actually set up a web server, it is expected that you have already configured the new database server to allow access from the new web server. After the database dump is complete, you should see a file called my_wp_db.sql in your current directory. Copy the .sql file to the new WordPress server.

scp -i ~/.ssh/your_private_key ./my_wp_db.sql root@my_new_server.com:~/

Change the domain name in the MySQL dump file

Using sed, you can execute one command and it will modify a whole entire file without even opening it.

sed -i 's/my_old_server.com/my_new_server.com/g' ./my_wp_db.sql

Import the database dump file into the new database server

SSH into the new web server

ssh -i ~/.ssh/your_private_key root@my_new_server.com

Import the database dump into the new database server

mysql -v -u root -h new.database.blog.com -p < ./my_wp_db.sql

Copy WordPress Files

The easiest way to make a clone is to do a direct copy of the whole WordPress file system (rather than downloading a new WordPress installation and installing it from scratch).

I keep my WordPress installation in /var/www/ on the server, so here’s what I did to move the files to the new server (as the root user):

tar -czvf ~/wordpress.tar.gz /var/www
scp -i ~/.ssh/your_private_key ~/wordpress.tar.gz multisite.blog.com:/var/www/
exit
ssh -i ~/.ssh/your_private_key root@multisite.blog.com
cd /var/www
tar -xzvf ./wordpress.tar.gz
mv ./www/* ./

File Modifications:

Open wp-config.php and change the following lines to match the database credentials for the new database server:

/** MySQL database */
define('DB_NAME', 'my_wp_db');

/** MySQL database username */
define('DB_USER', 'my_database_username');

/** MySQL database password */
define('DB_PASSWORD', 'my_database_password');

/** MySQL hostname */
define('DB_HOST', 'database2.server.url');

Scroll down through the file and find this line a bit further down…

/** Domain Name */
define( 'DOMAIN_CURRENT_SITE', 'multisite.blog.com' );

Plugin Modifications

If you have domain mapping enabled on the production server, but are only testing on the new server, you will probably want to disable any domain mapping. You will know if you have domain mapping if a CNAME’d mywordpress-site.com brings up mywordpress-site.multisite.blog.com.

DNS Modifications

In order for WordPress to serve any sub-domains in the multi site instllation, you will need to add a couple of DNS records so that they point to the new WordPress server. In this case…

domain = blog.com

// create a DNS "A" record called "multisite" and point it to the IP address of the server
[A] multisite => 192.168.0.100

// create a wildcard DNS "A" record with an asterisk, a dot, and multisite
[A] *.multisite => 192.168.0.100

In the end, you will have two DNS A records:

multisite.blog.com
*.multisite.blog.com

Apache Wildcard Host

In your Apache host configuration file (usually /etc/apache2/sites-available/000-default (or sitename.conf) or at the bottom of /etc/apache2/httpd.conf or /etc/apache2/apache.conf, you’ll want to make sure that you have the following:

ServerName mulsite.blog.com
ServerAlias *.multisite.blog.com

The above lines tell apache to respond to anything.multisite.blog.com

Done

Now that you have made it through these steps, try out your new WordPress site. If you notice that I missed anything, or if I did something that doesn’t look right, please make a comment below and let me know.

9 Replies to “How to Move or Clone a Single Site or Multi Site WordPress Installation”

  1. Kris- I’ve used the sed technique to good success, but I have two questions-
    Have you had an issue with post scheduling? I’m finding that scheduled posts don’t fire off correctly with installs I’ve used sed to do the domain translation on.

    Also- I was worried there would be an issue with serialized php variables stored in the dumpfile if the translation values are different character lengths. Is this something to be concerned about?

    1. I don’t personally use scheduled posts, but I have seen issues with them where they don’t fire off on time. If you are using multi-site, there is a plugin which is made to assist with that. Check out the WordPress plugins site.

      I haven’t experienced any serialization issues with changing info w/ sed, but if you are concerned, there is some logic to the serialization which you can figure out and modify in the database.

  2. Just wanted to follow up that the sed command up there you posted absolutely rules. It does work for me and saves so much time.

    I really can’t thank you enough.

    My environment is os x (10.8) and I couldn’t use the -i option, but rather had to specify the input file > output.

  3. That’s very cool. Will it also work with a multisite subdirectory install? That’s the problem I’m trying to tackle. I’m thinking I may still have to muck with the database.

    1. I imagine it should work with sub-directories… All you’re really doing is cloning the file system and database – so nothing really changes but the URL and the server it’s on.

  4. Thanks for your kind words, feshin. Typically you use a domain mapping plugin to map a domain do a blog ID. You use a CNAME record to map that domain to the default domain.

    I have updated the tutorial above so that now you don’t even need to make any MySQL queries; all of the edits are now done directly in the MySQL dump file.

  5. Hi Kris–

    This is a huge help. Thanks a ton for the article.

    I’m working on migrating a multisite from one domain to another and I’m thinking I also need to update the wp_n_options tables as well as the wp_n_posts table (in terms of inserted images/files).

    Currently I’m having to add a line for each individual blog like this:

    update wp_1_options set option_value=replace(option_value, ‘http://olddomain/’, ‘http://newdomain/’);
    update wp_2_options set option_value=replace(option_value, ‘http://olddomain/’, ‘http://newdomain/’);
    update wp_etc_options set option_value=replace(option_value, ‘http://olddomain/’, ‘http://newdomain/’);

    The more efficient way would be to use a wildcard for the blog id’s, but I don’t think that’s possible. Do you have any guidance?

Comments are closed.