Docker the Hard Way: Part 2
In a previous article, I specified the problem to orchestrate creation of two containers, WordPress and MySQL 7.2, using the
docker command. Some minimal features were to use persistent store for the database called
db_data, and allow for alternative port than the default
This is the solution to that problem challenge.
The Solution in Shell
This is the full solution in POSIX shell programming using Bash:
In case some are new to either shell programming or Docker, here are some details about the code.
The first step is to specify some variables I use through the script, and default
8080, if it is not set in the environment:
Create Persistent Volume Resource
We need to create a volume that will persist after reboots for the MySQL server:
docker volume create -d local --name $MYSQL_VOLUME
Create Network Resource
Now we create a network for these containers to use to communicate with each other. As this particular docker command is not idempotent, we have script around it to avoid errors:
docker network list | grep -q $NETWORK_NAME || \
docker network create $NETWORK_NAME
Deploy MySQL Container
docker ps -f name=db -q | xargs docker stop && \
docker ps -f name=db -aq | xargs docker rm
Now it is safe to run the container, run it:
docker run -d \
-v $MYSQL_VOLUME:/var/lib/mysql:rw \
-e MYSQL_ROOT_PASSWORD="wordpress" \
-e MYSQL_PASSWORD="wordpress" \
-e MYSQL_USER="wordpress" \
-e MYSQL_DATABASE="wordpress" \
--name "db" \
We will tell docker to use our volume
db_data and mount it at
/var/lib/mysql. We also want to run the container on the same network using
The MySQL 5.7 image has built-in automation to create a user, user password, and database owned by that user, along with the root password, all by using environment variables sent to the container and launch (deploy) time.
Deploy WordPress Container
We stop and remove the WordPress container, should it be running:
docker ps -f name=wordpress -q | xargs docker stop && \
docker ps -f name=wordpress -aq | xargs docker rm
Now, we can safely start the WordPress container on the same network as
wordpress_net and map it’s internal port
80 to a port we specify (or the default of
docker run -d \
-p "$WORDPRESS_PORT:80" \
-e WORDPRESS_DB_HOST="db:3306" \
-e WORDPRESS_DB_PASSWORD="wordpress" \
--name "wordpress" \
WordPress has some built-in automation using environment variables. Using the env
WORDPRESS_DB_HOST, we can specify the database host address and database TCP port, in case it is different from
The environment variables
WORDPRESS_DB_NAME will default to
wordpress if not specified. The
WORDPRESS_DB_PASSWORD will need to be specified explicitly.
These environment variables will then be used to configure the WordPress app, i.e.
Some takeaways for Docker:
- Creating a volume resource and a network resource for containers to use.
- Launching containers using deploy time configuration with environment variables.
- Mapping remote port (from private container network) to host port
For shell scripting, in case you are unfamiliar with these: