Using wp-cli with Docker

Earlier this week, I posted a tutorial on how to setup a local WordPress environment using Docker. If you read that, then this post will serve you well.

When you’re finished, be sure to check out my post on some helpful docker commands for cleaning up your dev environment.

Many of us use wp-cli to manage our WordPress installations. If you are using Docker to manage your local development, then you are probably wondering how you can leverage wp-cli since your container is now a virtual environment. People are still not used to using Docker, and so the idea of using it to manage your cli tools is still a bit confusing. Thankfully, I have already done the work for you!

If you benefit from this tutorial or you’d like to add to the conversation, be sure to hit me up on Twitter and I’ll get back to you.

The Quick and Dirty

Before you use the following snippet, be sure to checkout the first snippet.

https://gist.github.com/tatemz/fd745b4e48629255b4a158fa2c0667df

Let’s dive into more detail…

Setting Up docker-compose

If you followed my last post, you will have a docker-compose.yml file that looks like this inside of your WordPress directory:

my-wpdb:
image: mariadb
ports:
- "8081:3306"
environment:
MYSQL_ROOT_PASSWORD: ChangeMeIfYouWant

my-wp:
image: wordpress
volumes:
- ./:/var/www/html
ports:
- "8080:80"
links:
- my-wpdb:mysql
environment:
WORDPRESS_DB_PASSWORD: ChangeMeIfYouWant

Let’s add a wp-cli container to our stack…

my-wpcli:
image: tatemz/wp-cli
volumes_from:
- my-wp
links:
- my-wpdb:mysql
entrypoint: wp
command: "--info"

A few new things are new here since the last time:

  • First, we are telling this container to use the same synced volumes as our my-wp container (/var/www/html to be exact). This way, wp-cli has access to our WordPress files.
  • Additionally, we are linking the my-wpdb container to it in order for wp-cli to share access to the database. If you remember from our last post, this is assigning an alias to the my-wpdb as “mysql” — this is the same as the “DB_HOST” constant in the wp-config.
  • Lastly, we are overriding the default entrypoint and command this container will execute on startup. Since my custom tatemz/wp-cli container inherits functionality from the wordpress container, the default command that starts Apache will be fired. In this case, our entrypoint will be the “wp” command and the subcommand that we want to run is the “--info” command. On starting our my-wpcli container, it will quickly close after printing the output of the “wp --info” command.

Docker containers are most often just tiny, simple, linux servers. Therefore, if a command is run that does not exit, the Docker container will stay online. However, if a command exits, the container will halt. You can always check which containers are running on your machine:

$ docker ps

Now we are all set to run wp-cli commands…

Running Commands with docker-compose

We need to leverage our my-wpcli container that we added to our stack in order to only run one-off commands. In other words, we don’t need my-wpcli to run as a service — only as a cli tool:

$ docker-compose run --rm my-wpcli

Let’s break that down: the “run” command tells docker-compose to spin up your container and run a customizable command. Firstly, any arguments we pass to docker-compose must appear before the container name. In our case, we are only passing --rm as an argument; this simply removes the container right after it finishes the “wp --info” command. If we did not do this, we would create an orphaned container.

$ docker-compose run --rm my-wpcli

Anything that would come after the container name would override the “command” setting that we set above. In this case, the default is “--info”, but we can override it to something useful like this:

$ docker-compose run -rm my-wpcli post list

This is the same as running the following wp-cli command

$ wp post list

To make the process easier, we can store this command as an alias:

$ alias wp="docker-compose run -rm my-wpcli"
$ wp post list

Now we are flying with our alias!

$ wp core install --url="localhost:8080" --title="WordPress" --admin_user="admin" --admin_password="prollynotadmin" --admin_email="admin@email.com"
$ wp user create jimmy jimmy@email.com --role="administrator"
$ wp media regenerate -y
$ wp search-replace localhost:8080 productiondomain.com
$ wp db export site-dump.sql

A Simpler Way

I chose to expand my explanation in order to show you how to work with docker-compose in order to run one-off commands, however, our stack is now larger because of that. Since my tatemz/wp-cli container image inherits functionality from the official wordpress container, we can simplify this whole process by changing our my-wp stack to use my custom image:

my-wp:
image: tatemz/wp-cli
volumes:
- ./:/var/www/html
ports:
- "8080:80"
links:
- my-wpdb:mysql
environment:
WORDPRESS_DB_PASSWORD: ChangeMeIfYouWant

Since we are not overriding the “entrypoint” or the “command” settings, the default startup script will run and initialize Apache. Like in the previous post, let’s start our stack.

$ docker-compose up -d

Once our stack is up, we can now execute commands inside the running containers rather than creating a new one and destroying it after it exits.

$ docker exec my-wp wp post list

Did you benefit from this tutorial? Leave me a comment below or on Twitter.