How to Set Up WordPress with Docker Toolbox
Introduction
WordPress is the most popular blogging system written in PHP. According to statistics available on Wikipedia WordPress is being used by 27.5% of the top 10 million sites on the Internet.
For some reason, I wanted to play a little bit with WordPress settings. To do so I could've just installed an Apache/NGINX web server along with PHP, a MySQL database and configure them. That's certainly not that difficult, but I rather wanted to focus on WordPress not dealing with the web server's configuration.
Using Docker seemed to be a very straightforward approach considering there is an official WordPress image here available. Just start the image and everything is up and running. Sounds promising, does it?
Why Docker Toolbox?
The tricky part was that I'm using a Windows 10 Home edition now which does not support the Hyper-V feature. It turns out, Docker for Windows requires the Hyper-V feature enabled. Nevertheless, as a fallback option, we still can use Docker Toolbox.
Unlike Docker for Windows, the Docker Toolbox is not a native approach to run Docker. What it basically does is it runs Docker on a VirtualBox emulated virtual machine. That being said, running CPU intensive applications in Docker Toolbox might suffer from performance issues.
If you have Windows 10 Pro and your CPU supports virtualization then I'd definitely encourage you to use Docker for Windows instead.
But if you happen to use Home Edition, the following installation and setup guide may be useful.
Installing Docker Toolbox
Let's get started! The following steps guide you through the installation process:
-
Download the Docker Toolbox binary from here

-
Once downloaded, start the installer and click through it:





-
Open the freshly installed Docker Quickstart Terminal from the Start menu. This will set up VirtualBox and performs the first time initialization.



-
Important: Docker Toolbox ships with VirtualBox 5.2 by default. Not only this version is a bit outdated, but also for me the bind volumes did not work at all. The solution is to upgrade VirtualBox.
-
In Docker Quickstart Terminal, type the following command to first stop the virtual machine running Docker:
$ docker-machine stop -
Update VirtualBox. Open it and it'll prompt you that it's outdated — use the link from the window to download the latest version:

-
Once you've downloaded and installed the new version, verify the version (Help -> About):

-
-
Reboot your computer. This was a necessary step for me.
That's it, you've successfully installed Docker Toolbox! 🎉
Using WordPress with Docker Toolbox
It's time to install and start WordPress. We'll use the official image supplied here.
Since we want an out-of-the-box solution that includes the database as well, let's rather use the stack.yml file with docker-compose provided on that page.
Create a new directory where you'll work (e.g. c:\wordpress). Then grab the stack.yml from the WordPress image's page and put it in your newly created working directory.
It's time to start the containers:
docker-compose -f stack.yml up
If we run this command for the first time and haven't used the WordPress and MySQL before, it'll then first download these:

Once the assets/ have been downloaded and the containers have been configured, Docker will start them:

Well, the containers have started, but wait a bit. There's a problem as highlighted in the picture above:
wordpress_1 | MySQL Connection Error: (2002) Connection Refused
It looks like the WordPress container is unable to reach the database container. To prove this assumption I executed a ping db command from the WordPress container and it's indeed the case, there's no network between the containers.
The solution for me was to add the following part to the stack.yml file of the wordpress section:
links:
- db
This ensures the db container should be available for the wordpress container through an internal network.
Execute the docker-compose -f stack.yml up command again and this time everything should be fine, the network link between the containers works!
Accessing WordPress
Alright, the containers are up and running, so we should finally see WordPress in the browser. According to the docker ps command, the WordPress container's web server is exposed to port 8080 on the host machine. That being said, navigating to http://localhost:8080 should load WordPress:

It didn't work. Let's think a bit why — Docker is actually running in a VirtualBox virtual machine. That being said, the host environment for Docker is not the Windows, but the actual virtual machine running in VirtualBox! And that virtual machine has its own IP address.
Let's figure out that IP address. Open VirtualBox, then make the virtual machine's window appear by clicking the Show button:

That brings up the VM. Run ifconfig | less to take a look at the network interfaces the machine has:

The address 192.168.99.101 is the one we're looking for. With that said, let's give it a try in the browser:

That did the trick!
I'm pretty sure this is well covered somewhere in the documentation, but it was more fun to discover it on the go.
Setup WordPress
WordPress is ready, so you can start playing with it.



How to add Plugins to WordPress and Edit the Code Live
We'll very quickly run into the following problem: How can you add plugins? Or how can you edit the code?
To address this issue we need to expose the WordPress' installation directory to the host machine. This can be done by using bind mount.
In other words, we'll make some changes in the stack.yml file so that the folder /var/www/html from the container (where WordPress is located) is mapped to a local directory on the host. This means we'll be able to see the WordPress files in Windows and any changes made to these files (or copying a plugin to the wp-content/plugins folder) will be immediately visible.
Under the hood, bind mounts are using VirtualBox shared folders. That means first we need to set up the shared folders:
-
Create folders for the WordPress and database files (e.g.
c:\docker\wp) -
Stop the virtual machine using the
docker-machine stopcommand in the Docker Quickstart Terminal -
Create the shared folders:



-
Start the virtual machine by typing
docker-machine start
Now that the shared folders are set in VirtualBox, it's time to adjust the stack.yml file to use bind mount for WordPress. For reference, here's the complete stack.yml file I ended up with:
version: '3.7'
services:
wordpress:
image: wordpress
restart: always
links:
- db
ports:
- 8080:80
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
volumes:
- type: bind
source: /docker/wp
target: /var/www/html
db:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: exampledb
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- db:/var/lib/mysql
volumes:
wordpress:
db:
Start the containers with the commanddocker-compose -f stack.yml up again.
Once the containers have started, let's look at the folder we provided in the bind mount configuration:

Great! The WordPress files have appeared here, feel free to start experimenting with adding plugins, or even start writing a new one:

Your changes take effect immediately and they persist once the containers are shut down.
How to Create and Restore Database Backup
Say you did some changes in your WordPress sandbox that you want to persist.
Oddly enough, bind mount did not work for me with MySQL. It was something related to handling files Linux and Windows. No problem, a regular volume will also be fine.
You can create a backup by typing the following command:
docker run --rm --volumes-from wordpress_db_1 -v /c/docker/db-backup:/backup ubuntu bash -c "cd /var/lib/mysql && tar cvf backup.tar . && mv backup.tar /backup"
This seems to be a little bit complicated, let's break it down. This command:
- Mounts the volumes of the database container (
/var/lib/mysql) - Creates a bind mount (the host's
c:\docker\db-backupfolder to/db-backupon the container) - Uses a container based on the
ubuntuimage - Creates an archive on the
/var/lib/mysqlfolder and copies the archive (backup) to the/backupfolder
If you look at the c:\docker\db-backup folder once you've executed this command, you'll see the backup there named backup.tar.
And how can we restore the archive? You can use the following command:
docker run --rm --volumes-from wordpress_db_1 -v /c/docker/db-backup:/backup ubuntu bash -c "tar xvf /backup/backup.tar -C /var/lib/mysql"
The approach is very similar. We mount the same volume and directory but this time we extract the backup.tar from the bind mount to the volume /var/lib/mysql.
Summary
We have successfully containerized WordPress and also learned some techniques on how to easily access its source code folder so that we can copy plugins there or even edit the code. We've also learned how to create backups of the database container.