Création d'images via commit

A la découverte de Docker partie 10

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 ?).

pecl install imagick
#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.

apachectl restart

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.

docker image ls

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.

docker-compose up -d

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 -

Sinon jete un coup d’oeil aux autres catégories

Ma boîte aux lettres

Tu veux me demander quelque chose ?