Docker and wordpress for a better world

14 Dec 2015 · Six minute read · on Gianluca's blog

I am trying to represent a typical wordpress infrastructure

Wordpress typical infrastructure

Isolation: every single wordpress share all with the others, filesystem, memory, database.

This lack of isolation causes different problems:

We are overwhelmed by the problems

Problem

LXC Container

it is an operating-system-level virtualization environment for running multiple isolated Linux systems (containers) on a single Linux control host.

by wikipedia

Wikipedia helps me to resolve one problem (theory), container is isolated Linux System

Docker

Docker borns as wrap of LXC container but now we use an own implementation runc to serve your application ready to go in an isolate environment, with own filesystem and dependencies.

Worpdress in this implemetation has two containers, one to provide apache and php and one for mysql database. This is an example of Dockerfile, it describes how a docker container works it is very simple to understand, from this example there are different keywords

FROM ubuntu
RUN dpkg-divert --local --rename --add /sbin/initctl
RUN ln -s /bin/true /sbin/initctl
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y install mysql-server
EXPOSE 3306
CMD ["/usr/bin/mysqld_safe"]

Very easy to read, it is a list of commands! We are only write a container definition, now we can build it!

docker build -t gianarb/mysql .

In order to increase the value of this article and to use stable images I will use the official mysql and wordpress images.

Download this images

docker pull wordpress
docker pull mysql

We are ready to run all! Dockerfile is only a way to describe each single container, and the pull command downloads online container ready to work, it is a good way to reuse your or other containers.

We downloaded mysql and wordpress, with the run command we start them and we define our connections

docker run \
    --name mysql \
    -p 3306:3306 \
    -e MYSQL_ROOT_PASSWORD=passwd  mysql

docker run -e WORDPRESS_DB_HOST=wp1.database.prod \
    -e WORDPRESS_DB_USER=root \
    -e WORDPRESS_DB_PASSWORD=help_me \
    -p 8080:80 \
    -d --name wp1 \
    --link wp.database.prod:mysql wordpress

I can try to explain this commands, it run two containers:

We are ready! Now you have a worpdress ready to go on port 8080.

Docker Compose

To save time and to increase reusability we can use docker-compose tool that helps us to manage multi-container infrastructures, in this case one for mysql and one for wordpress. In practice we can describe all work did above in a docker-compose.yml file:

wp:
  image: wordpress
  ports:
    - 8081:80
  environment:
      WORDPRESS_DB_HOST: wp1.database.prod
      WORDPRESS_DB_USER: root
      WORDPRESS_DB_PASSWORD: help_me
  links:
    - wp1.database.prod:mysql
mysql:
  image: mysql:5.7
  environment:
    MYSQL_ROOT_PASSWORD: help_me

Now we can run

docker-compose build .
docker-compose up

To prepare and start our infrastructure. Now we have one wordpress with own mysql that run on port 8081. We can change wordpress port to start new isolate wordpress installation.

via GIPHY

In Cloud with AWS ECS

We won a battle but the war is too long, we can not use our PC as server. In this article I propose AWS Elastic Container Service a new AWS service that helps us to manage containers, why this service? Because it is Docker and Docker Composer like, it’s managed by AWS, maybe there are more flexible solutions, Swarm, Kubernetes but it is a good start point.

AWS Elastic Container Service

A services of keywords to understand how it works:

In practice

  1. Create a cluster
ecs-cli configure \
    --region eu-west-1 \
    --cluster wps \
    --access-key apikey \
    --secret-key secreyKey
  1. Up nodes (one in this case)
ecs-cli up --keypair key-ecs \
    --capability-iam \
    --size 1 \
    --instance-type t2.medium
  1. Push your first task!
ecs-cli compose --file docker-compose.yml  \
    --project-name wp1 up
  1. Follow the status of your tasks
ecs-cli ps

You can use another docker-compose.yml with a different wordpress port to build another task with another worpdress!

Now is only a problem of URL

We are different isolated worpdress online, but they are an ip and different ports, maybe our customers would use a domain name for example. I don’t know if this solution is ready to run in production and it is good to run more and more wordpress but a good service to turn and proxy requests is HaProxy. This is an example of configuration for our use case:

wp1.gianarb.it and wp1.gianarb.it are two our customers and 54.229.190.73:8080, 54.229.190.73:8081 are our wordpress.

...
frontend wp_mananger
        bind :80
        acl host_wp1 hdr(host) -i wp1.gianarb.it
        acl host_wp2 hdr(host) -i wp2.gianarb.it
        use_backend backend_wp1 if host_wp1
        use_backend backend_wp2 if host_wp2
backend backend_wp1
        server server1 54.229.190.73:8080 check
backend backend_wp2
        server server2 54.229.190.73:8081 check

Note: This configuration increase the scalability of our system, because we can add other service in order to support more traffic.

backend backend_wp1
        server server1 54.229.190.73:8080 check
        server server1 54.229.190.12:8085 check
        server server1 54.229.190.15:80 check

There are other solutions

Something weird with this website? Let me know.