Skip to content

How to Run WP-CLI Commands on a Remote Server

This weekend at WordCamp Minneapolis I presented an introduction to the power of WP-CLI, a tool that allows you to manage your WordPress website from the command line.  I’ve given this talk several times now, but am always looking for cool new features to include.

This weekend’s addition to my talk was the ability to run WP-CLI commands from my local machine against a remote site…. which is very cool, and saves even more time.

The Old Way

  1. SSH into Remote Server
  2. Change Directory to where my WordPress Site is installed
  3. Execute WP-CLI command.

The New Way

  1. Execute WP-CLI Command

Step 1: Setting It Up

  1. In order to run commands remotely, you need to install WP-CLI on both the computer you want to run the command from and the server on which your site is located.
  2. I would also recommend setting up passwordless-ssh on your server  so that you don’t need to enter your password every time you run a WP-CLI command.

Step 2: Execute the Remote Command

The trick to running commands on a remote server is the –ssh option.  Adding this option to any command will tell it to SSH into the remote server and execute the command there.  For example, running

wp --ssh=shawn@example.com/var/www/html/ plugin list

would be the same as connecting to example.com via SSH using the username shawn, changing directories to /var/www/html/ and then running the wp plugin list command.

Optional: Aliases

Adding that SSH flag to every command does seem a little tedious though.  “There has to be a better way!” you demand.  Well, there is: aliases.  WP-CLI allows you to configure some global parameters in a file called wp-cli.yml.  Aliases are one of these features – they allow you to setup friendly names that represent your remote environments.  Here’s an example of the wp-cli.yml file I use.

wp-cli.yml (placed in the root of my site, in the same location as the wp-config.php file)

1
2
3
4
5
6
@test:
     ssh: shawn@test.example.com/var/www/html/
@staging:
     ssh: shawn@staging.example.com/var/www/html/
@production:
     ssh: shawn@example.com/var/www/html/

With this file in place, I can now execute commands using the alias.   If I wanted to get the list of plugins on my staging server, I can now type:

wp @staging plugin list

Much nicer, right?!

Even More Power: Multiple Aliases at Once!

You can also configure groups of aliases in your wp-cli.yml file.

wp-cli.yml (placed in the root of my site, in the same location as the wp-config.php file)

1
2
3
4
5
6
7
8
9
@test:
     ssh: shawn@test.example.com/var/www/html/
@staging:
     ssh: shawn@staging.example.com/var/www/html/
@production:
     ssh: shawn@example.com/var/www/html/
@prerelease:
 - @test
 - @staging

In the above file, I’ve now stated that the alias @prerelease is a group that contains both of our previously defined @staging and @test aliases.  So I can execute a command like this:

wp @prerelease core update

and update the version of the WordPress Core on both staging and test servers in one command.

There is also a built in @all alias. Executing:

wp @all core update

would execute this command on all defined aliases (in the example above: test, staging and production).

The Database Migration Example

The example of using this command that I demoed at WordCamp Minneapolis this weekend was the ability to update the database on my staging server with the data from my production server, using WP-CLI. Using the above configuration, and a little knowledge of piping commands together in bash, we can execute a command like this:

wp @production search-replace example.com staging.example.com --export | wp @staging db import -

(you might need to scroll to read the entire command)

In one line of code, this command:

  1. Connects to production (using an alias)
  2. Does a search and replace on my production domain name, replacing it with the staging domain name
  3. Exports those results to STDOUT (instead of to a file)
  4. Connects to staging (using an alias)
  5. Imports the production data using input from STDIN ( the hyphen after import ), using the data from the production export.

Cool, right?

Now, as I pointed out in the session, this command only moves the database, and not any of the media library, plugins, etc. In my particular use case, where my assets are stored in Amazon S3 buckets with Delicious Brains’ S3 Offload Plugin, this solution is all I needed.

12 Comments

  1. Hey Shawn!

    Great article. Very nice database transfer example. Just to be clear – STDOUT will be on the local computer where the command is originally executed, right? So production transfers the db to STDOUT locally and then uploads back to staging where it’s imported? So good for smaller websites but for larger databases it would be very bandwidth intensive?

    • Absolutely Phill. For a large database, I would run this command from the staging server (or whichever environment was the “destination”) in order to avoid the doubling of the bandwidth. This would mean setting up the wp-cli.yml file on either the source or destination server.

      • Doh. Of course! That makes much more sense than running the wp-cli command in a local dev environment and doubling the bandwidth 🙂

  2. dawninkmsllc dawninkmsllc

    Thanks for this article. We are looking for a replacement for WordShell. We used to use a script WordShell that would let us use something like @all and then loop thru multiple (25+ in our case) WordPress accounts and update each up. Very powerful . I am not familiar with WP-Cli but now that WordShell is coming to its end of life could something like WP-Cli and @all be used to go thru each site, upload and active a plugin?

    • I’m not familiar with WordShell, so I can’t comment specifically on it. But you could definitely setup a script with WP-CLI that would connect to all your client sites and install/update a plugin! Take a look at the command: wp plugin install –activate. The can be a slug from a plugin in the WordPress.org repo, a zip file path on the site’s server, or a URL to a plugin zip file anywhere on the web.

  3. Thank you for this tutorial. I’m new to WP-CLI and wonder what else is possible to do with it? Can you move WordPress files from your localhost WP installation to a live website using it, too?

    • Hey Gavin,

      You’re right! I’ve updated the post to reflect this. Thanks.

  4. peter@pixelliquid.com peter@pixelliquid.com

    Good article. Followed the steps, but the only annoying thing is that I keep getting the error “Cannot connect over SSH using provided configuration”. The first time I got this: “The authenticity of host … … Are you sure you want to continue connecting(yes/no)?” I opted for yes, of course. Then it was just the “Cannot”-error.

    When I login manually I need to type in the passphrase. Where do I put this in the wp-cli.yml file? In the section Aliases there is only place for user, url, path, ssh, http.

    • I don’t believe you can place your password in the wp-cli.yaml file, which would be extremely insecure anyway. The best bet is to configure passwordless SSH from your computer to your server. Here’s a good article from DigitalOcean explaining how to set that up: https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys–2

      I believe that’s the cause of the “Cannot connect” error you’re receiving.

      • peter@pixelliquid.com peter@pixelliquid.com

        Thanks Shawn I’ll check that article asap. The first time I started using ssh with this provider I created a passphrase so that’s probably the culprit.

Leave a Reply

Your email address will not be published. Required fields are marked *