Migrate a Single WordPress site to Multisite WordPress System Using WP CLI


February 18, 2020

Transferring a single WordPress site to a multisite WordPress system can become complicated, especially if you have a large website with many contents and plugins. Here we will see how we can manually transfer a single site using the WP command-line interface. In this document, we assume you have access to the servers hosting your websites and have created a multisite WordPress network, and you are ready to transfer your site.

Getting Started

Backup Eveything

Backup your files and your database:

ubuntu@VM1:~$ wp db --dbuser=<db_username> export db.sql
ubuntu@VM1:~$ tar -C /var/www -zcvf files.tar.gz wordpress 

Copy Files to New Multisite Folder

When you create a new site in multisite WordPress, a corresponding folder for that is created. Assume the WordPress picks up the id 8 for this site; thus its contents are stored in:

/path/to/multisite-root/wp-content/uploads/sites/8

Copy all uploaded contents to the new location:

ubuntu@VM1:~$ cp -rp /path/to/singlesite-root/wp-content/uploads/* \
                     /path/to/multisite-root/wp-content/uploads/sites/8/

Find and Install Plugins

Before you proceed, you have to install and activate all used plugins and themes in the multisite WordPress. To get the list of installed plugins in the single-site WordPress:

ubuntu@VM1:~$ wp plugin list
ubuntu@VM1:~$ wp theme list
# On the mutisite WordPress:
ubuntu@VM1:~$ wp plugin install <name-of-plugin> --activate-network

Export wp-options Table and Contents

Plugins settings and configuration you have made are all stored in the wp-options table. In a multisite environment, each site has its own set of tables. They are distinguished by getting a unique prefix. For instance, wp-options for our target site is became wp-8-options. We first export this table from single-site WordPress:

# To export wp-options table from database
ubuntu@VM1:~$ wp db --dbuser=root export --tables=wp_options ~/wordpress_options.sql 
# To export all posts, pages, menus and etc. into a XML file:
ubuntu@VM1:~$ wp export

Perform Modifications

Now we have two files which we have to perform some filtering on them. In particular, we need to change the path to the contents and the site URL and home URL.

ubuntu@VM1:~$ sed -i 's/wp_/wp_8_/g' ~/wordpress_options.sql 

Open the ~/wordpress_options.sql and change the site URL and home URL to multisite URL in the first line of INSERT TO statement.

Once you finish that, it is time to change some paths on the XML file which contains the contents of your site:

ubuntu@VM1:~$ sed -i 's/<old-url>/<new-url>/g' <xml-file>
ubuntu@VM1:~$ sed -i 's/http:\/wp-content/http:\/\/<new-url>\/wp-content/g' <xml-file>
ubuntu@VM1:~$ sed -i 's/wp-content\/uploads/wp-content\/uploads\/sites\/8/g' <xml-file>

By now, we are almost done. We need to import the ~/wordpress_options.sql and <xml-file> into the database.

Import into Database

ubuntu@VM1:~$ wp db --dbuser=root import ~/wordpress_options.sql 
# On the multisite WordPress perform:
ubuntu@VM1:~$ wp import --authors=usermaps.csv --url=<site-url> <xml-file>

Check the output of the above commands for any failure during the import procedure. If you get some error, look for the corresponding attachments in the <xml-file>. You probably need to correct the paths of a few items. The file usermaps.csv provides a mapping from contents’ authors and the current existing users in the multisite WordPress. It looks like:

ubuntu@VM1:~$ cat usermaps.csv
old_user_login,new_user_login
old-username1,new-username1
old-username2,new-username2

Final Step: Search and Replace

Often times, you will see some images or links which still are using the <old-url>‍‍‍‍‍‍‍. To check the whole database for any occurances:

ubuntu@VM1:~$ wp search-replace '<old-url>' '<new-url>' --url=<new-url> --precise

Although this is a useful tool, however, you can also dump the whole database and replace whatever is needed as well.


WordPress