Yesterday I migrated an entire database from one WordPress installation to another, a process somewhat complicated by the fact that the source WordPress environment was older than and differently configured to the target. Perhaps I should have exported and imported the posts, and left the target configuration untouched. wp-cli makes that pretty easy too.

First, though, I think it’s time I confirmed that all is well with my setup by throwing it all out and starting again. It’s a good idea to always be building – otherwise, things tend to get baked in and you become scared to upgrade or change stuff too much.

So I’ve zeroed my WordPress directory. I’m going to start by dumping the database just in case.

$ ./vendor/bin/wp --path=site/wp db export
Success: Exported to 'getinstance.sql'.

Now I have a backup, I’ll clear it down completely.

$ ./vendor/bin/wp --path=site/wp db reset
Are you sure you want to reset the database? [y/n] y

Time for a fresh git clone.

$ git clone getinstance
Initialized empty Git repository in /var/www/getinstance/.git/
remote: Counting objects: 275, done.
remote: Compressing objects: 100% (261/261), done.
remote: Total 275 (delta 17), reused 178 (delta 3)
Receiving objects: 100% (275/275), 12.29 MiB | 4.89 MiB/s, done.
Resolving deltas: 100% (17/17), done.

To get a rough idea of the state of the files and directories I’ve cloned here, it might be worth checking day five in which I described my git repository. Since then I have temporarily added the Twenty Seventeen theme and, more permanently, a child theme named twentyseventeen-gi-child. I have also tweaked the bin/ script a little, adding a couple of wp-cli calls – one to set up the permalink structure, and another to activate the theme:

# set rewrite structure (see day 13)
./vendor/bin/wp rewrite structure /%postname%/ --path=site/wp
./vendor/bin/wp theme activate twentyseventeen-gi-child --path=site/wp

So now I’ll run the script:

./bin/ \
    getinstance \
    getinstance \
    123456789 \ bob \ \

Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Generating autoload files
Success: WordPress installed successfully.
Success: Updated 'siteurl' option.
Success: Rewrite rules flushed.
Success: Rewrite structure set.
Success: Switched to 'getInstance child' theme.

Surely, it can’t be as easy as that? I’ll fire up the browser and take a look:


Well, that was painless indeed!

Time to head back to my source WordPress environment and export its posts and pages. This is as easy as:

$ wp export
Starting export process...
Writing to file /var/www/getinstance/htdocs/getinstance.wordpress.2016-12-14.000.xml
Success: All done with export.

There are many options you can add to the export command which allow you to filter the types and dates of posts. But I want the lot so I can keep it simple. The data is exported in XML format. Now I just need to copy the output file across to my development server and run a couple of commands.

Importing requires a plugin: wordpress-importer. Up until now I’ve installed plugins using Composer. But since this is a one-off requirement, I’ll use wp-cli for it.

$ ./vendor/bin/wp --path=site/wp plugin install wordpress-importer --activate
Installing WordPress Importer (0.6.3)
Downloading install package from
Unpacking the package...
Installing the plugin...
Plugin installed successfully.
Activating 'wordpress-importer'...
Plugin 'wordpress-importer' activated.
Success: Installed 1 of 1 plugins.

By using the --activate flag, I’m able to install and activate my plugin with a single command. Now that my WordPress environment is properly configured I can run the import:

$ ./vendor/bin/wp --path=site/wp --authors=create import getinstance.wordpress.2016-12-14.000.xml 
Starting the import process...

Processing post #1 ("Hello world! (Inevitably)") (post_type: post)
-- 1 of 59 (in file getinstance.wordpress.2016-12-14.000.xml)
-- Wed, 14 Dec 2016 20:19:05 +0000
-- Imported post as post_id #3
-- Added terms (1) for taxonomy "category"
-- Added post_meta default_thumbnail


Processing post #269 ("migrated") (post_type: attachment)
-- 59 of 59 (in file getinstance.wordpress.2016-12-14.000.xml)
-- Wed, 14 Dec 2016 20:19:19 +0000

  All done. <a href="">Have fun!</a>

  Remember to update the passwords and roles of imported users.
Success: Finished importing from 'getinstance.wordpress.2016-12-14.000.xml' file.

Notice that I used the --authors flag. This is mandatory, and it determines how ownership is handled. Because I chose create, any authors associated with posts will be added to the system. And that’s it! I’ve installed all my getInstance posts. To prove it, I’ll show you a screenshot – but for the sake of the look of the thing I’m going to delete my first post (that is the default Hello World article).

$ ./vendor/bin/wp --path=site/wp post delete 1
Success: Trashed post 1.

And here’s my newly installed and populated blog!