Améliorez vous la vie avec Docker

Cloisonnez vos environnements avec plaisir !

Bastien Jaillot

Bastien Jaillot

Je suis fainéant pragmatique ಠ_ಠ

JoliCode

Conseil, réalisation, audit, expertise et formation

...Poney, Guinness et gif animé.

Postulat (trollesque)

  • Les technos et nos motivations changent
  • Nous ne devrions pas être pénalisé par nos projets les plus anciens

Contexte de ce projet 1/2

  • projet drupal
  • au minimum une release par jour
  • 20 sites au début, potentiel de beaucoup plus
  • chacun peut avoir ses spécificités

Contexte de ce projet 2/2

  • machine dédiée, mais avec d'autres sites qui tournent et hors de question de ne serait-ce que mettre le nez dedans
  • volonté d'utiliser PHP 5.5, redis, varnish
  • cloisonnement des caches ? bases de données ? utilisateurs ?
  • très très peu de temps

Multi-site Drupal ?

Complexe ! (pensez : mise à jour, site hors ligne, résistance aux erreurs)

Préférence pour isoler complètement chaque instance de site

Solutions traditionnelles ?

  • cloud, VM, VPS
  • chroot, LXC, OpenVZ, BSD Jails, …
  • Configuration ? Déploiement ?
  • Eviter le "ça marche chez moi !"

Vous utilisez vagrant et chef / puppet ?

Un bon point !

(Julien vous fera un calin pour vous féliciter)

Mais…

Dev: "It works on my machine, just not on the server." Me: "Ok, backup your mail. We're putting your laptop into production."

Oisin Grehan (x0n)

Docker

http://docker.io

Docker

  • http://docker.io
  • Solomon Hykes, français
  • DotCloud => Docker Inc.
  • Top 10 des nouveaux projets open source 2013
  • Levée de fonds de 15M$
  • > 300 contributeurs, 9360 stars github

Docker

  • Basé sur LXC, mais "friendly"
  • Conteneur : stack applicative pour fournir un SERVICE
  • … mais pas d'abstraction du système, c'est l'hôte qui le gère !
  • "Je veux gérer ma stack logicielle avec Git"

Docker installation

Nécessite un noyau linux >= 3.8


sudo apt-get update
sudo apt-get install linux-image-extra-`uname -r`
sudo apt-key adv […]

sudo sh -c "echo deb http://get.docker.io/ubuntu docker main\
> /etc/apt/sources.list.d/docker.list"
sudo apt-get update
sudo apt-get install lxc-docker
                    

Docker test

Peut s'utiliser comme un binaire "normal"

Indice : c'est rapide !


$ sudo docker run ubuntu echo "Hello World"
Hello world

real    0m0.131s
                    

Docker test

Peut s'utiliser comme une VM "normale" (en plus rapide)


$ sudo docker run -i -t ubuntu /bin/bash
root@cb71045ed695:/#

# … we are now inside a docker instance (~vagrant)
# … we can do anything we want

echo "toto" > /test-file

                    

Docker test


$ sudo docker commit cb71045ed695 test1 # it's commited!

$ sudo docker run -i -t test1 /bin/bash

# … we are inside a NEW instance but we have the changes
# that have been made before the commit
root@458c0347ecd3:/# cat /test-file
toto

$ sudo docker run test1 cat /test-file
                    

Dockerfile : PHP 5.3 cli

Possible de créer une nouvelle image de conteuneur avec un script Dockerfile


From ubuntu:precise
MAINTAINER Bastien Jaillot <bjaillot@jolicode.com>

RUN apt-get update && apt-get install -y php5-cli

                    



$ sudo docker build -t="meetup/php53" ./
$ sudo docker run meetup/php53 /usr/bin/php --version
PHP 5.3.10-1ubuntu3.9 with Suhosin-Patch (cli) (built: Dec 12 2013 04:27:25)
                    

Dockerfile : PHP 5.4 cli


From ubuntu:precise
MAINTAINER Bastien Jaillot <bjaillot@jolicode.com>

RUN apt-get update && apt-get install -y python-software-properties
RUN add-apt-repository ppa:ondrej/php5-oldstable && apt-get update

RUN apt-get install -y php5-cli

                    



$ sudo docker build -t="meetup/php54" ./
$ sudo docker run meetup/php54 /usr/bin/php --version
PHP 5.4.24-1+sury.org~precise+1 (cli) (built: Jan 24 2014 11:05:09)
                    

Dockerfile : PHP 5.5 cli


From ubuntu:precise
MAINTAINER Bastien Jaillot <bjaillot@jolicode.com>

RUN apt-get update && apt-get install -y python-software-properties
RUN add-apt-repository ppa:ondrej/php5 && apt-get update

RUN apt-get install -y php5-cli

                    



$ sudo docker build -t="meetup/php55" ./
$ sudo docker run meetup/php55 /usr/bin/php --version
PHP 5.5.8-3+sury.org~precise+1 (cli) (built: Jan 24 2014 10:15:11)
                    

Dockerfile : HHVM


From ubuntu:precise
MAINTAINER Bastien Jaillot <bjaillot@jolicode.com>

RUN apt-get update && apt-get install -y wget
RUN wget -O - http://dl.hhvm.com/conf/hhvm.gpg.key | apt-key add -
RUN echo deb http://dl.hhvm.com/ubuntu precise main | tee /etc/apt/sources.list.d/hhvm.list
RUN apt-get update && apt-get -y install hhvm-nightly

                    



$ sudo docker build -t="meetup/php55" ./
$ sudo docker run meetup/hhvm hhvm --version
HipHop VM 2.4.0-dev+2014.01.28 (rel)
                    

Docker : publication ?

Pas *si* facile que ça, car nous n'avons pas accès en écriture à l'index docker public


$ sudo docker push test1
$ sudo docker pull test1

                    

Un SaaS à la R.A.C.H.E ?

Projet drupal…, vieux dockerfile


FROM tianon/debian:wheezy
MAINTAINER Bastien Jaillot <bjaillot@jolicode.com>

RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install curl
RUN echo "deb http://packages.dotdeb.org wheezy all" >> /etc/apt/sources.list
RUN echo "deb http://packages.dotdeb.org wheezy-php55 all" >> /etc/apt/sources.list
RUN curl http://www.dotdeb.org/dotdeb.gpg | apt-key add -
RUN apt-get update

# Basic Requirements
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install mysql-server mysql-client nginx php5-fpm php5-mysql pwgen python-setuptools curl git-core unzip php5-curl php5-gd php5-intl php-pear php-http php5-imap php5-redis redis-server drush mc && apt-get clean

# Make mysql listen on the outside
RUN sed -i "s/^bind-address/#bind-address/" /etc/mysql/my.cnf

# nginx config
RUN sed -i -e"s/keepalive_timeout\s*65/keepalive_timeout 2/" /etc/nginx/nginx.conf
RUN echo "daemon off;" >> /etc/nginx/nginx.conf

# php-fpm config
RUN sed -i -e "s/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g" /etc/php5/fpm/php.ini
RUN sed -i -e "s/;daemonize\s*=\s*yes/daemonize = no/g" /etc/php5/fpm/php-fpm.conf
RUN find /etc/php5/cli/conf.d/ -name "*.ini" -exec sed -i -re 's/^(\s*)#(.*)/\1;\2/g' {} \;

# redis config
RUN sed -i -e "s/daemonize\s*yes/daemonize no/g" /etc/redis/redis.conf

# Supervisor Config
RUN /usr/bin/easy_install supervisor
ADD ./templates/supervisord.conf /etc/supervisord.conf

# nginx site conf
ADD ./templates/nginx-site.conf /etc/nginx/sites-available/default

# Retrieve drupal
RUN mkdir /var/www/ ; cd /var/www ; git clone -b master --single-branch --depth 1 git@github.com:<repo> project
RUN chmod a+w /var/www/project/drupal/sites/default ; chown -R www-data:www-data /var/www/

# Drupal Initialization and Startup Script
ADD ./templates/init.sh /init.sh
RUN chmod 755 /init.sh
RUN ./init.sh

# private expose
EXPOSE 80

CMD ["/usr/local/bin/supervisord", "-n"]


                    

Un SaaS à l'arrache ?

Fichier de config de sites à créer


codename;port;dnsname
master;49078;master.toto.fr
demo;49079;demo.toto.fr
bastien;49080;bastien.toto.fr
                    

lancement d'instances


$ docker build -t="drupal-saas" ./

for line in csv:
    instance_id = docker ps | grep line.port
    $ docker stop <instance_id>
    $ docker run -t -i -d -p <line.port>:80 \
        -v="<path>/<line.codename>":"/var/www/project/drupal/sites/default/files" \
        drupal-saas
    $ # update vhost with mapping
        => line.dnsname proxy on line.port
    $ sudo service nginx reload

                    

De JoliTests avec JoliCi

Vous connaissez / appréciez TravisCI ?

  • JoliCi vous apporte l'exécution de tests TravisCI… sur votre machine AVANT DE COMMITER !
  • lit votre .travis.yml
  • génère ou utilise des environnements docker
  • lance les tests de votre projet pour tous les environnements définis (ex: PHP 5.3, 5.4, 5.5, HHVM)

Cloud privé

Openstack + Docker

Pas sous linux ?

Si vous n'êtes pas sur un linux récent, vous avez deux solutions :

Pour aller plus loin

  • Possiblité de limiter les ressources allouées à une instance
  • Inception ? il est possible de lancer docker dans un docker
  • Mapping de port, partage de volumes, voir la doc
  • Utiliser Serf pour faire communiquer les conteneurs entre eux de manière évènementielle

Pour conclure

  • Permet de tester sans risque
  • Permet de varier les versions, les composants
  • Déploiements facilités
  • Facilite la communication entre les devs et les ops !

Ressources

Love you all!

Bastien Jaillot / @bastnic
coucou@jolicode.com

http://jolicode.github.io/docker-drupal-meetup-conf

PS : on recrute ♥