Introduction
Pour le moment, je fais tourner la plupart des sites de dev sur du Docker, ça me permet d’apprendre la techno à petits pas.
Il y a quelques jours, j’ai rencontré une problématique. Ça tombe plutôt bien, car grâce à ça je vais pouvoir introduire ce nouveau chapitre sur la création d’images par commit.
Créer des images par commit n’est pas forcément la meilleure solution car j’ai déjà un peu pu expérimenter les Dockerfile, mais c’est quelque chose qui viendra plus tard. Selon moi, c’est une étape tout à fait logique au regard des problèmes que j’ai pu rencontrer avec Docker.
Rapel sur les images
Je ne vais pas rentrer dans une explication laborieuse d’une image Docker, mais pour faire très simple, une image contient toutes les données et les directives pour construire un conteneur. Pour WordPress par exemple, l’image contient tout ce qu’il faut pour faire tourner l’OS Debian 9 (sur base de Docker hein, ne me fais pas dire ce que je n’ai pas dit), l’application Apache, les binaires PHP, les fichiers de l’application WordPress, ainsi que toutes les configs pour faire tourner tout ce joli monde ensemble.
Si je peux faire une analogie culinaire, je vois une image comme un gros carton avec des ingrédients sur lequel est annotée une recette. Docker, lui, je le considère comme mon cuisto personnel qui va se charger de me préparer un bon petit plat avec ce que je lui ai ramené, tout en respectant la bonne vieille recette de ma grand-mère.
Mise en contexte
Pour la réalisation d’un site internet sur WordPress, j’ai dû faire un traitement photo (flou) sur certaines images. J’ai donc décidé d’utiliser la library imagemagick qui fait assez bien le travail.
Pour me mettre en situation, je vais lancer un WordPress dans un conteneur avec docker-compose.
#je ferme tous les conteneurs en mode bourrin
docker container rm -f $(docker container ls -aq)
#lancement d'un wordpress fonctionnel
docker-compose up -d
Creating wordpress10sec_gol_db_1 ... done
Creating wordpress10sec_gol_wordpress_1 ... done
Après avoir installé le WordPress, je me connecte à l’admin et j’ajoute une image dans les médias de WordPress.
J’ai décidé de traiter directement l’image au chargement d’une page WordPress. Le but ici, c’est vraiment de t’expliquer toute la partie Docker, donc ne t’étonne pas que le code PHP s’exécute à cet emplacement et de cette manière.
Je me place donc dans le fichier functions.php et j’écris ce petit bout de code qui récupère simplement le chemin de l’image ayant l’ID 5 (c’est l’image que je viens d’uploader). Ensuite je tente de l’ouvrir avec Imagick (imageMagick).
<?php
$image_path = wp_upload_dir()["basedir"] . "/" . wp_get_attachment_metadata(5)["file"];
echo $image_path;
$imageRessource = new Imagick($image_path);
print_r($imageRessource);
die();
Le path de l’image est correct mais sans surprise, une fatal error apparait car Imagick n’est pas installé. Ça va être le contexte de départ.
/var/www/html/wp-content/uploads/2019/08/docker_logo.jpg
Fatal error: Uncaught Error: Class 'Imagick' not found in /var/www/html/wp-content/themes/twentynineteen/functions.php:7 Stack trace: #0 /var/www/html/wp-settings.php(443): include() #1 /var/www/html/wp-config.php(95): require_once('/var/www/html/w...') #2 /var/www/html/wp-load.php(37): require_once('/var/www/html/w...') #3 /var/www/html/wp-blog-header.php(13): require_once('/var/www/html/w...') #4 /var/www/html/index.php(17): require('/var/www/html/w...') #5 {main} thrown in /var/www/html/wp-content/themes/twentynineteen/functions.php on line 7
Installation de ImageMagick
Donc là, je dois installer ImageMagick pour résoudre l’erreur, mais tu vas voir que ce n’est pas exactement ça qui pose problème.
En premier lieu, je me connecte au conteneur que je viens de créer.
docker exec -ti wordpress10sec_gol_wordpress_1 bash
Comme pour l’installation de VIM, je vais d’abord mettre à jour la liste des paquets ainsi que les paquets déjà installés.
apt-get update && apt-get install -y
Ensuite il faut télécharger libmagickwand-dev qui est un assez gros paquet et qui va permettre la manipulation d’image. Sans lui, ImageMagick ne s’installera pas.
apt-get install libmagickwand-dev --no-install-recommends
P.S. Le flag –no-install-recommends permet de ne pas considérer les paquets recommandés comme étant des dépendances. Je dois t’avouer que j’ai pas trop creusé la question, j’ai laissé le truc tel quel.
Ensuite j’installe ImageMagick au travers de pecl (dépôts d’extensions pour PHP) et j’appuie sur enter lorsqu’il me demande un préfixe (je sais pas pourquoi, peut-être pour éviter des collisions de noms ?).
#Appuie sur enter
Please provide the prefix of ImageMagick installation [autodetect] :
Une fois installé, un message dans la console me dit que je dois ajouter l’extension à la configuration de PHP.
configuration option "php_ini" is not set to php.ini location
You should add "extension=imagick.so" to php.ini
Dans Docker c’est franchement pas difficile, il suffit de faire :
docker-php-ext-enable imagick
Et comme il y a eu un changement de config, il faut redémarrer Apache.
Image flouttée
Je rafraîchis la page sur mon navigateur et je peux voir que maintenant le warning a disparu. J’adapte un peu le code PHP pour appliquer un flou à l’image et je tente carrément de l’afficher, même pas peur !
<?php
header('Content-type:image/png');
$image = wp_upload_dir()["basedir"] . "/" . wp_get_attachment_metadata(5)["file"];
$blurImage = new Imagick($image);
$blurImage->blurImage(10,15);
echo $blurImage->getImagesBlob();
die();
Quel est le problème ?
Bon tu vas peut-être me dire, mais où est le problème ? Car là tu as installé la bibliothèque pour traiter l’image, tu as réussi à faire le flou, donc qu’est ce qui ne va toujours pas ?
Et bien en fait, quelques jours plus tard, j’ai fermé et supprimé tous les conteneurs avec un rm -f (pour faire des tests). Quand j’ai redémarré mon application WordPress avec docker-compose, c’est là que le drame est apparu. Toutes les modifications que j’avais faites, telles que décrites ci-dessus, ont disparu. Et c’est toute à fait logique, car Docker a reconstruit le conteneur sur base de l’image que j’avais en local et celle-ci n’a jamais changé.
Commit à la rescousse
Pas de panique, même si l’installation de ImageMagick paraissait laborieuse, en réalité je peux presque tout refaire en une seule fois. Je me reconnecte au conteneur et j’exécute la commande suivante.
apt-get update && apt-get install -y \
libmagickwand-dev --no-install-recommends \
&& pecl install imagick \
&& docker-php-ext-enable imagick \
&& apachectl restart
Maintenant, je vais créer ma propre image à partir de l’état de ce conteneur. C’est-à-dire sur base de l’image WordPress et de toutes les modifications que j’ai faites à l’intérieur, en gros l’installation d’ImageMagick.
Pour ce faire, je vais sortir du conteneur et utiliser la commande docker commit en spécifiant le nom du conteneur actuel (qui était déjà custom) et le nom pour ma nouvelle image.
docker commit wordpress10sec_gol_wordpress_1 imagick_wp
Les images
Je vais vérifier si mon image à bien été créée en utilisant une commande qui permet de lister les images disponibles sur mon ordinateur.
La nouvelle image que je viens de créer est en haut de la liste.
REPOSITORY TAG IMAGE ID CREATED SIZE
imagick_wp latest 137cc218f1ba 3 minutes ago 697MB
wiminstall latest 604ba46c5f1e 8 days ago 488MB
node latest 502d06d3bfdf 2 months ago 906MB
node 10 5a401340b79f 2 months ago 899MB
gol 1.0 74eb227208e8 4 months ago 492MB
Utiliser la nouvelle image
Maintenant le but va être de l’utiliser pour le projet. En premier lieu, je ferme tous mes conteneurs (en mode bourrin, histoire d’avoir un truc totalement clean).
docker rm -f $(docker container ls -aq)
J’édite le fichier docker-compose.yml en spécifiant le nom de la nouvelle image que je viens de créer à la place de l’image WordPress.
gol_wordpress:
image: imagick_wp
restart: always
ports:
- 8004:80
environment:
WORDPRESS_DB_HOST: gol_db
WORDPRESS_DB_USER: yann
WORDPRESS_DB_PASSWORD: 123
WORDPRESS_DB_NAME: db-gol-wp
WORDPRESS_TABLE_PREFIX: gol_
volumes:
- /Users/golendercaria/Docker/wordpress10sec/SITE:/var/www/html/
Et je ré-exécute le docker-compose pour relancer mon conteneur.
Et devine quoi, ça marche ! J’ai résolu mon problème. Si jamais je supprime mon conteneur, lors de la reconstruction de celui-ci, tous les changements que j’ai effectués et commités seront bien présents.
Pas de commit du code applicatif
Attention, il est aussi important de savoir que les fichiers qui sont partagés dans le volume et qui constituent le WordPress (wp-config.php, functions.php, etc.) ne sont pas commités dans l’image.
14/06/2021
Yann Vangampelaere - nouslesdevs -