Le binaire Symfony à l’usage

Après notre premier article présentant le binaire Symfony, voici enfin la suite ! Nous allons revenir sur le projet où nous l’avons utilisé et vous présenter les détails de cette mise en place.

Notre projet 🙌

Pour ce projet, nous avons deux applications Symfony : le front et l’API. À chaque requête, le front fait plusieurs appels à l’API pour récupérer son contenu. Si l’API est lente, le front l’est donc également.

Docker en place ! 👨‍🔧

Chez JoliCode, nous utilisons une stack Docker commune à nos projets (avec fabric pour aider à la gérer). Et, même avec l’utilisation de Dinghy, nous n’arrivons pas à avoir des performances intéressantes sous macOS (sans modifier nos fichiers docker-compose) :

SlowPerfs

D’un côté toutes les solutions autour de docker (Docker for Mac, dinghy, …) sont limités par des soucis d’IO, or Symfony en mode dev en est très consommateur. Cache ou pas, on est de toute manière plus lent qu’en natif. Et le fait d’avoir deux applications qui communiquent entre elles amplifie grandement le problème (surtout que nous sommes en mode dev). Sur certaines pages du site, le front peut appeler 5 endpoints de l’API. Nous devions donc réduire l’impact de ces lenteurs pour nos développeurs sous macOS car nous ne pouvions pas réduire le nombre de ces appels API.

Le binaire Symfony à la rescousse 👨‍🚒

Nous avons donc cherché à remplacer notre stack Docker par un autre outil. L’outil le plus simple à utiliser est le WebServerBundle, mais celui-ci utilise le serveur Web inclus dans PHP et est donc très limité : pas de nom de domaine, pas d’HTTPS, … Nous avons dû trouver un nouveau candidat. Nous nous sommes alors tournés vers le binaire Symfony ! Et en voici le résultat :

BetterPerfs

Nous pouvons noter une claire amélioration des performances et cela devient plus agréable de travailler dans ces conditions. Pour continuer, nous verrons les différents problèmes que nous avons rencontrés et comment les gérer !

Et comment en sommes-nous arrivé là ? 🔄

Nous partons du principe que nous avons une stack minimale avec le binaire Symfony telle que décrite dans mon premier article et nous allons régler les soucis que nous rencontrons un par un à partir de maintenant.

Un nom de domaine, mais pas le bon TLD 😢

Tout d’abord, le binaire Symfony nous impose un TLD en .wip alors que nous utilisions un .test. Nos services extérieurs (Google Maps, Adyen, …) étaient déjà configuré avec ce TLD et, pour éviter de complexifier notre projet, nous ne pouvions pas nous permettre d’avoir des configurations différentes entre macOS et les autres développeurs. Après un peu de recherche, nous avons pu voir que l’on pouvait changer ce TLD en allant modifier le fichier ~/.symfony/proxy.json comme suivant :

{
  “tld”: “test”, // ici
  “port”: 7080,
  “domains”: {
    “api.application”: “/home/foo/dev/application/project/apps/api”,
    “www.application”: “/home/foo/dev/application/project/apps/front”
  }
}

Ensuite, il vous suffit de couper le proxy et le relancer et vous voilà avec votre nouveau TLD. 🎉

Attention ⚠

Après ce changement, tous les projets utilisant le binaire utiliserons ce même TLD, il est donc important de bien unifier les TLD de vos projets. 😉

Et comment on gère PHP maintenant ? 🤔

Autre souci, le binaire utilise le PHP local, ce qui rend la gestion des versions de PHP plus compliquée. PHP 7.1 pour un projet, PHP 7.3 pour un autre… Heureusement, le binaire Symfony a mis en place un fichier .php_version.

Information 💡

Le binaire Symfony va chercher ce fichier .php_version depuis la racine de votre projet puis remonter les dossiers jusqu’à le trouver. Si vous avez un dossier apps avec vos applications dedans, il vous suffit donc de mettre le fichier ici. 😉

Le contenu du fichier correspond simplement à la version de PHP à utiliser. Pour savoir quelles versions de PHP le binaire Symfony peut utiliser sur votre système, vous pouvez faire la commande suivante symfony local:php:list :

symfony-local:php:list

Pour installer plusieurs versions de php sur votre macOS, vous pouvez soit passer par Homebrew avec la commande: brew install php@7.2 ou via php-osx avec la commande: curl -s https://php-osx.liip.ch/install.sh | bash -s 7.2 (en remplaçant 7.2 par la version dont vous avez besoin).

Nous vous recommandons aussi d’avoir l’extension php-fpm pour les versions de PHP que vous utilisez sur vos projets pour que le binaire Symfony utilise directement fpm au lieu du serveur CLI moins performant.

Mais nous avons plusieurs applications ! 🤹

Dernier souci que nous avons rencontré : le multi-app. Comme dit plus tôt, nous avons une stack avec un front et une API qui sont toutes les deux des applications Symfony. Il y a donc deux applications qui tournent avec le binaire Symfony et qui doivent discuter entre elles.

Tout d’abord, pour que le front puisse parler avec l’API, nous devons lui indiquer le proxy à utiliser. Pour ce faire, nous ajoutons un fichier .env.local avec le contenu suivant :

HTTP_PROXY=http://127.0.0.1:7080/
HTTPS_PROXY=http://127.0.0.1:7080/

Information 💡

Le proxy du binaire Symfony est en HTTP mais il fait passer du traffic HTTPS (et HTTP, bien sûr)

Ensuite, nous devions lancer les applications une par une ce qui nous faisait perdre pas mal de temps. Nous avions mis en place un script avec fabric (il est totalement possible de faire quelque chose de similaire avec un Makefile) pour lancer toutes nos applications en même temps. Il suffit de jouer avec les arguments du binaire Symfony et cela donne quelque chose proche de :

symfony local:sever:start --dir=project/apps/api --daemon
symfony local:sever:start --dir=project/apps/front --daemon

Pour aller plus loin ! 🚀

Nous n’utilisons pas tout ce que permet le binaire Symfony vu que notre projet a débuté bien avant sa mise en place et que nous avions déjà beaucoup d’existant basé sur Docker et fabric. Mais voici quelques pistes pour aller encore plus loin avec le binaire Symfony.

Une intégration Docker 🐋

En complément des fonctionnalités déjà présentées, le binaire Symfony a récemment eu une mise à jour pour y ajouter une intégration Docker. Comment cela fonctionne ? Le binaire détecte les containers qui tournent pour le projet et va injecter les variables d’environnement correspondantes dans votre application Symfony. Par exemple, pour le conteneur MySQL, il va injecter le DSN directement dans la variable d’environnement correspondante : DATABASE_URL="mysql://root:password@127.0.0.1:3306/?sslmode=disable&charset=utf8” dans notre cas.

Nous avons testé cette intégration sur notre projet mais à cause de notre stack Docker complexe, le binaire n’a pas pu détecter le projet automatiquement, nous avons donc ajouté la variable d’environnement “COMPOSER_PROJECT_NAME” pour indiquer le nom du projet dans Docker au binaire Symfony. Suite à cette correction nous avons pu lancer le projet, mais toutes nos commandes passent déjà dans fabric, et n’utilisent pas le binaire symfony, du coup nous n’avions pas d’intégration Docker en CLI, ce qui nous a empêcher d’utiliser l’intégration sur le projet. Mais si votre stack utilise cette intégration dès le début je pense que c’est une fonctionnalité très intéressante.

Pomdok 🍏

Nous avons rencontré deux soucis qu’il était nécessaire de régler :

  • Avec plusieurs applications, nous sommes obligés de les démarrer une par une ;
  • Lorsque l’on utilise un TLD différent sur deux projets, nous devons modifier le fichier JSON de configuration à chaque fois que l’on change de projet.

C’est pour cela que nous avons développé pomdok. Le principe de base est d’avoir une configuration par projet et non partagé pour tout l’ordinateur, comme le fait le binaire Symfony, et de la mettre à jour à chaque fois que nous changeons de projet. Sur un projet, il suffit de lancer pomdok init pour copier la configuration de votre projet uniquement dans le fichier ~/.symfony/proxy.json (configuration du binaire Symfony). Ensuite la commande pomdok start permettra de lancer tous les projets contenus dans le fichier ~/.symfony/proxy.json. Qui plus est, la commande pomdok init fonctionne depuis n’importe quel dossier de votre projet, il remontera les dossiers jusqu’à trouver la configuration. Pour la commande pomdok start, vous pourrez même la lancer en dehors de votre projet vu qu’elle se base sur le fichier du binaire Symfony.

Pomdok est disponible sur Homebrew et d’autres fonctionnalités existent, je vous laisse consulter la page du projet pour plus d’informations !

Conclusion

Comme dit dans le précédent article, nous avons commencé à étudier le binaire Symfony principalement pour nos utilisateurs de macOS et, comme vous pouvez le voir ici, le résultat a été direct. Avec ces dernières astuces, vous devriez être capables de passer votre stack sous le binaire Symfony ! Cette technique relance la question de la stack de développement ISO-prod, mais je pense que malgré nos containers Docker, nous étions déjà rarement ISO-prod (sauf dans les cas où Docker est en production) et l’utilisation du binaire Symfony ajoute aussi de la complexité à votre stack (que je tente de réduire via pomdok).

Bref, cette solution est loin d’être parfaite, et nous aurions surement pas réfléchi à cette technique si les développeurs sous macOS n’avaient pas eu de si gros problème de performance. Aujourd’hui cela permet à nos développeurs macOS d’être plus efficaces et moins râleurs, donc déjà une belle réussite. 🎉

blog comments powered by Disqus