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 ontutum/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 fromDockerfile
(build
key defines the location ofDockerfile
, it is the same location asdocker-compose.yml
in this case), with link to thedb
container (thedb
container is visible by thedb
alias in theweb
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.
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!