Utiliser Symfony avec Docker sur mac OS

written by Romaric 12 octobre 2018

Docker, qu’est-ce que c’est?

Docker est un outil open-source de container. Depuis sa première version en mars 2013, Docker s’est imposé comme une référence sur ce marché qu’il a créé, ou du moins très largement popularisé.

Mais qu’est-ce qu’un container/conteneur?
Un container est un processus Unix « isolé », c’est-à-dire qu’il n’a accès qu’à des ressources (mémoire, fichiers, réseau…) délimitées. On peut le comparer à une version très light d’une Machine Virtuelle (comme VirtualBox, Vagrant…), où un seul processus est exécuté au sein d’une image. Il ne voit et n’a accès qu’à ce qu’il y a dedans, fichiers, ports, mémoire… Si on arrête le processus, le container meurt, l’image est réinitialisée, les fichiers dedans disparaissent. On peut bien sûr monter un répertoire dans le container, mais les concepts de base sont l’isolation et l’aspect éphémère. On ne modifie pas un container qui tourne, on l’arrête, détruit son image et on la reconstruit avec une nouvelle configuration.

Derrière Docker, nous retrouvons des outils Unix assez anciens, mais à l’usage complexe.
Docker a su les rassembler, pour proposer une solution simple à utiliser. À l’usage, on déclare comment construire le container – par exemple de quelle distribution partir, quelles dépendances installer, quels fichiers copier ou monter, quel processus faire tourner – et Docker s’occupe ensuite de le build et de l’exécuter.

Les avantages des containers sont nombreux. Plus spécialement, dans une agence web, nous retrouvons tous les jours ceux-ci:

  • automatisation: un poste de travail vierge peut être préparé en quelques minutes, le temps d’installer Docker et de le démarrer ;
  • résilience, fiabilité: pas de crainte qu’une mise à jour de son OS casse son installation d’Apache, ou qu’un projet ne fonctionne plus dans 6 mois parce qu’on a changé de version de MySQL ;
  • flexibilité: on se sent plus libre d’utiliser les versions les plus appropriées (PHP5 pour le legacy ou PHP7.3 cutting edge…), et au besoin plus d’outils (ElasticSearch…), chaque projet étant isolé et rapide à installer ;
  • documentation: la « configuration » Docker décrit quoi installer et quels paramètres injecter.

Finalement, Docker peut également être utilisé en production. Les outils alors sont alors un petit peu différents, et on préfèrera certainement avoir des images différentes, avec par exemple une configuration de PHP ou de MySQL réglée pour la production. Ce point sera l’objet d’un futur article 🙂

Les concepts

La plupart des tutoriels montrent comment démarrer un seul container en ligne de commande, ou bien comment spécifier son image de zéro. En réalité, pour une application web courante, on aura besoin de plusieurs containers (d’une part Apache avec PHP et d’autre part MySQL, typiquement), et il est possible d’utiliser des images pré-construites.

Une image est spécifiée dans un Dockerfile, un fichier composé majoritairement de script bash, qui spécifie quoi installer et comment.

Vient ensuite le Docker Hub, qui est grossièrement un répertoire de  Dockerfile déjà écrits, pour par exemple, avoir PHP avec Apache (par ici). Il est conseillé dans un premier temps de se limiter aux images officielles (« OFFICIAL REPOSITORY » mentionné en haut de page). Sur chaque page est décrit comment utiliser l’image, c’est une lecture recommandée.

Un setup simple

La première étape est d’installer Docker. On va démarrer avec « Docker Desktop », qui comprend le moteur Docker, les outils nécessaires, et une petite UI pour lancer et mettre à jour le service. Cela se télécharge ici, et cela existe pour mac OS ou Windows. Pour Linux, on installera directement le moteur, les instructions pour Ubuntu par exemple sont ici.

Plutôt que de gérer chaque container manuellement, nous allons utiliser un outil très pratique, Docker Compose. Cela permet dans un seul fichier YAML de décrire quelles images télécharger, s’il faut rendre leurs ports accessibles, éventuellement monter un dossier, etc.

Sans détour, voici un setup minimal, à placer dans un fichier docker-compose.yml à la racine de son projet, pour avoir un serveur Apache avec PHP 7.2 accessible sur le port 80, avec les fichiers du répertoire courant, et un serveur MySQL dont les données seront sauvegardées:

En quelques mots, nous indiquons à Docker qu’il faut télécharger les images officielles de PHP/Apache et MySQL, monter dans le répertoire web d’Apache le répertoire courant, et via les variables d’environnement nous configurons la base de donnée et l’utilisateur MySQL.

Il suffira ensuite d’exécuter docker-compose up -d depuis le même répertoire pour construite et démarrer les containers. Ensuite, pour les arrêter, docker-compose down.

Avec Symfony 2, 3 ou 4

Avec Symfony, il y a une petite subtilité supplémentaire: nous avons besoin du mod_rewrite Apache, non activé de base. Nous allons en plus avoir besoin de quelques extensions recommandées (OpCache, INTL…), d’installer Composer et d’autres utilitaires.
Pour cela, nous faisons notre propre Dockerfile, que nous allons baser sur l’image Apache/PHP officielle utilisée précédemment, et sur laquelle nous exécutons nos personnalisations.

Finalement, nous créons un vhost Apache, afin de ne pas devoir rajouter /public ou /web dans l’URL pour accéder au site web.

Le code (les noms de fichiers figurent sous chaque extrait):

Le résultat peut être vérifié en accédant simplement à http://localhost

Docker détecte normalement automatiquement les modifications lorsqu’on re-exécute docker-compose up -d, mais il est également possible de forcer la reconstruction avec docker-compose up -d --build.

Performances sur mac OS

Docker souffre d’un problème particulier sur mac OS: les fichiers montés sont lents, voir très lents. Sur une application avec beaucoup de fichiers inclus comme Symfony, les performances en pâtissent fortement. A l’origine, des limites sur le passage d’un système de fichier à un autre, et leur synchronisation.

Docker a introduit des modes permettant de relâcher les contraintes de consistence sur les fichiers montés: on indique de quel côté le fichier sera modifié en général, et la modification pourra être propagée avec parfois un petit délai (de l’ordre de quelques ms) dans l’autre sens.

Pour une application Symfony, l’astuce est de retirer du système de fichier partagé le cache et les logs (qui ne seront plus visibles depuis notre machine), et activer ce mode sur le répertoire de code.
Cela s’active simplement en modifiant docker-compose.yml:

Conclusion

Docker apporte de gros gains de productivité chaque jour, je l’utilise quotidiennement depuis deux ans. L’outil a évolué, s’est bonifié au fil des versions, je ne peux que le recommander maintenant.
J’espère que cet article vous aura aidé à démarrer avec, et nous verrons prochainement comment utiliser Docker en production 🙂

You may also like

2 comments

emilien 23 avril 2019 at 12 h 30 min

Salut Romaric, j’utilise Docker avec Symfony depuis maintenant plus de 2 ans, et j’ai eu aussi des soucis de lenteur sous OSX. J’ai utilisé une autre méthode que celle que tu décris bien qu’elle n’en est pas très éloignée…
Je te laisse jeter un oeil ici : http://docker-sync.io
Sinon tes articles sont très bien écrit et très enrichissant, merci 🙂

Reply
Romaric 30 avril 2019 at 10 h 21 min

Bonjour Emilien, merci 🙂
C’est en effet une autre méthode, de mémoire tu as (ou a eu?) plusieurs outils similaires dans l’approche, y compris de mettre en place soi-même un petit rsync. Il y a aussi la possibilité d’un montage NFS, je ne sais pas si c’est toujours d’actualité. Pour l’instant je me suis arrêté à l’approche de l’article, je trouve la différence de performance sur un SF 3 ou SF 4 pas assez grande pour justifier la complexité, mais c’est bien d’avoir une ouverture sur d’autres possibilités 😉

Reply

Leave a Comment

*