Docker the Hard Way with WordPress
Orchestrating WordPress-MySQL containers w. Docker command
Recently I was helping a friend get rapidly up to speed in Docker, and developed this small lab, which I am sharing in hopes this might be helpful in your Docker learning activities.
For this lab challenge, you will run a WordPress and MySQL containers, and then use your web browser to point to the container.
Why WordPress
You might ask, why WordPress?
Simply, WordPress is a class multi-tier monolithic web application with dependency to a database. As WordPress is widely used and well known, it has become the gestalt to demonstrate automation, especially for change configuration. This makes it great as a teaching tool to demonstrate docker.
About the Tools Required
Docker consists of many components, but for this lab we mainly focus on the docker client tool, simply called docker
. The docker client will communicate to a docker service running on a Linux server.
Getting Docker on macOS (aka Mac OS X)
You can set all of this up with either Docker Desktop or Docker Machine (or both). If you have Homebrew installed, you can get the components with these commands:
- Docker Desktop:
brew cask install docker
- Docker Toolbox (for Docker Machine):
brew cask install docker-toolbox
Getting Docker on Windows 10
You can set all of this up with either Docker Desktop or Docker Machine. If you have Chocolatey installed, you can install either of these tools with:
- Docker Desktop:
choco install docker-desktop
- Docker Toolbox (for Docker Machine):
choco install docker-toolbox
Getting Docker on Linux
On Linux, you can follow instructions for Docker CE (Community Edition).
The Lab Challenge
The goal of this exercise is to create a shell script (or whatever you would like to use for automating command lines) to automate using the docker
command and do the following below, divided into basic and advanced features.
Once completed, you will have a self executing script (docker_run.sh
, docker_run.py
, docker_run.rb
, or other language, or simply docker_run
) that will run the docker commands to do this.
The script will do this solution completely using the docker
command. You will only need four docker
commands to complete this solution.
Basic Features
For the basics, we simply want to launch the containers:
For the basic features, we’ll do the following:
- Launch MySQL (
mysql:5.7
) with restart policy of always, container name ofdb
, and pass environment variables to the container that will trigger the container’s internal self-configuring automation. - Launch WordPress (
wordpress:latest
) with restart policy of always, container name ofwordpress
, and map the container port80
to a host port of8080
, and pass environment variables to the container that will trigger the container’s internal self-configuring automation.
Advanced Features
For these features, we want to use a private network, have a persistent volume for the database, and allow the user to specify the host port using an environment variable WORDPRESS_PORT
.
For the advanced features, we’ll need to do the following:
- Create a private network
wordpress_net
, and configure the containers to use the private network. - Create a volume called
db_data
, and mount the volume as/var/lib/mysql
in the MySQLdb
container. - For the
wordpress
container, set the host port to the environment variableWORDPRESS_PORT
, and if this is not set, then default it to port8080
.
Further Notes
For this exercise, you do not need to craft any Dockerfile
for either WordPress or MySQL containers. Use the official Docker images mysql:5.7
and wordpress:latest
.
When the script is completed, test the script, by running these tests:
- No port set, test by navigating your web browser to
localhost:8080
, or if Docker Machine is used, use the IP addressed specified bydocker-machine ip
. - Clean Up the running containers (see clean up below).
- Run the script again, but this time with the environment
WORDPRESS_PORT
set to another value, e.g.8888
, and then navigate your web browser to the same address (in step 1) with this port, e.g.localhost:8888
.
Clean Up
To stop and remove the containers, you can the following:
docker ps -f name=wordpress -q | xargs docker stop && \
docker ps -f name=wordpress -aq | xargs docker rmdocker ps -f name=db -q | xargs docker stop && \
docker ps -f name=db -aq | xargs docker rm
If you would like to remove the volume and network, you can run:
docker volume rm db_data
docker network rm wordpress_net
Verifying Solution
If you have the tool Inspec installed, you can use this test case to validate the environment and practice systems level TDD.
Then with the containers running, run:
# run your solution
./docker_run # verify your solution
inspec exec container_test.rb
If you use specified a custom host port with WORDPRESS_PORT
, you can do this:
# run your solution
export WORDPRESS_PORT=8888
./docker_run# verify your solution
echo "port: $WORDPRESS_PORT" > attributes.yml
inspec exec container_test.rb --attrs=attributes.yml
After, you should see something like this:
Until Next Time…
That’s the the lab, and if you are unfamiliar with Docker, this will require some research and tinkering. For those familiar with Docker, this may be a good lab to review commands, and also to compare and contrast to something like Docker Compose, that is easier to use than raw docker commands.
In the next article, I will follow up with a solution, and introduce doing a similar lab with Docker Compose and Ansible as alternatives to interact with Docker service and orchestrate containers.