Docker is an open platform for developing and deploying distributed applications, like web applications. Docker allows you to easily build up the environment for your applications from preconfigured components and run the same environment both on your teammates’ laptops, the data center VMs and the cloud.
The platform takes advantages of Linux kernel to provide Docker containers – entities with application and its dependencies, isolated from other containers and the host operating system, but sharing the kernel with it. This makes Docker containers a perfect alternative to virtual machines as the containers enjoy the resource isolation of virtual machines, but are much more portable and mean more performance.
You may want to learn more about Docker essentials on its website.
Preparing the WordPress configuration
Schibsted.pl is powered by WordPress, which is one of the most popular content management systems in the world. From the technical point of view its supremacy is disputable, but without any doubt it gives a lot of benefits for content editors. WordPress is written in PHP, so it can be run with just a standard LAMP stack.
The idea of Docker is that each single process runs in a separate container. In this case we need at least two containers: first with Apache and PHP, and second with MySQL. Building containers is easy thanks to a number of preconfigured images available on Docker Hub. In this case we use the official PHP image with Apache to run the
web container, and Tutum’s MySQL image to run the
db container. The MySQL image can be used without any changes, but the PHP image needs some additional configuration to run WordPress.
Actually, we need to build our own image based on the official PHP image. The configuration of the image is placed in a file called
Dockerfile. Here is the minimal configuration for running WordPress:
RUN apt-get update
&& apt-get install -y git zlib1g-dev
&& docker-php-ext-install mysql pdo_mysql zip
ADD docker/vhost.conf /etc/apache2/sites-enabled/000-default.conf
ADD docker/php.ini /usr/local/etc/php/php.ini
RUN a2enmod rewrite
RUN curl -sS https://getcomposer.org/installer | php
&& mv composer.phar /usr/bin/composer
Let me walk you through this file. First of all, we define the base image we use – this is the official PHP image with PHP 5.6 and Apache. Then, we install necessary packages and PHP libraries. In the next step we add the prepared Apache’s
vhost.conf file and the PHP’s
php.ini file. The following step enables Apache’s rewrite module and then Composer is being installed. At the end, we define the workdir to the application folder.
NOTE! The full example described in this post is available on GitHub!
Running the environment
Running multiple containers and linking them together used to be a hustle in the past, but now, thanks to Docker Compose, it is a pure pleasure. With Docker Compose you configure the environment in one simple YAML file called
docker-compose.yml. Here is the configuration of a simple LAMP stack:
In the indicated configuration we have two containers:
A dbcontainer based on
tutum/mysqlimage, with configured MySQL’s credentials, sharing MySQL data folder (it means data will remain after the container is stopped) and exposing its 3306 port.
A webcontainer based on our own image being built from
buildkey defines the location of
Dockerfile, it is the same location as
docker-compose.ymlin this case), with link to the
dbcontainer is visible by the
dbalias in the
webcontainer), sharing application sources and exposing its 80 port.
The only thing you need to run the environment is to type the docker-compose up -d command in your host’s console and voila! The environment is up and ready.
However, there are also some additional steps to make WordPress work. First, we need to install dependencies to actually get the WordPress files. Running
composer install in the
web container would be enough for that. To do so, you may want to log in to the container by running the following command:
docker exec -it dockerwordpress_web_1 bash
dockerwordpress_web_1 is the actual name of the web container. It is defined automatically by Docker Compose based on the project’s root folder name (first part) and the container’s name in
docker-compose.yml (second part).
After logging to the container we can run the composer install -n command.
Second, we need to create a database for WordPress. It can be done by running the
mysql command after logging to the
db container (the similar way as before), but we can run the command directly from the host machine as well:
docker exec -it dockerwordpress_db_1 mysql -u root -e "CREATE DATABASE wordpress;"
The final step is to configure WordPress’ host in the local hosts file.
Using multiple Docker containers configuration makes it very easy to add additional tools to the environment. For example, in the schibsted.pl case we use Varnish to cache static content.
Running on MacOS X
Docker containers use internal Linux kernel stuff, which means they can be run only on Linux distributions. In fact, a number of developers in Schibsted Tech Polska use MacOS X for work, which forces us to virtualize Linux to run Docker containers. Previously we used to use Vagrant for that, but now we switched to boot2docker.
Boot2docker is a simple tool that installs the Docker client on your host OS (MacOS or Windows), allowing you to use Docker commands in the host’s console. It also runs a small VirtualBox’s virtual machine with Linux and Docker servers installed – this is the place where containers are being run.
Boot2docker works pretty cool, but you may find some issues when using it. One of the most annoying is this with writing to the shared volume. However, don’t feel disappointed – there is a pretty easy workaround for that!
All you need to do is to edit
/var/lib/boot2docker/profile file on the boot2docker virtual machine. So first, login to the VM (you can simply run
boot2docker ssh command), and then add the following lines to that file:
mount -t vboxsf -o uid=33,gid=33 Users /Users
Finally, restart the VM by running boot2docker restart.
There is plenty of resources in the Web discussing tips and tricks in tuning up boot2docker. The one we found most valuable in our case was the experience of blackfire.io.
Using Docker for development is just a first step. The real power is when you use the same configuration to develop on your local machine and then running the whole thing on production. Indeed, we use Docker to run schibsted.pl on production as well!
I will describe it in the oncoming post on this blog. Stay tuned!