Docker is an open-source container technology best known for simplifying the workflows of developers and sysadmins. In Docker, applications are in fact shipped within virtual software containers, which can be run either on a physical machine, an instance in a public or private cloud, or a distributed system.

Docker has equally proven to be an excellent technology for hosting WordPress sites. By enabling users to easily migrate an environment from one server to another without needing to change configuration settings, Docker increases the security of these websites and makes it easier for the user to scale them.

Web agencies, who host a huge number of websites on their servers, can also use Docker to industrialise their hosting platforms and cohabit heterogeneous application environments, such as different versions of a language. In a nutshell, Docker improves the performance and facilitates maintenance of their platforms.

The components

  • 1 VPS Cloud 1 on Ubuntu 14.10
(We've also just launched an Ubuntu 14.04 image with Docker pre-installed for VPS Cloud and Classic)

Docker gives us 3 separate containers on the VPS:

  • 1 container for WordPress (static files)
  • 1 container for the MySQL database used by WordPress
  • 1 container for Piwik, an open-source website traffic analysis system

Security, scalability, industrialisation: the advantages of Docker hosting

The first great thing for us in using Docker is the isolation it provides by installing the different components within separate containers to increase the security of our server. By doing this, we can access WordPress configuration files in the event of an issue with WordPress, but never the VPS itself or the Piwik application. If one of the containers is pirated, we simply have to stop it, restore a backup of it, apply the updates and patches straightaway and then relaunch the it. This won't impact our other containers.

Another great thing: the solution's scalability. As Docker containers are independent from the platform they run on, we can easily move them to another server on Linux. In October 2014, Docker Inc. announced that it had signed an agreement with Microsoft to make the solution available on Windows operating systems (more info here). In real terms, if the website gets overloaded tomorrow, we can easily move the database container to a second VPS or a physical dedicated server.

Lastly, Docker makes it easier to administer and maintain servers that host a large number of websites. Websites are contained in separate containers, which you can easily move and upgrade without having to reconfigure the application environment every time.

1) Installing Docker

Before you can install Docker on a OVH VPS Cloud, you need to modify the VPS kernel. We need to install a compatible kernel as the kernel automatically provided by OVH doesn't allow Docker to install or work properly. To do this, we need to log in to the VPS and use the following command to allow us to download and install the latest generic kernel for Ubuntu:

apt-get install linux-image-generic

More information on which kernel to use for your version of Ubuntu.

We then need to ask the server to boot on this new kernel. We do this by changing the /etc/default/grub file and the GRUB_DEFAULT to 1. Then we need to launch an update-grub and reboot the server. To check the kernel is correctly installed, we can use the command "uname -a", which should respond with: "Linux vpsXXXXX 3.16.0-30-generic"

To actually install Docker:

Create the /etc/apt/sources.list.d/docker.list file and write:

deb http://get.docker.io/ubuntu docker main

Download the GPG and install the following packet:

apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
apt-get update
apt-get install lxc-docker

There you go. We've now got a VPS Cloud with Docker.

2) Creating an SQL container

You can see all the Docker images that already exist in the Docker Registry Hub, the hosting platform for Docker images. We will use images officially kept by Docker Inc. to build our infrastructure. For the MySQL database, we're going to use the official MySQL image. We will use this command to download it:

docker pull mysql:latest
Once the image has downloaded, we can see it with this command:

docker images
To launch a container based on this image, let's use this command:

docker run -e MYSQL_ROOT_PASSWORD=yourpassword --name db -v /home/mysql/:/var/lib/mysql/ -d mysql

The -v /home/mysql/:/var/lib/mysql/ part of the command will allow us to create a volume shared between our database container and the host. This is practical when we want to update the container after a security failure for example: we would just need to download the up-to-date image, delete the original container, start the patched container, and then bind the container to the data on the host.
Now let's enter the "docker ps" command to see if the container is properly launched. If the command returns a result like:
this means that our container is up and working! We now have a MySQL database bound to port 3306. The port's default login is "root" and the password was set when the command was run to generate the container. To easily retrieve the IP address attached to our MySQL container, we're going to create an alias:

alias dockip="docker inspect --format '{{ .NetworkSettings.IPAddress }}'"

To test that our database is working properly, we can bind it to the database container by running the following command:

mysql -h$(dockip db) -uroot -pyourpassword


Our database container listens to port 3306, but only locally (reachable only via the host machine - our VPS - and our containers' IPs).

3) Creating a WordPress container

It's the same principle for WordPress containers. We're going to download an image from the Docker Registry Hub.
For this tutorial, we will use the official WordPress image. To download it, use the following command:

docker pull wordpress:latest

Once we've downloaded the image, we can launch the container that will be based on this image by running this command:

docker run --name some-wordpress --link db:mysql -v /home/wp/:/var/www/html/ -p 80:80 -d wordpress

The "--link db:mysql" part of the command will simply allow us to link our WordPress container to the MySQL container we previously launched.

We then just need to go to the site by opening a web browser and entering our server's domain name or IP address in the address bar. Please note that it's better to configure WordPress with the final domain from the outset, otherwise WordPress won't be configured with the correct URL. We simply need to define a username and password for WordPress admin access.

We now have a web infrastructure with a MySQL container and a WordPress container which work and communicate with one another!

3) Creating a Piwik container

We're now going to install a tool named Piwik to enable us to quantify and analyse visits to our website. Why use Piwik over another web analytics tool? One of Piwik's biggest advantages over its competition is that it gives the user full control of the tool. With Piwik, users can protect themselves against potential data leaks and the reuse of their collected data. For more information about Piwik: http://piwik.org/

To install Piwik, let's log in to https://registry.hub.docker.com// and search for a Piwik image. We will base our search on the number of downloads and stars, and we will quickly check the dockerfile to make sure the selected image runs only what we want. Let's choose for example the "cbeer/piwik" image, which also has the advantage of being an automated build, i.e. the container's source code is open, anyone can build it and it's built in the Hub Registry by the contributors:
To download it, run the following command:

docker pull cbeer/piwik:latest

Once the image is downloaded, you need to launch it in a container. To do this, we will run this command:

docker run -d --name piwik --link db:mysql -p 49170:80 cbeer/piwik

Now our Piwik container listens to port 49170 - we can therefore access the Piwik interface by entering the domain name or the server's IP followed by 49170 in the web browser's address bar.

Piwik will firstly ask us for information about the database. We're going to create our own database for Piwik via our MySQL container using a username and password. To improve the security of our infrastructure, they need to be different to those used for the WordPress database.

Let's start by logging in to the database via our VPS:

mysql -uroot -h$(dockip db) -pyourpassword

Then run the following commands:

CREATE DATABASE piwik;
GRANT ALL PRIVILEGES ON piwik.* TO "username"@"%" IDENTIFIED BY 'password';
FLUSH PRIVILEGES;

We're now going to enter the following information into the Piwik interface:
  • server: mysql (host name created from the Docker link --link db:mysql)
  • user: username
  • pass: password
  • database name: piwik
  • prefix: piwik_

Piwik will then ask us for the URL of the website it needs to analyse: example "http://www.mysite.com/, as well as the Piwik username and password. Once these credentials have been validated, we will see the Piwik login page:
Once logged in, go to Settings, then select General Settings. Under the Hostname, we can see Valid Piwik Hostname, with "mysite.com" by default. We will simply tell Piwik that the connection will pas through a specific port (in our example, 49170). The Valid Piwik Hostname will therefore go via "mysite.com" to "mysite.com:49170". Then click "save".
We now just need to do one more thing to authorise Piwik to retrieve visitor statistics for our WordPress website. Let's start by logging into our WordPress admin page. We will click on the extension, then on "add", and we will search for the "WP-Piwik" module. Once we've found it, we will install and activate it.
Let's then go to the WordPress settings and select "WP Piwik", then "Piwik settings".
We will specify several settings:

  • Piwik URL (REST API): in our example "http://www.mysite.com:49170/"
Auth Token: we need to retrieve this information directly from the Piwik administration panel. In the top right-hand corner, click on your login, then on "API" and copy the letters and numbers only that follow "&token_auth="
  • User agent: WP-Piwik

We will then save the modifications and go to the "Tracking" page, still in the "WP-Piwik" configuration. Here we simply need to tick the "Add tracking code" box and then save the changes.

Our Piwik is now working and you should get visitor statistics for your website.

5) Basic VPS security

Now that we've set up our 3 containers and installed our components, we will apply security settings to our VPS. We will use fail2ban to secure the connection to our VPS's port 22 (SSH port). Let's start by installing fail2ban:

apt-get install fail2ban

Port 22 is monitored by default. However, if you've changed its default settings or if you want to change the IP blacklisting deadlines (bandtime, findtime), you need to edit the file /etc/fail2ban/jail.conf.
For more information on how to use and configure fail2ban:
http://www.fail2ban.org/wiki/index.php/Main_Page

For more security, you can also add iptable rules to filter or close ports that your server doesn't use. You can also secure the infrastructure by installing fail2ban and creating iptable rules before you begin installing Docker, which is advised to prevent attacks during the installation.

6) Conclusion

Docker has enabled us to quickly set up an optimised and secure basic web infrastructure.
We could have also covered how you can use a Docker-type orchestrator or gaudi, or how to implement an Nginx reverse proxy to the containers so they can all use port 80 and SSL.
There are clearly plenty of subjects surrounding Docker that we will soon cover in future articles.