9 min read

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:

  1. Download the Docker Toolbox binary from here

    Docker Toolbox is being downloaded

  2. Once downloaded, start the installer and click through it:

    Docker Toolbox Installer Step 1.

    Docker Toolbox Installer Step 2.

    Docker Toolbox Installer Step 3.

    Docker Toolbox Installer Step 4.

    Docker Toolbox Installer Step 5.

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

    Open Docker Quickstart Terminal

    Docker Quickstart Terminal running the first time

    Docker Quickstart Terminal available

  4. 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.

    1. In Docker Quickstart Terminal, type the following command to first stop the virtual machine running Docker:

      $ docker-machine stop
      
    2. Update VirtualBox. Open it and it'll prompt you that it's outdated — use the link from the window to download the latest version:

      VirtualBox showing it's outdated

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

      VirtualBox was successfully upgraded

  5. 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:

Docker Qu

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

VirtualBox was successfully upgraded

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:

VirtualBox was successfully upgraded class=right

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:

Open the virtual machine console class=max

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

Check the IP of the virtual machine class=max

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:

WordPress appearing with the correct IP address class=max

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.

WordPress installation page

WordPress installation success

The WordPress page

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:

  1. Create folders for the WordPress and database files (e.g. c:\docker\wp)

  2. Stop the virtual machine using the docker-machine stop command in the Docker Quickstart Terminal

  3. Create the shared folders:

    Seting Shared Folders Step 1.

    Seting Shared Folders Step 2.

    Seting Shared Folders Step 3.

  4. 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:

WordPress files are mapped to host directory

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

Start developing for WordPress

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-backup folder to /db-backup on the container)
  • Uses a container based on the ubuntu image
  • Creates an archive on the /var/lib/mysql folder and copies the archive (backup) to the /backup folder

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.