La philosophie de Docker est "un conteneur pour un processus", ce qui veut dire que si vous voulez monter une infrascture web "classique" LAMP ou autre il va falloir : 3 conteneurs minimum.
A la fin de mon précédent article sur Docker j'expliquais comment linker deux conteneurs en ligne de commande, ce qui va devenir un peu contraignant si on a plus de deux conteneurs.
Heureusement l'univers Docker est peuplé d'applications pour nous faciliter la vie. Il existe donc docker-compose qui va nous permettre de créer des sortes de "recettes" de déploiement de conteneurs.
Installation
L'installation est assez simple, je parle bien sur de l'installation sous Debian 8, sur Windows et Mac, docker-compose fait partie des Docker Toolbox
# curl -L https://github.com/docker/compose/releases/download/1.6.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
# docker-compose -v
docker-compose version 1.6.2, build 4d72027
Simple ...
Architecture de travail
Pour jouer un peu on va partir sur la même infrastructure que mon article sur haproxy on va juste zapper le serveur NFS le volume de données se trouvera sur le serveur hébergeant les conteneurs.
Composons
En route pour cette symphony métallique, ndlr je vous propose d'écouter un petit metal opéra en composant tout cela : Avantasia
Pour créer notre infrastructure de conteneurs nous devons rédiger un ficher au format yaml : docker-compose.yml, ce fichier doit se trouver dans un répertoire (pour être bien organisé et avoir plusieurs infrasctures sur le même serveur.
Haproxy
$ mkdir infra01
$ cd infra01
$ vi docker-compose.yml
haproxy:
image: haproxy
volumes:
- ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
links:
- weba
- webb
ports:
- "80:80"
- "8080:8080"
expose:
- "80"
- "8080"
On commence en spécifiant les caractéristiques du conteneur haproxy.
On spécifie en premier l'image à utiliser.
On monte un volume qui va contenir le fichier de configuration de haproxy.
On link les serveurs web.
On expose les ports : 80 pour le proxy et 8080 pour les stats haproxy.
A partir du moment ou vous avez les bases de connaissance sur Docker c'est assez simple, sinon relisez l'article d'introduction à Docker
Serveurs Web
Pour cette infra je vais mettre des serveurs NGinX qui vont servir de proxy au conteneur PHP. On rajoute ceci à la suite dans le fichier docker-compose.yml :
weba:
image: nginx:latest
hostname: weba
expose:
- 80
volumes:
- ./site:/var/www/html
- ./nginx/web01.conf:/etc/nginx/conf.d/web01.conf
links:
- php
webb:
image: nginx:latest
hostname: webb
expose:
- 80
volumes:
- ./site:/var/www/html
- ./nginx/web01.conf:/etc/nginx/conf.d/web01.conf
links:
- php
webc:
image: nginx:latest
hostname: webc
expose:
- 80
volumes:
- ./site:/var/www/html
- ./nginx/web01.conf:/etc/nginx/conf.d/web01.conf
links:
- php
Encore une fois rien de bien compliqué
- on prends l'image de base nginx
- on monte le volume contenant le code du site dans le répertoire /var/www/html
- idem pour la configuration de nginx
- on expose le port 80 pour que le proxy puisse joindre le serveur web
- on link le conteneur php
Conteneur PHP
On rajoute le conteneur pour gérer le PHP. On va cette fois-ci prendre l'image php:7-fpm de base mais la modifier car on doit rajouter les librairies d'accès à MySQL.
Pour cela on va devoir faire un Dockerfile dans un sous-répertoire php :
$ mkdir php ; cd php
$ vi Dockerfile
FROM php:7-fpm
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libmcrypt-dev \
libpng12-dev \
&& docker-php-ext-install -j$(nproc) iconv mcrypt \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) gd \
&& docker-php-ext-install mysqli pdo pdo_mysql
Pour les détails voir la documentation de l'image PHP sur le hub Docker.
On rajoute maintenant le conteneur PHP dans notre configuration :
php:
build: php
hostname: php01
volumes:
- ./site:/var/www/html:ro
links:
- mariadb
Remarquez le build à la place de image, on y reviens après, puis on monte le répertoire du site en read-only pour que PHP puisse lire les fichiers PHP.
MariaDB
Pour finir notre conteneur qui va gérer la base de données.
mariadb:
image: mariadb
volumes:
- ./sql:/var/lib/mysql/web01
environment:
- MYSQL_ROOT_PASSWORD=passrootmysql
- MYSQL_DATABASE=bddsite
- MYSQL_USER=usersite
- MYSQL_PASSWORD=passwordsite
On isole la base de données dans un répertoire et on définit les variables pour la base de données.
Utilisation
Docker-compose build
Notre infra est maintenant complète. On va pouvoir l'utiliser. Mais avant de démarrer les conteneur il faut "construire" notre image PHP modifiée, les commandes sont à lancées dans le répertoire racine du projet, ie le dossier dans lequel se trouve le fichier docker-compose.yml.
Voici mon arborescence :
.
├── docker-compose.yml
├── haproxy
│ └── haproxy.cfg
├── nginx
│ └── web01.conf
├── php
│ └── Dockerfile
├── site
│ ├── index.php
...
└── sql
On build l'image php
$ docker-compose build
Docker-compose up
Tout semble bon pour démarrer notre infra de conteneurs :
$ docker-compose up
Creating infra01_mariadb_1
Creating infra01_php_1
Creating infra01_webc_1
Creating infra01_weba_1
Creating infra01_webb_1
Creating infra01_haproxy_1
Si tout ce passe bien tout les conteneurs démarrent et vous pouvez vous connecter sur le port 80 de votre machine.
Si il y a des erreurs il faut explorer les logs des conteneurs qui posent problèmes.
Docker-compose stop
Pour stopper tout les conteneurs d'un coup.
Docker-compose rm
Pour supprimer tout les conteneurs ... attention à vos données bien sur ...
La prochaine fois
La prochaine fois j'aborderais docker-machine et swarm de façon à déployer des conteneurs sur plusieurs serveurs physiques.