Nous avons utilisé ChatGPT pour améliorer la grammaire et la syntaxe de la transcription.
Bonjour, bonjour tout le monde ! J'espère que vous avez fait une bonne pause-café. Merci d'avoir assisté à cette conférence. Aujourd'hui, je vais vous parler de Nix et un peu de la maintenance des conteneurs.
Qui suis-je ? Je suis Jérôme Vieilledent, Product Manager chez Platform.sh. Oui, je sais qu'il y a beaucoup d'intervenants de Platform.sh, mais n'hésitez pas à me contacter à tout moment si vous voulez discuter des produits, de Platform.sh, ou simplement bavarder. Je suis ici au stand.
Pour introduire cet exposé, je dois expliquer pourquoi nous sommes arrivés à cette technologie, ce que certains pourraient considérer comme gênant, mais c'est en fait génial. Nous allons parler de Nix et de son rôle dans la gestion des conteneurs à Platform.sh.
Tout d'abord, parlons des conteneurs chez Platform.sh. Nous utilisons des conteneurs, mais pas Docker ; nous utilisons plutôt LXC (conteneurs Linux). Cette décision a été prise pour des raisons historiques. Lorsque Platform.sh a démarré, Docker était à peine expérimental, mais LXC était plus stable et bien connu, à l'instar des jails BSD ou des zones Solaris.
Oui, nous utilisons des conteneurs, mais nous avons également un système d'orchestration industrialisé. Nous n'utilisons pas Kubernetes ; à la place, nous avons un logiciel appelé "Manufacturer", dont j'espère que nous ouvrirons la source un jour. Il orchestre tout sur notre plateforme.
Un autre fait est que nous exploitons une plateforme horizontale en tant que service (PaaS). Notre objectif est d'être une plateforme qui peut héberger n'importe quel type d'application, quel que soit le temps d'exécution. Cet exposé se concentrera principalement sur PHP, mais notre plateforme prend en charge de nombreux autres moteurs d'exécution. La maintenance de ces conteneurs est un défi. Rien que pour PHP, nous avons 11 images différentes, chacune avec des versions différentes de Debian et de leurs dépendances. Il est même possible (bien que non recommandé) d'héberger une application PHP 5.4.
Au total, Platform.sh supporte de nombreux runtimes - 71 images pour les applications, et 95 autres pour les services tels que les bases de données(Redis, Memcached), les moteurs de recherche (Solr, Elasticsearch), et plus encore. Au total, cela représente 166 images à maintenir. Trois personnes assurent la maintenance de toutes ces images à temps plein, et elles sont très compétentes dans ce qu'elles font.
Mais ce n'est pas tout. Vos applications ont besoin de bien plus que de PHP. Par exemple, vous pouvez avoir besoin d'outils comme ImageMagick pour la manipulation d'images ou quelque chose pour convertir des fichiers en PDF. Parlons des paquets supplémentaires dont vous pourriez avoir besoin dans vos conteneurs.
Voici ma liste de souhaits pour Noël : Je veux PHP 8.3, que je lance toujours parce que j'aime être à la pointe de la technologie. Mais j'ai aussi besoin de PHP 7.2 pour un vieux script de construction que j'utilise depuis une décennie. Je veux ImageMagick, mais je veux la version 6, pas la version 7, parce que je suis trop paresseux pour m'occuper des changements. Et j'ai besoin de LibreOffice pour générer des PDF.
Mais il y a un problème. Ces différentes dépendances ne fonctionnent pas toujours bien ensemble. Il en résulte ce que nous appelons "l'enfer des dépendances". Imaginez que vous essayiez de compiler toutes ces différentes versions de PHP et de leurs extensions, ainsi que d'anciennes versions de Python, en une seule fois. Il y a de fortes chances qu'il se casse, ce qui donne lieu à ce que nous appelons un moment XKCD, où vous réalisez que vous êtes en train de construire une énorme chaîne de dépendances juste pour se supporter lui-même.
Alors, quelle est la solution ? Eh bien, il y en a une : elle s'appelle Nix.
Qu'est-ce que Nix, et pourquoi est-ce si génial ? Nix est un gestionnaire de paquets fonctionnel. Qu'est-ce que cela signifie ? Tout d'abord, il est supporté par un langage de programmation fonctionnel. Cela permet de traiter les paquets comme des valeurs, et puisque c'est fonctionnel, toutes les fonctions utilisées pour générer des paquets (que nous appelons "dérivations" dans Nix) ne peuvent pas avoir d'effets secondaires. Tout est construit de manière totalement isolée.
Comment y parvenir ? Tout d'abord, il n'est pas possible d'avoir des dépendances non déclarées. Si vous avez déjà utilisé des fichiers .deb ou .rpm, vous avez peut-être rencontré ce problème lorsque les dépendances ne sont pas correctement déclarées. Cela peut également se produire avec des gestionnaires de paquets comme Homebrew. Mais dans Nix, il est impossible de construire quelque chose sans le déclarer explicitement.
Ce qui est bien avec Nix, c'est que vous pouvez enfin dire "ça marche sur ma machine" et le penser. Si cela fonctionne sur votre machine, cela fonctionnera également sur une autre machine. C'est un gage de cohérence entre les différents environnements.
Un autre aspect clé est que tous les paquets sont construits en isolation totale. Comment ? Nix utilise ce que l'on appelle le magasin Nix, généralement situé dans /nix/store. Tous les paquets y sont stockés, et chaque paquet est associé à un hachage qui l'identifie de manière unique, ainsi que ses dépendances. Ce hachage est basé sur une somme de contrôle SHA-256, et il capture le paquet et toutes ses dépendances, garantissant ainsi l'isolation.
Cette approche permet également la coexistence de plusieurs versions d'un même paquet. Vous pourriez avoir PHP 5.4 fonctionnant à côté de PHP 8.3 sans conflit. C'est incroyablement difficile à réaliser avec les gestionnaires de paquets traditionnels.
Nix s'appuie sur un langage fonctionnel, mais il n'est pas nécessaire d'en savoir beaucoup pour l'utiliser. Cependant, plus vous creuserez dans Nix, plus vous rencontrerez des "expressions Nix", qui sont des fichiers écrits dans ce langage fonctionnel. Il s'agit d'un langage simple, un peu similaire à JSON mais plus puissant. Ces expressions Nix sont évaluées pour créer des dérivations. Chaque fois que vous créez un paquet Nix, l'expression Nix que vous avez écrite (en spécifiant vos paquets et tous les crochets shell dont vous avez besoin) devient une nouvelle dérivation dans le magasin Nix.
Nix est également soutenu par Nixpkgs, le plus grand dépôt de paquets au monde, avec plus de 80 000 paquets. Il s'agit essentiellement d'un énorme dépôt GitHub que Nix interroge chaque fois que vous souhaitez installer quelque chose. Par défaut, tout est construit à partir de la base (compilé), mais il y a aussi un cache de binaires préconstruits pour la plupart des plateformes, de sorte que vous n'aurez pas toujours besoin de compiler les choses vous-même.
Pour vous donner un exemple, voici une vieille image montrant Subversion et ses dépendances. À gauche, vous voyez comment c'est censé fonctionner. Vous voulez le paquet "hello", qui dépend de libc (parce que tout dépend de libc), et il y a une autre dépendance pour une version spécifique de libgmp. Le problème est que si vous dépendez de la libc de votre système d'exploitation, vous pouvez rencontrer des problèmes lorsque vous essayez de compiler quelque chose qui attend une version différente.
Ce type de conflit de dépendance se produit souvent, en particulier avec des paquets comme Subversion, qui peut avoir besoin d'une version spécifique d'OpenSSL ou de Berkeley DB. Mais avec Nix, tout est isolé et versionné, ce qui permet d'éviter complètement ce type de conflit. Chaque paquetage a son propre environnement isolé, et grâce au système de hachage, Nix peut gérer plusieurs versions d'un même paquetage sans effort.
Très bien, essayons maintenant quelque chose de pratique, une petite démo. Je veux toujours mon PHP 8.3 parce qu'il est génial, et je veux mon extension "eerie". J'en ai choisi une appelée SOAP - plus personne n'utilise SOAP, n'est-ce pas ? Sauf sous la douche, bien sûr. Mais c'est un bon exemple.
Comme je travaille sur un Mac, je veux toujours Python 2.7 (même s'il est dépassé). Alerte au spoiler : si vous essayez de l'installer avec Nix, il vous avertira que ce n'est pas sûr, et vous devrez passer outre. J'ai donc ajouté une variable d'environnement spécifique pour cela. Je veux aussi ImageMagick, mais j'ai décidé d'abandonner LibreOffice pour cette démo parce qu'il prend trop de temps à construire.
Essayons-le. Pour cela, je vais utiliser nix-shell. Nix-shell est une commande utilisée pour créer un environnement temporaire dans votre terminal avec les paquets que vous voulez. Je vais le mettre en mode verbeux pour que vous puissiez voir ce qui se passe. J'ai tout pré-téléchargé pour que nous n'ayons pas à attendre 10 minutes pour l'installation.
J'ai dit que je voulais PHP 8.3. J'ai donc besoin du paquet PHP 8.3 et de l'extension SOAP. Je veux aussi Composer parce que je vais en avoir besoin, et j'ajouterai Python 2.7 et ImageMagick 6.
Ce que Nix fait ici est d'évaluer toutes les expressions Nix pour chaque dépendance des quelques paquets que j'installe. Comme vous pouvez le voir, il y a beaucoup de dépendances. C'est ce qui se passe dans les coulisses de votre système d'exploitation lorsque vous essayez de construire quelque chose.
Vérifions ce que j'ai sur mon système actuellement sans Nix. J'ai installé PHP 8.2, mais je n'ai que Python 3, et aucune commande python n'est disponible. Je n'ai pas non plus ImageMagick, dont nous aurons besoin plus tard.
Maintenant, après avoir utilisé Nix, j'ai PHP 8.3, ImageMagick 6.7 (qui a pris beaucoup de temps à compiler), et Python 2. J'ai également installé l'extension SOAP, ce qui nous permet de prendre une "douche" métaphorique.
C'est essentiellement ce que fait Nix : il met en place un environnement de travail avec tous les paquets dont vous avez besoin. Mais il peut être fastidieux de spécifier manuellement chaque paquetage pour chaque session de l'interpréteur de commandes. C'est parfait pour tester un nouveau logiciel, mais vous voudrez l'automatiser à un moment ou à un autre. Il y a plusieurs façons de le faire, mais l'une des plus simples est de créer un script qui charge tout pour vous.
J'ai créé un script shell Nix très simple qui déclare toutes mes entrées et dépendances. Il inclut même un hook shell qui imprime "Hello Symfony" lorsqu'il est exécuté. Maintenant, au lieu de taper toutes les options manuellement, je peux juste lancer nix-shell, et tout est mis en place pour moi automatiquement.
C'était la partie fantaisiste de la démo. Nous pourrions l'essayer avec LibreOffice, mais nous n'avons pas le temps aujourd'hui. Tout cela signifie qu'avec Nix, pour nos propres systèmes, nous pouvons réduire le nombre d'images que nous devons maintenir de 166 à une seule image composable. C'est une grande victoire pour nous.
Bien sûr, nous pourrions encore maintenir quelques images différentes pour des services spécifiques, mais le fait est que Nix nous permet de tout gérer avec une seule image qui peut être personnalisée pour divers besoins. Et si vous utilisez Docker, vous pouvez même utiliser Nix pour générer de véritables images Docker, construites à partir de vos paquets plutôt que de commencer par une image Docker et d'ajouter des choses plus tard. Il existe également une image Nix pour Docker lui-même, ce qui facilite grandement l'ajout de paquets et d'outils à votre pile.
Ce n'est pas seulement utile pour nous dans la maintenance de notre infrastructure avec tous ces conteneurs, mais c'est aussi utile pour tous ceux qui rencontrent l'enfer des dépendances. Je suis sûr que vous avez tous connu ce problème où vous essayez de compiler quelque chose, mais cela nécessite une version de bibliothèque spécifique, qui dépend d'une autre version de bibliothèque, et ainsi de suite, jusqu'à ce que vous abandonniez finalement. C'est pour cela que Docker a été inventé, n'est-ce pas ? Pour gérer l'enfer des dépendances. Mais cela peut toujours arriver, même dans Docker.
Voilà, c'est à peu près tout. Nous avons vu comment Nix peut simplifier la gestion des dépendances et la maintenance des conteneurs. J'ai terminé un peu tôt, donc je serais heureux de répondre à vos questions.
Nous avons un peu de temps pour les questions. Oh, nous avons le cube pour faire circuler le micro.
Question : Quelle image de base utilisez-vous pour votre projet ? Quelle image de base utilisez-vous pour vos conteneurs LXC ? Y a-t-il une image de base spécifique ?
Réponse : Excellente question ! Nous utilisons Debian comme image de base. Nous utilisons LXC et l'image de base est pratiquement une Debian brute, elle est donc construite à partir de zéro.
Question : Vous avez mentionné que vous pouvez créer une configuration Nix à partir d'une machine. Cela signifie-t-il qu'elle fixera indéfiniment les versions de tous les paquets que vous avez installés sur cette machine ?
Réponse : Oui, c'est exactement cela : Oui, c'est exactement cela, jusqu'à ce que vous décidiez de faire une mise à jour. Nix vous permet de gérer vos paquets d'une manière qui assure la cohérence. Et cela m'amène à une chose que je n'ai pas mentionnée plus tôt : Nix peut également être utilisé comme un système d'exploitation complet. Vous pouvez l'utiliser pour gérer tous vos paquets et les mettre à jour quand vous le souhaitez.
Votre question porte sur l'épinglage de version. Si vous spécifiez PHP 8.3, par exemple, il continuera à utiliser PHP 8.3 jusqu'à la fin de son cycle de vie. À ce moment-là, vous devrez passer à PHP 8.4 ou à la version suivante, quelle qu'elle soit. Il en va de même pour d'autres paquets. Par exemple, LibreOffice a deux canaux : le canal frais (avec les dernières fonctionnalités) et le canal stable. Vous pouvez choisir le canal que vous souhaitez suivre.
Et même si vous suivez le canal principal des paquets Nix, vous pouvez toujours épingler une version spécifique du paquet. Pour cela, il suffit de référencer le commit dans Nixpkgs qui correspond à la version souhaitée, et le tour est joué. Le paquetage ne sera pas mis à jour à moins que vous ne changiez manuellement la version épinglée.
Question : Comment partagez-vous vos configurations entre développeurs ? Comment partagez-vous vos configurations entre développeurs ? Est-ce que vous livrez un fichier Nix avec tout ce qui est inclus, ou est-ce que vous construisez quelque chose et le partagez ensuite en tant que paquetage ?
Réponse : La façon la plus simple est d'écrire une expression Nix, comme je l'ai fait dans la démo. Mais au lieu de le faire uniquement pour nix-shell
, vous devriez créer un fichier plus complet, probablement appelé default.nix
. Ce fichier définirait l'ensemble de votre pile. Ensuite, n'importe quel membre de votre équipe peut simplement lancer nix-build
ou n'importe quelle commande que vous avez mise en place, et tout sera construit en fonction de ce fichier default.nix
.
Vous pouvez même faciliter les choses en créant un Makefile qui exécute la commande Nix. De cette façon, n'importe qui peut simplement taper make up
ou quelque chose de similaire, et ils auront la même pile que vous. C'est très simple à partager entre équipes.
Question : Existe-t-il un processus de compatibilité avec les images ou les fichiers Docker ?
Réponse : Pas directement, pour autant que je sache. Mais Nix a des outils qui peuvent vous aider à générer des images Docker, de sorte que toutes les couches de l'image seront construites pour vous par Nix. C'est une façon de procéder. Donc, bien qu'il n'y ait pas de conversion directe des fichiers Docker, vous pouvez toujours utiliser Nix pour construire des images Docker.
Question : Comment déployer Nix ? Existe-t-il une plateforme en tant que service pour Nix ?
Réponse : Pour Platform.sh, nous sommes sur le point de lancer Nix en tant que fonctionnalité expérimentale. Dans quelques semaines, vous pourrez définir votre pile dans votre fichier YAML en utilisant Nix. Au lieu de spécifier toutes vos dépendances manuellement, vous direz simplement "Je veux PHP 8.3 et ces autres paquets", et cela utilisera automatiquement l'image Nix.
Nous y travaillons encore, mais à l'avenir, vous pourrez même écrire des expressions Nix personnalisées directement dans votre fichier YAML. Et oui, il y a aussi la possibilité d'utiliser Docker avec Nix. C'est encore en cours d'évolution, mais Nix arrivera très bientôt dans Platform.sh.
La question est la suivante : Si je veux utiliser Nix dans mes environnements de développement et de production, quelle est la meilleure façon de le déployer maintenant ? Dois-je simplement pousser mon fichier default.nix,
ou existe-t-il une autre approche ?
Réponse : Pour le moment, Nix n'est pas entièrement supporté pour les déploiements en production. Cependant, je serais ravi d'en discuter plus avant avec vous car nous sommes très intéressés par la possibilité d'effectuer des déploiements basés sur Nix en production. Nous aimerions qu'il soit possible d'évaluer les expressions Nix pour vos conteneurs au moment de la construction.
Question : Comment fonctionne Nix sous le capot ? Utilise-t-il une sorte de magie de préchargement ou des binaires statiques pour les dépendances ?
Réponse : Bonne question ! Nix utilise le cache de cache.nixos.org. Il s'agit d'une énorme plateforme qui préconstruit tous les paquets et dépendances courants. Si le paquet dont vous avez besoin n'est pas disponible dans le cache, il le compilera pour vous. Et si vous voulez plus de contrôle, vous pouvez toujours mettre en place votre propre cache. Cela vous permet de préconstruire toutes vos dépendances et de faire en sorte que votre infrastructure locale les récupère avant le cache de NixOS.
Jérôme : Très bien, merci pour toutes ces excellentes questions. C'est tout pour aujourd'hui. Merci encore pour votre participation et n'oubliez pas, si vous voulez plonger plus profondément dans Nix, venez me trouver moi ou les autres membres de l'équipe Platform.sh ici. Et n'oubliez pas que le responsable de la pile PHP pour Nix est également dans la salle - il se cache, mais il est là, et il a de belles histoires à partager !
Merci, et j'espère que vous apprécierez le reste de l'événement !