Services gratuits
Intégrer des maps à vos sites QR Code modifiable après impression Lien court personnalisable Générateur de de mot de passe Créer des images pour les réseaux sociaux Créer des palettes de couleurs harmonieuses Déminifiez votre code Créer des fichiers .gitignore facilement Système de réservation pour restaurantsSommaire
Coucou les petits loups 😁.
Merci d'avoir cliqué sur cet article, on retourne dans la technique ? Ça vous tente ? En tout cas, j'espère qu'il vous plaira.
Sinon ça va vous ? Moi c'est la pleine forme !
Vous connaissez Caddy, c'est un serveur web moderne, écrit en Go (oui oui le langage compilé qui génère des binaires statiques là...).
Et bien aujourd'hui, on va bricoler sa surcouche pour PHP, FrankenPHP.
D'ailleurs petite info comme ça, le fait que FrankenPHP utilise Caddy, ça nous donne accès à des choses sympa comme les "Early hints", vous ne savez pas ce que c'est ? Allez hop hop hop, on fait des recherches.
Vous êtes prêt ? Alors, c'est parti !
Bon alors, déjà, ce paragraphe serait peut-être plus trop vrai prochainement, vu qu'on va sûrement tous passer aux conteneurs par Apple.
Je n'ai pas encore regardé, mais j'imagine que c'est prometteur, pour le moment je n'ai pas trop le temps de bouger ma stack (il y en a des trucs, je vous le dis moi) sur Apple container.
Revenons dans le présent et parlons de Docker sous macOS.
C'est un problème qui ne date pas vraiment d'hier, après je n'ai pas refait de benchmark sur ce sujet depuis, tout simplement car ma solution fonctionne nickel depuis des années.
Mais par défaut, quand vous montez un volume qui en fait est un dossier qui est sur votre Mac, vous allez avoir des lenteurs plutôt atroces...
Au passage, ma solution à ça est de créer un "Sparse Bundle" avec un système de fichiers qui respecte la casse sur macOS (comme Linux lui respecte la casse), et de mettre tous mes projets dedans...
Et donc pour ça, j'ai besoin de faire tourner PHP nativement sur macOS et non pas dans un Docker...
Si vous voulez un cas concret de ce que je vous dis, parlons du cache de Symfony...
Symfony est un framework avec lequel c'est un vrai plaisir de développer mais pour ça, on a le profiler...
Et donc, pour que tout ça fonctionne bien et nous donne la meilleure expérience de développement possible, Symfony écrit et lit beaucoup dans le dossier var/cache.
Et le fait de mettre ce répertoire dans un ramdisk ou un volume non monté ?
Alors, oui c'est une solution... mais vous savez moi je suis un gros lama...
Que je vous explique, je l'aime bien mon petit PHPStorm, même s'il est lourd.
Et pour facilement aller voir comment les choses fonctionnent, il faut avouer qu'avoir les vendor directement sur le Mac, c'est pratique.
Il y aurait la solution de mettre les vendor sur le Mac et dans une image non montée Docker, ou encore des trucs comme rsync (que j'ai testé à l'époque), mais tout ça, ça fait usine à gaz.
Simplement plusieurs versions de PHP, installées avec Homebrew, ça marche très bien, après pour les extensions pecl fait très bien le travail.
Une fois qu'on a ce setup, il suffit de faire :
Et ça fonctionne parfaitement, enfin, ça fonctionnait parfaitement, parce que maintenant, il y a FrankenPHP.
FrankenPHP est un serveur d'applications PHP moderne, construit sur Caddy FrankenPHP: the modern PHP app server, ce fameux serveur web écrit en Go dont je vous parlais juste avant.
Mais FrankenPHP ne se contente pas d'être une simple surcouche à Caddy. Il permet d'embarquer l'interpréteur PHP directement dans le binaire du serveur web.
Contrairement à PHP-FPM qui redémarre complètement votre application à chaque requête (autoloader, construction du container, etc.), le mode worker de FrankenPHP permet à votre application de rester en mémoire et de réutiliser les éléments qui peuvent l'être entre les différentes requêtes HTTP.
Selon une analyse réalisée par Sylius, l'utilisation du mode worker de FrankenPHP réduit les temps de réponse de 80 %, tout en divisant par 6 le nombre de machines nécessaires pour servir le même nombre d'utilisateurs.
FrankenPHP utilise les goroutines de Go (on le voit sur la page officielle du projet), ce qui lui permet de gérer la concurrence de manière très efficace. Votre application peut d'ailleurs être servie telle quelle, même si elle n'est pas compatible avec le mode worker.
Le serveur démarre avec une commande simple, et il suffit d'un binaire pour tout faire fonctionner, sans service externe (il n'y a pas que ce mode, mais en production, c'est plutôt bien pratique et ça entre bien dans la philosophie de Docker).
Le plus cool ? FrankenPHP peut surveiller vos fichiers et redémarrer automatiquement les workers en arrière-plan lorsqu'un fichier change.
Mercure permet de faire du temps réel, dans vos applications, il est connu dans l'écosystème de Symfony... (Turbo tout ça tout ça)
Mercure utilise les Server-Sent Events (SSE) pour pousser des événements en temps réel du serveur vers les clients. Pas besoin de bibliothèque JavaScript particulière, le navigateur sait déjà faire !
Et, c'est directement intégré à FrankenPHP.
Bref, on est sur un serveur web pour PHP nouvelle génération.
D'ailleurs sur Dockerhub vous pouvez voir des images de FrankenPHP prêtes à l'emploi.
Si vous utilisez Windows Subsystem for Linux ou tout simplement Linux, je pense que vous devriez complètement utiliser ces images Docker pour vos projets en dev.
Et oui, Kévin Dunglas met à disposition FrankenPHP sur Homebrew.
Tout simplement car lors de mes tests, quand j'ai voulu l'utiliser, il venait avec PHP 8.4, et dans mon cas j'avais besoin d'une version plus ancienne de PHP.
Le projet pouvait sûrement fonctionner sur du PHP 8.4 mais je n'avais pas envie de tenter le diable, je voulais juste pouvoir travailler (et ça me permettait de mieux comprendre FrankenPHP).
On en a déjà parlé plus haut, le mode worker de FrankenPHP nécessite PHP "thread-safe" (le ZTS) parce que FrankenPHP utilise les goroutines de Go pour gérer plusieurs requêtes en parallèle dans le même processus.
Contrairement à PHP-FPM qui crée des processus séparés (chacun avec sa propre mémoire isolée), FrankenPHP démarre plusieurs workers sous forme de threads qui persistent entre les requêtes. Ces threads partagent certaines zones mémoire, ce qui nécessite absolument que PHP soit compilé en mode "thread-safe".
En mode Thread-Safe, PHP peut être un tout petit peu plus lent, ce qui est compensé par la stack avec FrankenPHP.
Également, il est possible que certaines extensions ne fonctionnent pas correctement avec PHP ZTS.
Vous pouvez recompiler votre PHP ou directement utiliser ce tap Homebrew.
Comme on en a déjà parlé, si vous voulez la dernière version de PHP, alors utilisez simplement Homebrew, sinon...
Sinon, peu importe le mode de compilation, commencez par sortir votre meilleur "git clone" pour récupérer le code de FrankenPHP en local :
Bon puis... forcément après ça il faut faire un légendaire "cd" pour aller dans le dossier que vous venez de créer (incroyable, n'est-ce pas ? 😝)
Là dans notre binaire on a directement PHP, attention cependant XDEBUG n'est pas compatible avec ce mode-là.
Si vous regardez dans le code source, vous verrez un petit fichier "build-static.sh", il porte bien son nom n'est-ce pas ?
Ce fichier (build-static.sh) va vous permettre de créer un fichier binaire qui contient l'ensemble de ce qu'il vous faut pour faire tourner PHP et vous pouvez même choisir les extensions qu'il vous faut, par contre attention, avec cette méthode, vous recompilez entièrement PHP, donc, c'est très long.
Avant de l'utiliser on lui donne des variables d'environnement, la version de PHP, ou encore les extensions que vous voulez...
Si vous voulez voir la liste complète des variables d'environnement, elle est disponible ici.
Oui, oui, vous ne rêvez pas je me fais reprendre parce que la version 8.3 de PHP est dépréciée.
Une fois la compilation terminée vous aurez un joli binaire qui contient tout ce qu'il faut pour faire tourner votre serveur Caddy et votre application PHP.
Dans ce mode, on utilise PHP disponible sur notre système (le ZTS installé précédemment), et on peut aussi utiliser xdebug du coup 😁.
Bon, bah déjà il nous faut un PHP "Thread safe" sur notre système :
Ici, c'est la version 8.3 que j'installe mais vous pouvez le faire avec la 8.2 ou encore la 8.4 (si vous êtes dans le futur 8.5...).
Après, ma méthode n'est pas celle recommandée par Kévin Dunglas (le développeur de FrankenPHP), ayant déjà compilé quelques applications Go dans le passé, j'ai juste utilisé un bon gros "go build" basique...
Bon, ça, c'est ma méthode de gros bourrin, mais dans la doc officielle, ils recommandent d'utiliser xcaddy.
Avec xcaddy ça donne un truc du genre (c'est copié collé de la doc).
L'intérêt avec xcaddy c'est de pouvoir ajouter les modules, après je n'ai pas testé, j'ai juste fait un "go build" à l'arrache moi 😝.
Une fois que vous avez votre merveilleux binaire disponible (le static ou dynamique), vous pouvez le placer dans un endroit comme "/usr/local/bin/frankenphp" ou "/usr/bin/frankenphp".
Puis pour lancer frankenPHP, il faut lui donner quelques variables d'environnement et son Caddyfile (sa config, que vous devez créer).
Pour ce qui est du Caddyfile, je vous laisse chercher, ça vous fera un peu de boulot (no mé oh ! 😝).
Notre petit tour d'horizon de FrankenPHP est désormais terminé.
L'idée de se prendre le chou à compiler à la main est de comprendre comment ça fonctionne, et, comprendre l'intérêt de l'utiliser.
Vous saviez vous qu'il y avait un mode Thread Safe de PHP ? Perso ça fait tellement longtemps que j'utilise FPM que bah... non, je ne savais pas.
Allez, à la prochaine pour un autre article, en attendant, portez-vous bien 🤩.