Bash Scripting of Docker with WordPress
When you use Docker, the commands that you need to type can be numerous. Some of them don’t change between projects like using docker compose to start and stop your containers. There are others that are specific to the images. For example, I’m using Docker to manage a WordPress development site. I’ve added WP-CLI, which is an administrative developer tool for managing a WordPress site from the command line. My solution was to do some Bash scripting of Docker with WordPress.
The Bash Script
The code needed could be written as an executable Bash script that is located in your system PATH. However, that wasn’t necessary for my purposes. I only needed to create a Bash function that is loaded by my ~/.bashrc file when opening my terminal. I called my function dot:docker. The prefix dot: is just a convention I use to identify it as being part of my personal dotfiles project. Since I’m dealing with multiple services, I’m using docker compose. There are two obvious actions needed to run any Docker project – to start and stop the containers. So we do the simplest thing possible with this script.
function dot:docker {
local opt
opt="$(opal:str_trimmer "$1")"
case "$opt" in
"start" )
docker compose up --detach
;;
"stop" )
docker compose down
;;
*)
message="$(opal:str_trimmer "You have chosen poorly. \
Try using one of these: start, or stop.")"
opal:failure "$message"
;;
esac
}
Note: The function opal:str_trimmer is just a function from the Opal project that expands on the standard trim function by replacing multiple whitespace characters within a string, with a single space. The opal:failure displays the message in red text, to make it stand out to the user.
When I run dot:docker start will bring up the containers that are defined in the compose.yaml file. Running dot:docker stop will stop and remove the containers. This is a small layer of abstraction that reduces the amount I need to type, which all gives me less to think about.
Sometimes, it’s useful to be able to explore inside the container of your services. To keep things simple, I’m using the name bash to run this docker compose exec -it wordpress bash to provide a bash shell. Once you’re inside, you’ll be much more limited in the commands that you can run than to which you’re accustomed.
You might also want to get of list of what’s being used. So let’s use the name list as our label for the commands(s) we want to run. This is where you have some discretion. So what do you want to run. Perhaps you’d like to run docker container list to get a list of the containers you’re currently running. You may want to run docker compose ls for a list of running compose projects. Running docker compose images will list images used by the created containers. Similarly, running docker compose volumes will list volumes by the created containers. Now that you know what they do, which of them would you like to use? Let’s go nuts and use all of them! To make thing a little nicer, and some titles to identify each section.
Here’s the updated script
function dot:docker {
local opt
opt="$(opal:str_trimmer "$1")"
case "$opt" in
"start" )
docker compose up --detach
;;
"stop" )
docker compose down
;;
"bash" )
docker compose exec -it wordpress bash
;;
"list" )
opal:label "List of running Docker Containers"
docker container list
opal:spacer
opal:label "List of running Compose Projects"
docker compose ls
opal:spacer
opal:label "List of Images used by the running containers"
docker compose images
opal:spacer
opal:label "List of Volumes used by the running containers"
docker compose volumes
;;
*)
message="$(opal:str_trimmer "You have chosen poorly. \
Try using one of these: start, or stop.")"
opal:failure "$message"
;;
esac
}
The opal:label function displays the text in bold yellow color to make it more visible. The opal:spacer function adds a number of blank lines to create vertical space. By default, it creates a single blank line.
There’s just one thing left to do. That’s add the star of the show – WP-CLI. In my compose.yaml file, WP-CLI is a separate service but it works together with the WordPress Service. Unlike the docker commands above, where the commands are known ahead of time, we’re going to pass ad hoc commands to WP-CLI container. The list of commands supported by WP-CLI is extensive.
The block we create for WP-CLI only needs two commands. They work together to pass along your command through to the container. For future convenience, the name of the variable $wpcli_service holds the name of of the service you named in your compose.yaml file.
Here they are
shift
docker compose run --rm $wpcli_service --allow-root $@
Consider how we call our function: dot:docker wpcli core version. The values passed in are wpcli core version and they are usable individually via their positional variable, $1, $2, and $3, respectively. They can also be treated as a unit with the $@ array. In the case statement the variable $opt has the value of $1 which is wpcli. Once we get down of the wpcli block, we don’t need that value anymore. By using shift, it gets thrown away. This makes the $@ array one item shorter. so now it contains core version . This is exactly what we want the WP-CLI container to run for us. So we just pass it along on the end of the docker compose run . Let’s see it all put together.
function dot:docker {
local opt
local wpcli_service
# The WP-CLI service name must match the service name in your compose.yaml
wpcli_service=wpcli
opt="$(opal:str_trimmer "$1")"
case "$opt" in
"start" )
docker compose up --detach
;;
"stop" )
docker compose down
;;
"bash" )
docker compose exec -it wordpress bash
;;
"list" )
opal:label "List of running Docker Containers"
docker container list
opal:spacer
opal:label "List of running Compose Projects"
docker compose ls
opal:spacer
opal:label "List of Images used by the running containers"
docker compose images
opal:spacer
opal:label "List of Volumes used by the running containers"
docker compose volumes
;;
"wpcli" )
#
# Pass the supplemental arguments straight trhough to WP-CLI
#
shift
docker compose run --rm $wpcli_service --allow-root $@
;;
*)
message="$(opal:str_trimmer "You have chosen poorly. \
Try using one of these: start, stop, wpcli, bash or list.")"
opal:failure "$message"
;;
esac
}
Wrap Up
That’s it in a nutshell. If you forget to pass an argument, or don’t pass one that matches, you’ll end up at the end of the case, displaying the error message. You may want to call other docker compose commands. It all depends on what you’re trying to do. One idea you might want to consider is the ensure that the $@ has a value in it after the shift and before you try to pass it through. Or maybe you want to thin down the list block of code, to reduce the number of commands that gets run. Either way, use this function as a starting point for your next Docker project.
