Docker, un environnement de développement versionnable
Docker est un logiciel libre qui permet d’embarquer dans un container virtuel une application. Cela permet ainsi non plus de virtualiser un système mais de virtualiser un processus, et c’est pourquoi on parle parfois de virtualisation légère. Dans notre exemple, nous allons mettre en place Docker ainsi qu’un environnement de développement basé sur Nginx, PHP-fpm et MySQL.
Pour une explication approfondie de Docker, je vous conseille l’article de Nicolargo : Virtualisation légère avec Docker.
Installation & Configuration de Docker
Sous Windows, l’installation se fait via un installeur standard. Dans mon cas, le seul truc que je n’ai pas coché est Git, car je l’avais déjà installé.
Après installation, on lance une ligne de commande, on se déplace dans dossier et on tape quelques commandes.
- On vérifie les machines présentes sur le système :
c:\wamp\www\myProject>docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
Normalement, cela devrait être vide.
- On crée la machine par défaut :
c:\wamp\www\myProject>docker-machine create --driver virtualbox default Running pre-create checks... Creating machine... (default) Copying C:\Users\
\.docker\machine\cache\boot2docker.iso to C:\Users\ \.docker\machine\machines\default\boot2docker.iso... (default) Creating VirtualBox VM... (default) Creating SSH key... (default) Starting the VM... (default) Check network to re-create if needed... (default) Waiting for an IP... Waiting for machine to be running, this may take a few minutes... Detecting operating system of created instance... Waiting for SSH to be available... Detecting the provisioner... Provisioning with boot2docker... Copying certs to the local machine directory... Copying certs to the remote machine... Setting Docker configuration on the remote daemon... Checking connection to Docker... Docker is up and running! To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env default - On définit les variables d’environnements :
c:\wamp\www\myProject>docker-machine env --shell cmd default SET DOCKER_TLS_VERIFY=1 SET DOCKER_HOST=tcp://192.168.99.100:2376 SET DOCKER_CERT_PATH=C:\Users\
\.docker\machine\machines\default SET DOCKER_MACHINE_NAME=default REM Run this command to configure your shell: REM FOR /f "tokens=*" %i IN ('docker-machine env --shell cmd default') DO %i A ce niveau, on copie et exécute dans l’invite de commandes les lignes commençant par « SET ».
Référence : https://docs.docker.com/machine/reference/env/
Configuration de notre environnement via Docker Compose
Notre environnement sera composé d’un fichier docker-compose.yml.
La base de notre environnement sera :
- une base de données : MySQL
- un serveur Web : NGinx
- et PHP
Un article suivra pour configurer d’autres outils comme SASS, PHPMyAdmin, MailDev ou Sentry.
Configurer MySQL
Dans le fichier YAML, nous allons ajouter ces lignes :
## MySQL db: image: mysql restart: always ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: rootpassword MYSQL_DATABASE: myprojet MYSQL_USER: user MYSQL_PASSWORD: pass
Nous allons utiliser l’image Docker fourni officiellement : https://hub.docker.com/_/mysql/.
Pour pouvoir se connecter au port 3306 de MySQL, il faut définir le port de sortie qui sera le même.
Ensuite, l’image MySQL a des variables d’environnements que l’on peut définir :
- MYSQL_ROOT_PASSWORD : permet de définir le mot de passe root (obligatoire) ;
- MYSQL_DATABASE : permet de définir la base de données à créer (facultatif) ;
- MYSQL_USER : permet de définir l’utilisateur MySQL à créer (facultatif) ;
- MYSQL_PASSWORD : permet de définir le mot de passe de l’utilisateur MYSQL_USER (facultatif) ;
Configurer Nginx
Après MySQL, nous allons configurer le serveur Web. A la fin du fichier docker-compose.yml, nous allons ajouter ces lignes :
## Server Nginx web: image: nginx restart: always ports: - "80:80" volumes: - ./:/var/www/local.dev - ./.docker/nginx:/etc/nginx/conf.d links: - php:php
Pareil, nous partons sur l’image officielle fourni par Docker : https://hub.docker.com/_/nginx/.
Pour utiliser le port 80 de Nginx, il faudra que l’on définisse un port de sortie, et qui comme MySQL sera le même.
Nous allons passer aux volumes : ce sont des dossiers un peu spéciaux qui permettent de connecter un lien dans le container vers un dossier soit d’un autre container, soit sur le système hôte.
Nous allons en configurer deux :
- Dans le container, le dossier « /var/www/local.dev » pointera vers le dossier « ./ », soit la racine de notre projet ;
- Dans le container, le dossier « /etc/nginx/conf.d » pointera vers le dossier « ./.docker/nginx ».
Précisons que certains containers ont besoin de fichier de configuration ou emplacement de stockage. Dans notre cas, Nginx a besoin d’un fichier de configuration : default.conf qui est censé se trouver dans le dossier « /etc/nginx/conf.d » du container, soit au niveau de notre dossier : « ./.docker/nginx ».
Le fichier default.conf est simple. Je n’irais pas plus dans les détails le concernant si ce n’est le fastcgi_pass : celui pointe vers le port 9000 du container php que l’on lie via le noeud « links ».
server { listen 80; server_name localhost; root /var/www/local.dev/www; index index.php index.html index.htm; sendfile off; location / { # try to serve file directly, fallback to front controller try_files $uri /index.php$is_args$args; } # location ~ ^/index\.php(/|$) { location ~ ^/(index|index_dev)\.php(/|$) { fastcgi_pass php:9000; fastcgi_split_path_info ^(.+\.php)(/.*)$; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param HTTPS off; } # Return 404 for all php files as we do have a front controller location ~ \.php$ { return 404; } }
Configurer PHP
On a notre serveur Web et une base de données : il ne nous manque plus que PHP pour pouvoir compléter notre environnement.
Pour PHP, nous allons compiler nous-même PHP afin de pouvoir utiliser les extensions que l’on souhaite.
Modifions tout d’abord le fichier docker-compose.yml :
## PHP php: build: .docker/php restart: always volumes: - ./:/var/www/local.dev - ./.docker/php/ini:/usr/local/etc/php links: - db:db
Contrairement aux deux autres containers, nous n’allons pas passer par une image mais un build. Le noeud build a besoin du chemin, relatif à l’emplacement du fichier docker-compose.yml, du dossier où se trouvera le fichier Dockerfile pour builder le container.
Les volumes liés sont :
- Dans le container, le dossier « /var/www/local.dev » pointera vers le dossier « ./ », soit la racine de notre projet ;
- Dans le container, le fichier « /usr/local/etc/php » pointera vers le fichier « ./.docker/php/ini »
Le container lié est cette fois le container « db » pour que le container « php » puisse faire une requête MySQL vers celui-ci.
Il nous reste deux fichiers à définir : le fichier Dockerfile pour générer le container PHP, et le fichier php.ini (à placer dans le dossier « ./.docker/php/ini/ ») qui contiendra la configuration de PHP.
Le fichier Dockerfile de PHP est le suivant :
## On se base sur le container officiel PHP en version 5.6-fpm FROM php:5.6-fpm ## On met à jour, on installe les pré-requis et on installe les extensions PHP RUN apt-get update && apt-get install -y \ libfreetype6-dev \ libjpeg62-turbo-dev \ libmcrypt-dev \ libpng12-dev \ libsqlite3-dev \ libssl-dev \ libcurl3-dev \ libxml2-dev \ libzzip-dev \ && docker-php-ext-install iconv json mcrypt mbstring mysql mysqli pdo_mysql pdo_sqlite phar curl ftp hash session simplexml tokenizer xml xmlrpc zip \ && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \ && docker-php-ext-install gd ## On installe XDebug et on crée le fichier de configuration RUN pecl install xdebug \ && touch $PHP_INI_DIR/conf.d/xdebug.ini \ && echo 'zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20131226/xdebug.so' >> $PHP_INI_DIR/conf.d/xdebug.ini \ && echo 'xdebug.remote_enable=1' >> $PHP_INI_DIR/conf.d/xdebug.ini \ && echo 'xdebug.remote_connect_back=1' >> $PHP_INI_DIR/conf.d/xdebug.ini \ && echo 'xdebug.var_display_max_depth=10' >> $PHP_INI_DIR/conf.d/xdebug.ini \ && echo 'xdebug.cli_color=1' >> $PHP_INI_DIR/conf.d/xdebug.ini \ && echo 'xdebug.show_local_vars=1' >> $PHP_INI_DIR/conf.d/xdebug.ini ## On définit le dossier de travail WORKDIR /var/www ## On build PHP en mode FPM CMD ["php-fpm"]
Avant de lancer notre serveur, nous allons générer notre container PHP. Pour cela, on lance la commande :
c:\wamp\www\myProject>docker-compose build php
Je ne vous affiche pas le log car avec la génération de PHP, cela prend un nombre conséquent de lignes.
Le fichier php.ini est le suivant :
display_errors=1 error_reporting=E_ALL ;upload_max_filesize = 200M ;post_max_size = 40M
Configurer le partage avec Boot2Docker
Attention, ce chapitre est pour les utilisateurs de Windows.
On va configurer le partage entre le système hôte (votre ordinateur) et Boot2Docker.
Pour cela, il faut ajouter un partage au niveau de la machine virtuelle de Boot2Docker :
c:\wamp\www\myProject>"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" sharedfolder add "default" --name "c/wamp" --hostpath "C:\wamp"
Via cette ligne de commande, on ajoute un dossier partagé à la machine virtuelle nommé « default » sous le nom « c/wamp » du dossier « C:\wamp » présent sur le système hôte.
Autoriser les ports de Boot2Docker
Attention, ce chapitre est pour les utilisateurs de Windows.
On va faire de la translation de ports en mappant le port 80 de la VM vers le port 80 sur le réseau local.
c:\wamp\www\myProject>"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" modifyvm "default" --natpf1 "web,tcp,,80,,80"
Via cette ligne de commande, on redirige le port 80 vers le port 80 de la VM.
Il faut le faire pour chaque port venant de nos containers que l’on sort sur le réseau.
Utiliser notre environnement de développement
Maintenant que tout est configuré dans notre fichier docker-compose.yml, on va lancer notre environnement.
Pour les utilisateurs de Windows, on vérifie que Boot2Docker est lancé et sinon on le lance.
c:\wamp\www\myProject>docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS default - virtualbox Stopped Unknown c:\wamp\www\myProject>docker-machine start default Starting "default"... (default) Check network to re-create if needed... (default) Waiting for an IP... Machine "default" was started. Waiting for SSH to be available... Detecting the provisioner... Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command. c:\wamp\www\myProject>docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS default - virtualbox Running tcp://192.168.99.100:2376 v1.10.0
On lance la commande suivante pour enregistrer les variables d’environnement :
c:\wamp\www\myProject>FOR /f "tokens=*" %i IN ('docker-machine env --shell cmd default') DO %i
On se connecte en SSH à Boot2Docker pour activer le partage de dossiers :
c:\wamp\www\Github\myProject>docker-machine ssh ## . ## ## ## == ## ## ## ## ## === /"""""""""""""""""\___/ === ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ / ===- ~~~ \______ o __/ \ \ __/ \____\_______/ _ _ ____ _ _ | |__ ___ ___ | |_|___ \ __| | ___ ___| | _____ _ __ | '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__| | |_) | (_) | (_) | |_ / __/ (_| | (_) | (__| < __/ | |_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_| Boot2Docker version 1.10.0, build master : b09ed60 - Thu Feb 4 20:16:08 UTC 2016 Docker version 1.10.0, build 590d5108 docker@default:~$ sudo su root@default:/home/docker# mount -t vboxsf -o uid=1000,gid=50 "c/wamp" /c/wamp root@default:/home/docker# exit docker@default:~$ exit
Ou en plus court :
c:\wamp\www\Github\myProject>docker-machine ssh default "sudo mount -t vboxsf -o uid=1000,gid=50 \"c/wamp\" /c/wamp"
On récupère l’IP de Boot2Docker :
c:\wamp\www\myProject>docker-machine ip 192.168.99.100
Après cela, il ne manque plus qu’à lancer la machine :
c:\wamp\www\myProject>docker-compose up
Et d’aller dans votre navigateur pour tester l’IP :
Conclusion
Les plus perspicaces d’entre vous auront remarqué le mot « versionnable » d’entre vous. Grâce au fait que notre environnement de développement n’est basé que sur des fichiers avec principalement le fichier docker-compose.yml, tout devient versionnable et vous pouvez ainsi votre les évolutions de votre environnement pour tester des outils et revenir en arrière.
Le seul souci qui me reste à traiter reste le fait de voir à chaque démarrage de Boot2Docker de de voir gèrer les variables d’environnement et monter le point de montage. Mais peut-être que Docker nous aidera dans une prochaine version, ou qu’un des lecteurs a une solution à me proposer. N’étant pas un expert Docker, je reste ouvert à tous commentaires.
Commentaires
[…] RootsLabs nous donne un exemple assez complet d’utilisation. […]
[…] mon précédent article, j’ai mis en place un environnement de développement basé sur des containers Docker avec Nginx, PHP-fpm et MySQL. Dans cet article, nous allons mettre en place différents containers Docker pour installer les […]
Ajouter un commentaire