1. Code
  2. WordPress

Using WP-CLI with Mina


In the first part of this series, we were able to use Mina to deploy WordPress. We learned that Mina creates a shell script file, then pushes WordPress to the server to run. Since all commands are run in a single SSH connection, Mina very fast. 

Utilizing this, we can write tasks to automate WordPress control. We can turn normal WordPress tasks such as creating users, installing a plugins, backing up our data, and so on into a sequence of shell commands. Then we combine these shell commands into Mina task. 

But how can we create the shell commands to perform those tasks? WP-CLI is the answer. It helps to control WordPress through command line. You don't need to sign in to the WordPress dashboard to do administration tasks. WP-CLI gives us a set of commands that is corresponding with WordPress admin tasks. Once we know the WP-CLI commands for a special task, we only need to put these commands into a Mina task. 

What Do I Need to Know Upfront?

  • You will need either a Mac OS or Linux OS in order to have access to a terminal. If you are on Windows, it is still possible but it won't be covered in this tutorial. 
  • You should have a very basic understanding of shell commands and the terminal. As long as you've opened the Terminal or iTerm app before, the tutorial should be very easy for you.
  • You need to have SSH access to your remote machine.

A Quick Look at WP-CLI

A very quick example so you can have a task of what we have with WP-CLI. When starting to develop a WordPress site, you have to create dummy posts or dummy user accounts for testing purpose. 

Typing this (once you've installed wp-cli) on your terminal will create you 100 dummy posts without minimal effort.

See how much time it will save you? But do we really need to run these things via command line? 

Saving time is nice, but not a need.

Here is a very good reason to do this: security. Some action from the WordPress dashboard requires write permission to the wp-content folder. Example: uploading plugins,  uploading themes, upgrading WordPress, and so on. The more permission we grant to the public, the more danger we are exposing to our site. 

Let's imagine that an attacker gains access to our WordPress dashboard. The attacker will be able to upload malicious scripts as a plugin. A way to prevent this is to disable write permission to any folder or file of WordPress except the wp-content/uploads folder. Therefore, no one can upload a plugin or theme to web server. 

In first part of this tutorial, we learn to give write privilege to Apache on wp-content/uploads folder. We changed owner ship of wp-content/uploads to the web server user. That way, the web server can write to the uploads folder; therefore, WordPress can upload pictures and write into our uploads folder. 

Any action that requires writing to the WordPress folder (except the uploads folder) should be done via the command line. In other words, we will add the file manually from our local machine, commit, and deploy to server with Mina. With this setup, our WordPress directory becomes a read-only box (except for the uploads folder which is used for storing our media). 

The media upload feature of WordPress already has a security layer to prevent uploading PHP files. If you want to go further, you can config to not run PHP files inside uploads folder, but that's the idea and won't be cover in this tutorial. We will focus more on command line action with WP-CLI.

Update WordPress Without Write Permissions

Once we removed write permission, then the auto update will no longer work, and you cannot simply update the application from WordPress dashboard. Since we have managed our WordPress code with Git, we should do the update manually

We can download the WordPress zip/tar file, uncompress it, overwriting current WordPress file. Next, We commit the new code, push to our repository, and do a deployment with Mina.

A Review of Mina Task Theory

A task in Mina is just a normal Rake task with a queue method that queued the shell commands to run on server later. For any command that we want to run on server, we can use the queue method as following.

The desc block is optional but it's nice to have. If you type mina without any parameter, the desc information will be printed out on screen for your reference.

For any command that we want to run on local machine, we can use the backtick(`) character.

Let's test it with mina sample to see what it prints out on your local machine.

So, basically a Mina task is built by creating a block of task :task_name do //... end
The task can be invoke with mina task_name. If we need to pass argument into the task, then we can use this syntax:

The bracket [] is just the Ruby way to access a hash. You can think of it like PHP associative array. We name the argument, then inside the task body, we can easily access its value with args[:argument_name]. In this example, argument_name is :arg and :another_arg

The task can be invoked with this syntax: mina taskname[param1, param2]. More arguments can be added and we will pass more parameter into it such as mina taskname[param1, param2, param3, param4].

You can imagine that the taskname is a method name and we are calling a method and passing its argument. If the parameter has a space, we should wrap the whole parameter with a quote.

 Let try above task now. It just prints out whatever we pass into it.

If you used zsh shell, you need to escape [ and ] with the backslash:

Another thing to note is the in_directory method of Mina. It's very likely that you will need to cd into a directory and run a couple of commands. Instead of manually queueingcd command, we can use the handy in_directory method. It will run the command inside the directory we indicate.

Okay, enough for theory. Let's start the fun part: We will install wp-cli, then setup a few tasks.

Install WP-CLI

All we need is to download the PHAR file of WP-CLI. It's a single file that is executable to the PHP engine. Instead of having a bunch of PHP files, you can compress them into a single file that is executable by PHP. 

It's a very easy way to distribute PHP packages. Just like on Windows, you download a software in a single .EXE file and run it. To do this, cd into your WordPress code on local machine, run this command:

Let's verify it works. On your local machine, run wp-cli.phar --info and you should get the following output.

Now, wp-cli is in same directory with your WordPress, let's commit it and
push to your repository and do a deployment.

At this point, wp-cli is in our WordPress directory on server. Let's do some magic with it: writing Mina task with wp-cli.

Writing a Mina Task With WP-CLI

In this section, I will show you how to do some basic tasks with wp-cli as well as how to put them into Mina so you can have a taste of how thing look like and go write your own task to match your workflow and your need. First things first: Hello World.

1. Hello World

The very first, very simple command of wp-cli is to show current WordPress version. Let create one more Mina task. Append this to your config/deploy.rb file:

Now, try to run it:

2. Installing a Plugin

We will download a plugin by hand, extract it, add it to repository, commit it, then deploy and run another mina task to activate a plugin. 

Here is the code we need for this task

We queue an echo command to output some text. The command to activate a plugin from wp-cli is plugin toggle plugin_name

For example, say that we want to install the Mathjax Latex plugin, and we already put it in wp-content/plugins

We can install this way:

Now the plugin is installed. Activation can be done via the WordPress dashboard. But since we have our Mina task let try it:

Updating a plugin is just the same procedure. You download the plugin, copy it over to wp-content/plugins/[plugin-need-to-update], commit and re-deploy.

3. Installing a Theme

The workflow is just like how we do with plugin, only a different wp-cli command to activate the theme. We only need to add the theme into Git, commit, push, deploy.

Take a look at the following example in which we will install this theme. We already downloaded and put it into wp-content/themes/natsume.

Again, the theme activating can be done on WordPress admin UI. But let make a Mina task so we can activate it once we deploy it, from the command line. 

Here is the task:

To activate a theme, run our task:

4. Database Backup

This task will dump the WordPress database to a gzip file in shared/backup folder. If the backup folder doesn't exist yet, we will create it, then we call the wp-cli db command to dump the database to a file. 

The file name will be the combination of date and time when we export in this format "[year][month][day]_[hour][minute][second].sql.gz". 

Let's compose our Mina task.

[ -d name ] is a syntax to check the existence of the folder. If not, we use mkdir to create it.
Then, we use Time object of Ruby to extract date and time and concatenate together to create our file name.

When you want to back up, from your local machine, type:

Simple and elegant. One command and you have it all.

5. Update Domain

Very often, when you change the domain, you have to re-config it in wp-config.php, or manually update the domain in database. Either way, it's lot of work. 

Let's just solve this one time. The command to update an option is : wp-cli option update [option_key] [option_value]. According to the WordPress documentation,  the domain is in two options: home and siteurl

So, here is our task:

Invoke it from command line:

6. Generate a Dummy Post

A very handy features of wp-cli is post generation. During testing time, you can find yourself manually creating lots of dummy posts. The command to create post with wp-cli is wp-cli post generate --count=quantity. As always, you can read the syntax yourself on wp-cli website.

We will create a task call gen_dummy_post with a parameter is the number of posts. To get content of post, we will use curl to get a lorem ipsum text via the Loripsum API. cURL is a command line tool which is usually pre-installed on Linux/Mac OS that allows you to send HTTP request.

You can think of it like a browser, but run on command line. So instead of typing an address into your browser, and see the output on your browser, you give cURL an website address, and it returns the website content.

Let's try below command:

So when you run it, five paragraphs of lorem ipsum are returned. You can change the number after /api to get more paragraph.

We know have content, we will feed it into wp-cli to create post. The syntax for doing that is:

Notice the chracter |, it means that we are piping the content into next commad. We know have the syntax, we can start composing the task

Once you knew the syntax of Mina task, you can read more about WP-CLI command to write your own task such as creating user, generate dummy users for testing...

If you want to lean more about wp-cli, you can visit these links:


We are now have a good enough understanding of how to write Mina tasks, how to utilize the power of wp-cli. With the combination these two tools, hope you will deploy very fast, and your WordPress installation will be more secure than before, and reduce the time for administration tasks. 

Don't limit yourself. The information in this tutorial is very brief, please add more things to your task files and let us know what you came up in comment. 

If you have any issue, please leave a comment, I like to help and talk. Happy WordPress automation!

Looking for something to help kick start your next project?