Comment dockériser un projet Symfony (base mysql) ?

Dans cet article, je vous explique comment faire fonctionner un projet Symfony 6 sur Docker utilisant php 8.1, une base mysql 8.0 et mailhog pour l’envoi automatique de courriels.

Ce tutoriel proposent des solutions à ces problèmes que j’ai rencontrés :

  • Créer un container pour apache et php et le configurer
  • Créer un container pour mysql et le configurer
  • Créer un container phpmyadmin et le configurer
  • Créer un container pour mailhog et le configurer
  • Créer un container pour l’application Symfony et le relier à la base de données
  • Installer les extensions php nécessaires au projet
  • Installer les extensions nécessaires à l’exécution des fonctions de traitement d’images (imagecreatefromjpeg, imagecreatefrompng, imagewebp)
  • Installer composer et symfony sur le container
  • Donner les permissions à un utilisateur pour permettre le téléversement d’images

Versions utilisées dans le projet : Symfony 6.1, php 8.1, mysql 8.0.34.

Versions sur Docker : php 8.2, mysql 8.0, docker 24.0.6, phpmyadmin 5.2.1

Système d’exploitation : Ubuntu

Fonctionnalités de symfony : traitement des images, data fixtures, ajout, modification et suppression d’éléments à l’aide de routes, envoi de courriers électroniques automatique.

A quoi sert Docker ?

Docker permet de créer des containers fonctionnant chacun avec une technologie propre. On peut par exemple, créer un container avec php 8.2, un autre avec php 7.3, un autre avec un serveur node, un autre avec java… Les possibilités sont infinies. Docker est donc un formidable outil pour tester une application dans des environnements différents avant production. Dans notre exemple, vous avez dû remarquer que les versions de php sont différentes sur le projet et sur docker. Nous allons donc vérifier au passage si le projet fonctionne bien avec une version légèrement supérieure. Imaginez qu’une entreprise ait une application en php 7 et qu’elle veuille passer en version 8. Plutôt que de reparamétrer un serveur local pour la tester, elle pourra le faire en contruisant des containers docker. Docker permet donc de gagner de beaucoup de temps car il lui suffira de démarrer les containers dont elle a besoin pour tester l’application.

Installer Docker sur ubuntu

Comme ma machine n’est pas compatible avec la virtualisation, je n’ai pas pu installer docker desktop. En revanche, docker compose et engine fonctionnent. Pour les installer, je vous recommande de suivre la documentation officielle.

Créer l’image docker

Pour créer une image docker, il faut créer un fichier intitulé Dockerfile. Nous le créons à la racine du projet symfony que l’on veut dockériser.

Le fichier Dockerfile contient une série de commandes. Celui que l’on crée va permettre de :

  • télécharger apache, php 8.2 et les extensions dont nous avons besoin. Nous utilisons les extensions php de ce script, ainsi que gd. Elles permettent de faire fonctionner les fonctions php liées au traitement des images (imagecreatefromjpeg, imagecreatefrompng et imagewebp). En complément nous installons intl et la bibliothèque libicu-dev dont elle dépend, mysqli et pdo_mysql pour faire fonctionner la base de données. A noter : pdo est déjà installée par le script.
  • paramétrer le fichier php.ini : nous modifions la taille maximale des fichiers téléversés.
  • installer composerinstaller symfony pour pouvoir utiliser la commande symfony.
  • copier l’intégralité du projet dans le container apache
  • configurer le container apache
  • définir le répertoire de travail par défaut à l’exécution du serveur
  • donner les permissions nécessaires au téléversement des fichiers.

Voilà à quoi ressemble le fichier Dockerfile

Avant de construire l’image, il faut rajouter dans un répertoire /php/ créé à la racine de votre projet, ce fichier qui permettra de configurer apache et celui-ci qui permet de configurer php. Vous pouvez bien sûr le remplacer par votre configuration.

Vous avez pu remarquer que mysql, phpmyadmin, et mailhog n’ont pas été installés avec le fichier Dockerfile. Nous allons donc en complément créer un deuxième fichier, toujours à la racine du projet. Il aura pour nom docker-compose.yaml

Il permettra de construire plusieurs containers à la fois tout en les configurant. Il va :

  • créer et configurer le container mysql à partir d’une image qui provient directement de docker hub. Nous n’avons pas besoin de la construire avec un fichier Dockerfile. Nous définissons son nom (ici « database »), le port sur lequel il s’exécutera, ainsi que les paramètres de connexion (nom de base de données, nom et mot de passe de l’utilisateur, ainsi que le mot de passe de root, « secret » par défaut.
  • créer le container de l’application à partir de l’image que l’on a construite précédemment. Le champ build indique le chemin du fichier Dockerfile dont nous avons besoin. Nous définissons seulement le port 8080. Nous rajoutons le paramètre « depends_on » qui renvoie au nom du container de la base de données (« database »).
  • créer le container php à partir de l’image déjà construite. Là encore, nous indiquons dans build le chemin du fichier Dockerfile qui contient l’image.
  • créer et configurer le container de phpmyadmin. PMA_HOST correspond au nom du container de mysql, « database ». Phpmyadmin s’exécutera directement sur le port 8000. Il vous faudra renseigner le nom et le mot de passe de l’utilisateur. Si vous renseignez les champs PMA_USER et PMA_PASSWORD, phpmyadmin se connectera automatiquement avec les identifiants saisis.
  • créer et configurer le container de mailhog. Le serveur utilisera 1025 pour l’envoi et 8025 permettra de visionner les messages.

Voici à quoi ressemble le fichier docker-compose.yaml

Avant de construire et d’exécuter les containers, il faut modifier le fichier .env

A la ligne 20, il faut modifier « localhost » en « database » si c’est le nom que vous avez donné au container. Sinon, remplacez-le par le nom que vous avez utilisé.
A la ligne 21, il faut remplacer localhost par le nom du container de mailhog. Ici, c’est « cont_mailhog ».

Il faut aussi désactiver le port 3306 car il est par défaut utilisé par mysql du serveur local. Tapez la commande :

sudo lsof -t -i:3306

Vous obtiendrez le pid du port 3306. Tapez ensuite pour libérer le port :

sudo kill -9 {pid}

Pour vérifier si l’installation de php est correcte, nous allons créer un fichier phpinfo.php dans le sous-répertoire /public/ du projet. Vous pouvez créer le vôtre ou télécharger celui-là si vous ne savez pas le faire.

Dans le terminal, plaçons-nous à la racine du projet Symfony. Nous pouvons maintenant construire et démarrer les containers en exécutant la commande :

docker compose up -d --build

La première fois, c’est assez long (environ 30 min) mais cela peut varier en fonction de votre matériel ou de votre connexion.

Une fois les containers construits, ils démarrent automatiquement. Vous devriez avoir quelque chose qui ressemble à ça.

Vous remarquez qu’un réseau est automatiquement créé. Regardons maintenant ce que docker a créé comme containers en tapant la commande :

docker ps

Il a bien créé un container pour l’application (projettestweb-app), un pour mysql, un pour mailhog, un pour phpmyadmin et un pour php. Chacun est identifié par un un id. C’est cet élément dont nous aurons besoin pour les exécuter.

Vérifications de l’installation de PHP, de ses extensions, de sa configuration

Vérifions si tout fonctionne et si toutes les extensions dont nous avons besoin ont bien été installées en ouvrant ce lien dans votre navigateur :

http://localhost:8080/phpinfo.php

Le serveur web s’exécute correctement. La version de php correspond bien à celle que nous avons installée.

Quant aux extensions dont nous avons besoin (gd, intl, mysqli, pdo, pdo_mysql), elles sont bien activées.

Pour finir, vérifions si notre fichier de configuration php-custom.ini a bien été pris en compte.

Dans le module Core, recherchez la ligne upload_max_filesize. Sa valeur doit être égale à 256M.

Vérification de la connexion à la base de données

Avec phpmyadmin

Vérifions maintenant si nous pouvons nous connecter à la base de données avec phpmyadmin en ouvrant ce lien :

http://localhost:8000

Vous devriez pouvoir vous connecter avec l’utilisateur et le mot de passe que vous avez créés ou avec l’identifiant « root » et le mot de passe « secret ».

Une fois connecté, vérifiez si la base de données du projet a bien été créée. Ici, symfonyTest. Vous pouvez regarder son contenu.

Avec le terminal

Vous pouvez aussi utiliser le terminal si vous préférez en exécutant le container de mysql. il faut taper la commande (container_id correspond bien sûr à l’id du container mysql) :

docker exec -it {container_id} bash

Pour accéder à la base de données du projet, tapez :

mysql -u {utilisateur} -p {nom_bdd}

Ici mysql -u utilisateur -p symfonyTest

Renseignez le mot de passe puis afficher les tables en tapant :

show tables;

Vous pouvez quitter mysql en tapant exit; puis exit pour sortir du container.

Créer les tables

Si la base est vide, il faut créer les tables en exécutant la migration Symfony. Pour cela, tapez ceci pour exécuter le container php (container_id est cette fois-ci l’id du container php) :

docker exec -it {container_id} bash

Puis pour lancer la migration :

symfony console doctrine:migrations:generate

Vous obtenez un nom de fichier ‘DoctrineMigrations\VersionXXXXXXXXXX’.

Copiez ce nom puis tapez cette fois :

symfony console doctrine:migrations:execute --up {'DoctrineMigrations\VersionXXXXXXXXXX'}

Vérification du serveur mailhog

Vérifions maintenant que nous pouvons nous connecter au serveur de mailhog en ouvrant ce lien :

http://localhost:8025

Vérification des fonctionnalités du projet

Nous vérifierons ces fonctionnalités :

  • Est-ce que les routes s’exécutent bien (get, post, put, delete) ?
  • Est-ce que le projet se connecte bien à la base de données ?
  • Est-ce que le serveur d’envoi mailhog fonctionne bien ?
  • Est-ce que le téléversement des images de plusieurs formats différents fonctionne bien ?

Si votre projet ne permet pas de faire tout ça, vous pouvez télécharger celui qui sert d’exemple ici.

Si vous l’utilisez, il faudra décomposer le projet que vous utilisez jusqu’ici en tapant :

docker compose down

Décompressez ou clonez le projet qui sert d’exemple. Placez-vous à sa racine. Puis, après avoir personnalisé les fichiers .env et docker-compose, éventuellement apache.conf et et php-custom.ini, composez les containers en tapant :

docker compose up -d --build

Quand les containers ont démarré, lancez le projet en ouvrant ce lien :

http://localhost:808o/login

Pour pouvoir créer un utilisateur et une catégorie de produits automatiquement, le projet utilise des data fixtures. Leur exécution permettra de créer plusieurs utilisateurs dont un « toto@email.com » avec le mot de passe « 123456 », ainsi que la catégorie « Ordinateurs portables » qui dépend d’une autre catégorie, « Informatique ».

Avant de les créer, faites la migration pour créer les tables (voir plus haut). Puis, tapez, toujours dans le container php :

symfony console doctrine:fixtures:load

Vérifiez avec phpmyadmin si les tables ont bien été crées et remplies. Seules users et categories ont reçu des données.

Vous pouvez maintenant vous connecter en tant qu’admin avec l’email « toto@email.com » et le mot de passe « 123456 ».

Une fois connecté, vous remarquez que l’utilisateur n’est pas activé. Cliquez sur « Renvoyer le lien d’activation ». Vous devrez voir affiché « Email renvoyé ». Vérifiez si vous avez bien reçu le message sur le serveur web mailhost :

http://localhost:8025

Dans inbox, vous avez normalement reçu un message intitulé « Activation de votre compte ». Ouvrez-le et cliquez sur le lien d’activation. Vous retournez automatiquement sur le site et le message « le token est valide apparait sur fond vert. »

On peut en déduire que le serveur mailhog émetteur fonctionne avec le port 1025. Et comme nous avons pu nous connecter avec la base de données, la connexion fonctionne bien.

Nous avons utilisé la route /login qui est en GET.

Essayons maintenant de créer, de modifier et supprimer un produit. Ouvrez le lien :

http://localhost:8080/admin/products/add

Dans le premier essai, nous mettrons un titre, une description et une photo au format png qui n’a rien à voir. Normalement, après l’avoir ajouté, vous devriez obtenir le message « Produit créé avec succès » sur fond vert. Nous allons maintenant modifier le produit pour avoir des données réalistes. Dans phpmyadmin, récupérez l’id du produit que vous avez créé, puis ouvrez le lien en ajoutant l’id de votre produit à la fin comme sur cet exemple :

http://localhost:8080/admin/products/edit/103

Mettez le texte que vous voulez pour le titre et la description, supprimez l’image précédente et en ajoutez-en une nouvelle au format jpeg.

Encore une fois, tout devrait bien se passer.

Vous pouvez afficher le produit en ouvrant cette page puis en cliquant sur « voir les produits »:

http://localhost:8080/

Il nous reste une dernière chose à faire : tester la suppression du produit en ouvrant cette page (remplacez 103 par l’id du produit) :

http://localhost:8080/admin/products/delete/103

Le produit ainsi que ses images sont supprimées dans la base et sur le disque.

Conclusion

Docker nous a permis de confirmer que le projet fonctionne bien avec php 8.2, sans que nous ayons eu besoin de modifier le code existant. A la place de mysql, nous aurions pu monter une base postgresql pour comparer la performance des deux systèmes. Nous aborderons ce sujet prochainement.

Soyez le premier à commenter

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.