Utiliser Docker pour développer avec le mkframework

Utiliser le célèbre conteneur pour développer plus facilement.

Michael Bertocchi

Dans un premier temps, nous installerons le gestionnaire de conteneur Docker et verrons ses commandes principales, puis nous installerons mkframework dans un conteneur.

Commentez

- Titre : Utiliser Docker pour développer avec le mkframework

- Auteur : Michael Bertocchi

- Parution : 11 janvier 2017

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2016 Michael Bertocchi. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Voir également :

- Apprendre à créer facilement un site web dynamique en PHP avec mkframework

- Créer son site de microblogging

- Création d'un site web full cache avec le mkFramework

- La sécurité web avec le mkframework

Sommaire

- I. Introduction

- II. Le gestionnaire de conteneur : Docker

- II-A. Installation de Docker

- II-B. Les commandes

- II-B-1. Chercher une image dans un dépôt à installer

- II-B-2. Construire votre propre image

- II-B-3. Lister les images

- II-B-4. Ajouter un tag à une image

- II-B-5. Démarrer un conteneur

- II-B-6. Éteindre un conteneur

- II-B-7. Se connecter à votre conteneur

- II-B-8. Conserver les modifications « éphémères » d'un conteneur

- II-B-9. Sauvegarde d'un conteneur dans une archive

- II-B-10. Restauration d'un conteneur depuis une archive

- III. Docker + mkframework

- III-A. Préparation de notre conteneur

- III-B. Préparation de notre espace de travail

- III-C. Travailler avec notre image docker

- III-D. Se connecter à notre conteneur pendant son exécution

- III-E. Travailler avec des virtualhost

- III-F. Travailler avec un serveur MySQL à notre conteneur

- III-F-1. Introduction

- III-F-2. Travailler avec une base de données mysql éphémère

- IV. Conclusion

- V. Remerciements

I - Introduction

Certains d'entre vous connaissent déjà le célèbre gestionnaire de conteneur Docker qui permet de faire tourner des services sans nécessiter le lancement d'une machine virtuelle complète.

Nous allons dans cet article apprécier son utilisation pour développer facilement vos applications avec le mkframework.

Dans un premier temps, nous installerons le gestionnaire de conteneur, nous ferons une rapide présentation des différentes commandes.

Dans un second temps, nous créerons notre conteneur de départ, puis nous verrons comment l'utiliser pour développer une application avec.

II - Le gestionnaire de conteneur : Docker

II-A - Installation de Docker

Il y a plusieurs façons d'installer cette application, développant sous GNU/Linux nous allons juste citer le cas d'Ubuntu et dérivés (j'utilise Linux Mint).

Ouvrons le gestionnaire de paquets :

Recherchons « docker.io » :

Double-cliquons dessus et validons avec le bouton « install ».

Voilà, l'application est installée, si vous n'êtes pas sous GNU/Linux, vous pouvez suivre les indications d'installation sous Windows et Mac.

II-B - Les commandes

Cette application s'utilise en ligne de commande, nous allons voir dans cette partie une liste des commandes dont nous aurons besoin.

II-B-1 - Chercher une image dans un dépôt à installer

Docker propose une commande pour rechercher dans son dépôt les images disponibles, vous pouvez par exemple installer un environnement Apache/PHP.

Cherchons par exemple une image « lamp » (Linux Apache MySQL PHP) :

docker search lamp

Vous devriez avoir une liste similaire :

Vous pouvez ainsi « récupérer » en tapant par exemple :

docker pull reinblau/lamp

II-B-2 - Construire votre propre image

Vous pouvez également « construire » un conteneur personnalisé via un fichier dit « DockerFile ».

Pour cela, créons un fichier « Dockerfile » dans un répertoire.

Par exemple :

# This is a comment
FROM debian:jessie
MAINTAINER mika <mika@localhost>

Ici une simple image contenant uniquement la version « jessie » de la distribution « debian ».

Voici une petite liste « non exhaustive » de la grammaire qui sera utilisée dans cet article :

- FROM : image de départ.

- RUN : lance une commande dans un shell (par exemple l'installation d'un paquet) à la construction de l'image.

- CMD : lance une commande au « lancement » de l'image (démarrer Apache par exemple).

- EXPOSE : écoute sur un port donné, par exemple indiquer que le port Apache est en écoute.

Vous pouvez ensuite construire celle-ci en vous rendant dans le répertoire et lancer la commande suivant :

docker build .

Dans cet article, nous détaillerons uniquement cette utilisation, car elle permettra de répondre à vos besoins plus finement en définissant paquet par paquet ce qui vous est nécessaire pour développer.

Une fois la « construction » terminée, vous devriez voir une ligne de type « Successfully built » suivi d'une liste alphanumérique représentant l'identifiant de votre image.

II-B-3 - Lister les images

Pour voir la liste des images disponibles sur votre ordinateur, vous pouvez lancer la commande suivante :

docker images

Vous devriez avoir une liste similaire :

Vous noterez que pour notre image personnalisée, il y a deux lignes au lieu d'une seule : en effet, Docker crée des images différentielles permettant ainsi de mutualiser une image de base comme Debian/Jessie pour plusieurs conteneurs différents.

II-B-4 - Ajouter un tag à une image

Les identifiants alphanumériques sont un peu inconfortables à écrire, l'utilisation de tag peut faciliter l'exécution des commandes.

Par exemple pour notre image « 2ea481ff9ce9 », nous allons créer le tag « mkf » via la commande suivante :

docker tag 2ea481ff9ce9 mkf

Vous allez voir le mot « mkf » dans la première colonne et « latest » dans la suivante :

II-B-5 - Démarrer un conteneur

Vous avez plusieurs façons de démarrer un conteneur.

Vous pouvez « juste » la démarrer, via la ligne suivante :

docker start identifiantImage

Le souci est que nous manquons ici d'options qui s'avéreront bien pratiques comme le fait de pouvoir définir à la volée un autre port ou la possibilité de « monter » un répertoire à la place d'un autre.

Pour cela, nous utilisons la commande run :

docker run identifiantImage

Que nous pouvons également utiliser avec un tag (comme le précédent ajouté) :

docker run mkf:latest

Ajoutons par exemple la redirection de port.

Imaginons que vous ayez déjà un serveur web qui tourne en local, le port 80 étant déjà utilisé vous souhaiteriez lancer ce conteneur sur un autre port.

Vous pouvez indiquer de rediriger le port 80 du conteneur vers le 81 de votre ordinateur via la commande suivante :

docker run -p 81:80 mkf:latest

Même chose pour le « montage » de volume, pour notre exemple, nous avons un répertoire « www » dans notre espace personnel, nous lançons ici le même conteneur en indiquant de lier le répertoire « /var/www/html » du conteneur au répertoire « www » de notre ordinateur via la commande suivante :

docker run -v /home/mika/www:/var/www/html mkf:latest

Le conteneur démarré fonctionnera ainsi comme si vous aviez branché votre répertoire « www » au répertoire web du conteneur.

II-B-6 - Éteindre un conteneur

Vous pouvez soit éteindre complètement un conteneur via la commande :

docker stop identifiantImage

Ou le mettre en « pause » :

docker pause identifiantImage

II-B-7 - Se connecter à votre conteneur

Une fois démarré, vous pouvez vous connecter à votre conteneur. Pour cela, après avoir récupéré l'identifiant de votre image, via l'habituel :

docker ps

Il vous suffit d'exécuter la commande suivante :

docker exec -it identifiantImage bash

Vous aurez ainsi une invite de commande connectée en tant que « root ».

Ceci peut vous permettre de vérifier un log/erreur, ou d'installer un paquet.

N'oubliez pas qu'un conteneur n'est pas une VM, tout ce que vous y faites sera perdu une fois celle-ci éteinte. Ainsi, les paquets que vous installerez avec cette commande seront perdus.

II-B-8 - Conserver les modifications « éphémères » d'un conteneur

Si vous souhaitez conserver les modifications effectuées via la commande précédente (ajout de paquet, modification d'un fichier de configuration), vous pouvez le faire avec la commande suivante qui créera un nouveau conteneur :

docker commit identifiantImage monBackup

Vous pouvez voir votre nouveau conteneur en faisant un habituel :

docker images

Vous verrez une nouvelle ligne du type :

II-B-9 - Sauvegarde d'un conteneur dans une archive

Vous pouvez également effectuer une sauvegarde d'un conteneur pour plusieurs raisons :

- sauvegarde de sécurité de vos conteneurs ;

- pouvoir communiquer/partager des conteneurs avec des collègues/amis ;

- permettre de déployer une application « packagée » sur un autre serveur.

Pour cela, vous pouvez lancer la commande suivante :

docker save identifiantImage > maSauvegarde.tar

Vous noterez ici que l'on utilise le chevron pour indiquer d'envoyer la sauvegarde vers une archive « TAR ».

II-B-10 - Restauration d'un conteneur depuis une archive

Quand on parle de sauvegarde, on doit donc logiquement expliquer comment restaurer celle-ci.

Il suffit de charger cette même archive « TAR » via la commande suivante :

docker load maSauvegarde.tar

La sauvegarde recréera dans la liste de vos images le conteneur d'origine.

III - Docker + mkframework

III-A - Préparation de notre conteneur

Nous avons vu plus haut comment utiliser docker et notamment créer et construire un conteneur personnalisé.

Nous allons ici créer un fichier contenant le mkframework « à jour ».

Créons un répertoire par exemple « dockerMkf » et ajoutons-y un fichier Dockerfile suivant :

# This is a comment
FROM debian:jessie
MAINTAINER mika <mika@localhost>
RUN apt-get update && apt-get install -y apache2 subversion php5 php5-mysql libapache2-mod-php5
RUN a2enmod php5
RUN rm /var/www/html/* -f
RUN svn checkout http://subversion.developpez.com/projets/mkframework /var/www/html/
RUN chmod 777 -R /var/www/html/data/genere
CMD /usr/sbin/apache2ctl -D FOREGROUND

EXPOSE 80

Détaillons un peu notre fichier vous permettant ainsi de l'enrichir si besoin :

- Nous partons d'une base distribution GNU/Linux « debian » version « jessie ».

- Nous y ajoutons le serveur web « apache2 », le module « php5 » ainsi que le gestionnaire de version « subversion » (pour installer le framework).

- Nous activons « php5 » sur ce serveur web.

- Supprimons les fichiers contenus dans le répertoire web.

- Installons le mkframework dans celui-ci et rendons le répertoire de génération inscriptible.

- Démarrons le serveur web en « démon ».

- Rendons disponible le port 80 (à l'extérieur du conteneur).

Maintenant nous allons utiliser les commandes vues précédemment.

Nous pouvons construire notre conteneur avec la commande :

docker build .

On affiche toutes nos images pour récupérer le dernier id de notre image fraîchement construite avec :

docker images

Puis nous ajoutons un tag « mkf » :

docker tag 2ea481ff9ce9 mkf

III-B - Préparation de notre espace de travail

L'idée dans cet article étant de faciliter vos développements avec Docker, nous allons créer sur notre ordinateur un répertoire qui accueillera nos projets web utilisant le mkframework.

Créons un répertoire dans notre espace personnel « mkProjects », donnons-lui les droits d'écriture totale afin de permettre au conteneur de pouvoir y écrire.

En effet, nous allons connecter ce répertoire à notre conteneur pour que l'instance du mkframework qui y tourne puisse écrire dedans.

III-C - Travailler avec notre image docker

Notre espace de travail créé, nous pouvons lancer notre image docker en liant le répertoire de génération du framework à celui-ci avec la commande suivante :

docker run -d -p 80:80 -v /home/mika/mkProjects:/var/www/html/data/genere mkf:latest

Rappelons que le framework est installé dans le répertoire « /var/www/html », et que son répertoire utilisé pour générer/gérer les applications est « data/genere ».

Notez que l'on précise le port, sinon vous ne pourrez pas y accéder dans votre navigateur.

Ouvrons notre navigateur à l'adresse http://localhost/ :

Vous voyez le builder du mkframework, nous pouvons créer une application pour commencer « monAppli ».

Inscrivons « monAppli » et confirmons avec le bouton « créer » :

Nous voyons bien dans le navigateur notre application, et de l'autre côté, sur notre ordinateur, nous voyons bien un nouveau répertoire dans notre espace de travail :

Nous pouvons désormais ouvrir notre application « monAppli » dans notre IDE préféré.

Nous pouvons ainsi facilement voir notre application via le bouton « voir le site » :

Vous pouvez bien sûr créer autant de projets que vous souhaitez, ils s'ajouteront dans votre espace de travail mécaniquement.

III-D - Se connecter à notre conteneur pendant son exécution

Il peut être utile de se connecter à son instance pour vérifier un problème : par exemple, regardez les logs d'Apache.

Pour cela, il vous faut l'identifiant de l'image qui tourne, lister les images en cours avec :

docker ps

Puis, une fois après avoir récupéré l'identifiantImage de votre conteneur, lancer la commande suivante :

docker exec -it identifiantImage bash

Vous aurez ainsi accès en ligne de commande à votre conteneur (connecté avec l'utilisateur « root ») :

Vous n'avez pas d'éditeur pour modifier les fichiers : ni « vi », ni « nano », vous pouvez utiliser « cat », « more », « head » et « tail » pour visionner des rapports d'erreurs et autre fichier de configuration.

Pensez bien qu'à l'arrêt d'un conteneur, toute modification est perdue.

III-E - Travailler avec des virtualhost

Nous allons ajouter un dns « monAppli.local » qui pointera sur notre première application, pour cela, éditons notre fichier /etc/hosts (de notre ordinateur) :

127.0.0.1       localhost monAppli.local
127.0.1.1       mika-Latitude-3340

Nous pouvons ajouter ainsi autant de dns locaux que nous souhaitons.

Créons un nouveau répertoire « virtualhosts » dans notre espace personnel et ajoutons-y un premier fichier virtualhost « monAppli.conf » contenant le code suivant :

<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName monAppli.local
DocumentRoot /var/www/html/data/genere/monAppli/public
<Directory /var/www/html/data/genere/monAppli/public>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
</VirtualHost>

Comme vous pouvez le lire, nous indiquons qu'en appelant le domaine « monAppli.local », il affichera le site du même nom situé dans le répertoire data/genere.

Mais attention, en l'état nous allons « perdre » le mkframework, car il n'y a plus de virtualhost pour « localhost », ajoutons un fichier localhost.conf avec le code suivant :

<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName localhost
DocumentRoot /var/www/html/
<Directory /var/www/html/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
</VirtualHost>

Ce qui donne dans votre nouveau répertoire :

Enfin, lançons notre conteneur avec un nouveau paramètre, le lien entre notre conteneur et de nouveaux répertoires contenant nos virtualhosts :

docker run -d -p 80:80 -v /home/mika/mkProjects:/var/www/html/data/genere -v /home/mika/virtualhosts/:/etc/apache2/sites-enabled/ mkf:latest

Ici, vous voyez notre nouveau répertoire lié au répertoire de virtualhost de notre conteneur.

Ainsi en stoppant/relançant une nouvelle fois notre conteneur (sans reconstruction), il chargera à chaque fois le contenu de notre répertoire virtualhosts.

Ouvrons un navigateur à l'adresse http://monAppli.local

Cela fonctionne bien sûr avec une seconde application, toujours :

- en ajoutant d'abord le domaine dans /etc/hosts ;

- puis le nouveau virtualhost dans notre répertoire ;

- enfin, en stoppant/lançant de nouveau notre conteneur (pour qu'il recherche la configuration Apache).

Ainsi, on aurait par exemple un nouveau nom de domaine « uneAutreAppli.local » :

127.0.0.1       localhost monAppli.local uneAutreAppli.local
127.0.1.1       mika-Latitude-3340

Dans notre répertorie de virtualhosts :

Et via notre navigateur :

Bien sûr, notre répertoire de travail :

III-F - Travailler avec un serveur MySQL à notre conteneur

III-F-1 - Introduction

En l'état, si vous travaillez avec une base de données, vous pouvez vous y connecter « normalement » en modifiant le fichier de configuration pour y indiquer l'adresse du serveur.

Mais si vous souhaitez embarquer un serveur de base de données comme MySQL/PostgreSQL pour faciliter vos développements (par exemple en déplacement, loin du serveur de base de données)…

III-F-2 - Travailler avec une base de données mysql éphémère

Pour ajouter un serveur MySQL à notre conteneur, il nous faut ajouter les paquets « mysql-server » et « mysql-client ».

Pour cela nous allons modifier notre fichier Dockerfile ainsi :

# This is a comment
FROM debian:jessie
MAINTAINER mika <mika@localhost>
RUN export DEBIAN_FRONTEND=noninteractive
RUN echo "mysql-server-5.6 mysql-server/root_password password  monmotdepasse " | debconf-set-selections
RUN echo "mysql-server-5.6 mysql-server/root_password_again password  monmotdepasse " | debconf-set-selections
RUN apt-get update && apt-get install -q -y apache2 subversion php5 php5-mysql libapache2-mod-php5 mysql-server mysql-client
RUN a2enmod php5
RUN rm /var/www/html/* -f
RUN svn checkout http://subversion.developpez.com/projets/mkframework /var/www/html/
RUN chmod 777 -R /var/www/html/data/genere
CMD /usr/sbin/apache2ctl -D FOREGROUND & /usr/sbin/mysqld

EXPOSE 80

Vous noterez trois nouvelles lignes permettant d'une part de spécifier une installation en mode « non interactive » de notre serveur MySQL, mais également de spécifier et confirmer le mot de passe « root » de notre base de données (habituellement demandé via un prompt).

Je vous invite à remplacer « monmotdepasse » par le mot de passe désiré.

Notez également que dans la ligne CMD, on lance à la fois Apache et MySQL, en effet on ne peut pas séparer ces appels en deux lignes.

Il nous faut reconstruire notre conteneur pour prendre en compte nos modifications avec l'habituelle commande (vu plus haut) :

docker build .

Une fois créé, il nous faut « déplacer » notre tag « mkf » sur cette nouvelle image, pour cela appelez simplement la méthode « tag » :

Pour utiliser cette base de données, nous pourrons simplement indiquer dans nos fichiers de configuration :

- « localhost » comme serveur ;

- « root » comme utilisateur ;

- et « monmotdepasse » comme mot de passe (comme indiqué dans le fichier dockerfile).

Il vous faudra ajouter un script d'initialisation de votre base de données pour chaque projet, par exemple en créant un sous-répertoire « init » dans votre répertoire « mkProjects » qui contiendra des scripts PHP d'initialisation comme celui-ci :

<?php

$sServeur='127.0.0.1';
$sUsername='root';
$sPassword='monmotdepasse';

$sDatabaseCreation='
CREATE DATABASE monApplicationDb;

use monApplicationDb;

CREATE TABLE auteur (
id INT NULL AUTO_INCREMENT,
nom varchar(50) NULL,
prenom varchar(50) NULL,

PRIMARY KEY id (id)
);

';

try {
$oPdo=new pdo('mysql:dbname=mysql;host='.$sServeur,$sUsername,$sPassword);
} catch (PDOException $e) {
die('Erreur connexion:'. $e->getMessage() );
}

$oStmt = $oPdo->prepare($sDatabaseCreation);
$oStmt->execute();

print "bases et tables cr&eacute;&eacutes;s avec succ&egrave;s";

Maintenant, vous pouvez lancer votre nouveau conteneur docker (incluant une base MySQL) :

docker run -d -p 80:80 -v /home/mika/mkProjects:/var/www/html/data/genere -v /home/mika/virtualhosts/:/etc/apache2/sites-enabled/ mkf:latest

Ouvrons notre navigateur, et apprécions dans notre second onglet de voir apparaître notre répertoire « init » précédemment créé.

Cliquons sur le bouton « voir le site » pour voir listé nos scripts de création de base de données :

Si nous cliquons sur notre premier script, celui-ci créera la base de données et la ou les tables nécessaires au développement de votre application.

Vous aurez un message « bases et tables créées avec succès ».

Notre table créée, nous pouvons modifier le fichier de configuration de notre application « monApplication ».

En éditant le fichier mkProjects/monApplication/conf/connexion.php :

;<?php die()?>
[db]

pdoMysqlExple.dsn="mysql:dbname=monApplicationDb;host=localhost"
pdoMysqlExple.sgbd=pdo_mysql
pdoMysqlExple.username=root
pdoMysqlExple.password=monmotdepasse

Ainsi vous pourrez, via le builder, utiliser votre base de données :

Vous voilà prêt pour travailler en toute autonomie avec un serveur web et sa base MySQL.

Si vous souhaitez vous connecter à votre serveur MySQL, vous le pouvez via la ligne de commande suivante.

Connectez-vous d'abord à celle-ci via l'habituel :

Docker exec -it identifiantImage bash

Et une fois connecté à votre conteneur, vous pouvez vous y loguer simplement.

IV - Conclusion

Comme vous avez pu le voir dans ce tutoriel, il est très pratique et facile d'utiliser ce gestionnaire de conteneur avec le mkframework.

Il vous sera ainsi plus confortable d'utiliser cette méthode plutôt que d'utiliser une VM complète et devoir y accéder en ssh/sftp pour coder votre application.

Là, votre IDE préféré pourra ouvrir en local les répertoires de votre application et ceci en consommant très peu de ressources, moins qu'avec un serveur complet.

Le second avantage est de pouvoir préparer un conteneur sur une autre version de PHP pour vérifier la compatibilité de votre application et de faire comme vu ici pointer vos mêmes répertoires applicatifs.

Nous avons vu ici une petite partie de ce gestionnaire de conteneur, vous pouvez lire les articles suivants pour en apprendre plus ici et là.

C'est la même chose pour le mkframework, vous avez d'autres tutoriels sur ce site ici et là, mais également sur celui du framework.

V - Remerciements

Je voudrais remercier chrtophe pour sa validation technique et f-leb pour sa relecture orthographique.