Team Leader
Published May 19, 2015

How we used Docker when developing Schibsted.pl

Docker has recently been one of the hottest tools in web applications development and deployment. In Schibsted Tech Polska we use Docker in number of different projects with different technologies. One of them is the website you are on:  Schibsted.pl!

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:

FROM php:5.6-apache

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

WORKDIR /var/www/wordpress

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

Preparation

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:

db:
  image: tutum/mysql
  environment:
    MYSQL_USER: wordpress
    MYSQL_PASS: password
  volumes:
    - /mnt/sda1/var/lib/wordpress:/var/lib/mysql
  ports:
    - "3306:3306"
web:
  build: .
  links:
    - db
  volumes:
    - .:/var/www/wordpress
  ports:
    - "80:80"

In the indicated configuration we have two containers:

  • A db container based on tutum/mysql image, 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 web container based on our own image being built from Dockerfile (build key defines the location of Dockerfile, it is the same location as docker-compose.yml in this case), with link to the db container (the db container is visible by the db alias in the web container), sharing application sources and exposing its 80 port.

The action

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

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

Additional containers

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.

More blog articles

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:

umount /Users
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.

Deployment

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!

Team Leader
Published May 19, 2015