Back to Blog Posts

Leveraging Docker-Compose for Local Dev Environment

By Arty / October 10th, 2018

I was honored to talk recently at cPanel Conference 2018 about how Docker might be useful to developers. It was hard to fit everything in the tight talk format, and given the audience feedback post-talk, I hope this post will be useful.

So what is this all about? As you probably heard by now, Docker may be primarily known as a production OS-level virtualization environment - but its utility does not end there. At WHMCS, we have been using Docker for local development for nearly three years with great success. Let's look into what it takes to get there.
First of all, for those who are not familiar with Docker - it's a software package that performs operating-system-level virtualization using containers. On a very basic level it allows running software such as Apache or MySQL within a closed environment known as a "container" that can be started or stopped in seconds. From a certain standpoint it might be compared to a virtual machine, however it incurs a lot less overhead and allows running multiple containers without overloading the host OS.

Docker environment software is available for all major operating systems, including Linux, macOS and Windows. While an OS-specific implementation may change, the net result is the same - you can run Docker containers on a variety of host operating systems in the same clean, portable and extensible way.

It's important to note that Docker containers are designed to run a single process. That process defines the lifetime of the container - as soon as the process exits, the container is stopped. However, to support a web application, we would normally need more than one software application - e.g. Apache+PHP for a web server, MySQL for a database server, etc. Since Docker containers are designed to run a single process, it means that we need multiple containers for a web application to be run. This is easily achieved using a tool called "docker-compose". It is available within the standard distribution of Docker environment and is designed to start, run and stop multiple containers at the same time, while allowing them to communicate between each other using a virtual network.
Using Docker for local development may sound like overkill at first, but it helps solve the following issues experienced by most web application software developers:

By unifying software runtime setups, Docker helps you reproduce setups reported by customers and eliminates discrepancies between multiple developer machines. If it breaks on your colleague's set up, you can pretty much rest assured it will break on yours.

Since different software components are decoupled from each other (almost as if they ran on different hosts), you can for example safely upgrade PHP without being concerned about what it will do to your MySQL server.

For the same reason, swapping different containers is made much easier - e.g. switching between any of the 4 actively supported PHP versions takes no more than a few seconds.

If there is a particular application that you require, you can almost always find it on Docker Hub, the official repository for pre-built Docker images. If there is something you cannot find, Docker images are quick to modify and extend using an easy-to-use file format.

A less known benefit of using a set of Docker containers for local development is the ability to use them as an environment to run automated testing. This however would be a topic for a separate article - but the possibility is there if you need it.
How It Works
Each software application runs in Docker within a container. Each container is described using a file usually called a "Dockerfile"

It contains instructions that tell Docker how to prepare the container to fit your needs. The first line specifies an image to start with - it's automatically downloaded from Docker Hub. In this case we will be starting with an image that runs Apache and PHP 7.2.

To run many containers at the same time, we use a file called "docker-compose.yml":

It will start multiple containers at the same time. In the screenshot above you can see the "services" node that has multiple containers in it. One such container is "web" which is instructed to start using a specific "dockerfile". You can also see "volumes" node that instructs which parts of the host filesystem should be mapped to particular paths inside the container. This allows our web container to easily serve our application files using its built-in Apache / PHP stack.

To start your container set, you would use docker-compose tool and specify the docker-compose.yml file. Fortunately, all these steps are being encapsulated in the start script that we will discuss below.
Quick Start Boilerplate
To get you up to speed in no time, we have prepared a GitHub repository that you can clone. Follow these steps to get started:

1. If you don't have a Docker environment set up yet, go to and download the Docker distribution for your OS. Run the install and make sure it's set up and running.

2. Clone the boilerplate repository:

3. In Terminal, change to the newly created directory and start your containers:

    $ docker/tools/

Done - you are now running a fully functional PHP web development environment. Open localhost:8081 to confirm:

You can use the buttons provided to confirm your environment is set up the way you need it. To change PHP version, go to your terminal, Ctrl-C out of the Docker run, then use the start script with an optional parameter:

    $ docker/tools/ --php 72

Please see the documentation on GitHub for more examples and an advanced usage section. All PHP versions include Xdebug, so you can even use a debugger right out of the box.

You can also download my presentation slides on Leveraging Docker Compose for Local Dev to see a bit more of my thoughts on the topic. I hope that this article and the slide deck will help you get started with web development using Docker and if you have any questions, I invite you to ask them in the comments below!

Liked this article? Share it