Taking Docker for a spin

Docker has intrigued me for some time now so I thought I'd take a closer look. Purely in a personal capacity, as until Docker supports Windows containers there are few applications at work.


Let's pick something simple but non-trivial. I'd like to set up an instance of WordPress locally. WordPress relies on MySQL for storage so let's split the MySQL database out into its own container first.

docker run --name db -e MYSQL_ROOT_PASSWORD=example -d mysql

Diagram 1

We can then run the WordPress container and link it to our MySQL container like so.

docker run --name wordpress --link db:mysql -p 8080:80 -d wordpress

Diagram 2

This is all fine and dandy but we need to persist the data beyond the lifetime of an ephemeral container.

We could mount a host directory as a data volume.

docker run --name db -v /var/container_data/mysql:/var/lib/mysql -d mysql

This will mount the host directory, /var/container_data/mysql, into the container at /var/lib/mysql.

A problem with this approach is that it is no longer portable and the data directory is outside the control of Docker.

Data Volume Containers, essentially data-only containers, provide the solution.

docker run -v /dbdata --name dbdata mysql /bin/true

The bin/true command is simply a dummy as docker needs something to run. It's also worth noting that the container doesn't need to be running to be used. Run docker ps -a to confirm that the container has been created.

We can then use this data container from our MySQL container.

docker run --name db --volumes-from dbdata -e MYSQL_ROOT_PASSWORD=example -d mysql

Diagram 3

The data is encapsulated by our data container. Within the data container we could mount a host directory as a data volume. However it feels more Docker-like to let the container manage the data and access it through other containers. See wordpress-backup for an example of backing up and restoring a WordPress install.

If you're curious you can use docker inspect dbdata to pinpoint the location of the MySQL storage directory.

"State": {
    "ExitCode": 0,
    "FinishedAt": "2015-05-11T18:35:01.586748612Z",
    "Paused": false,
    "Pid": 0,
    "Running": false,
    "StartedAt": "2015-05-11T18:35:01.270467585Z"
"Volumes": {
    "/dbdata": "/var/lib/docker/vfs/dir/fa6b72b85c32190da7307764f25888bb63f19e1fa728aeddb8b31b672a46f4ef",
    "/var/lib/mysql": "/var/lib/docker/vfs/dir/b091111b39a9da92883153bcd1ef3f6ae1dd5ac557381a972444e3e18c330d12"
"VolumesRW": {
    "/dbdata": true,
    "/var/lib/mysql": true

Running ls /var/lib/docker/vfs/dir/b091111b39a9da92883153bcd1ef3f6ae1dd5ac557381a972444e3e18c330d12 shows the contents of our MySQL directory.

auto.cnf ibdata1 ib_logfile0 ib_logfile1 mysql performance_schema wordpress