{"id":32526,"date":"2019-10-31T21:47:32","date_gmt":"2019-10-31T18:47:32","guid":{"rendered":"https:\/\/prohoster.info\/blog\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci\/"},"modified":"2019-10-31T21:47:32","modified_gmt":"2019-10-31T18:47:32","slug":"protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci","status":"publish","type":"post","link":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci","title":{"rendered":"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><strong>Je vous invite \u00e0 prendre connaissance de la transcription de la pr\u00e9sentation d'Alexander Sigachev d'Inventos \u00ab Le processus de d\u00e9veloppement et de test avec Docker + Gitlab CI \u00bb<\/strong><\/p>\n<p><\/p>\n<p>Ceux qui commencent \u00e0 mettre en \u0153uvre le processus de d\u00e9veloppement et de test bas\u00e9 sur Docker + Gitlab CI posent souvent des questions basiques. Par o\u00f9 commencer ? Comment s'organiser ? Comment tester ?<\/p>\n<p><\/p>\n<p>Cette pr\u00e9sentation est bonne car elle d\u00e9crit de mani\u00e8re structur\u00e9e le processus de d\u00e9veloppement et de test utilisant Docker et Gitlab CI. La pr\u00e9sentation date de 2017. Je pense que l'on peut tirer des bases, de la m\u00e9thodologie, de l'id\u00e9e et des exp\u00e9riences d'utilisation de cette pr\u00e9sentation. <\/p>\n<p>\n<center><div class=\"youtube-placeholder\" data-id=\"lJsqRwULRVA\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/lJsqRwULRVA\/hqdefault.jpg\" alt=\"Lire la vid\u00e9o\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><\/p>\n<p>Pour ceux que cela int\u00e9resse, je vous invite \u00e0 lire la suite. <noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><\/p>\n<p>Je m'appelle Alexandre Sigatchev. Je travaille chez Inventos. Je vais parler de mon exp\u00e9rience d'utilisation de Docker et de la mani\u00e8re dont nous l'int\u00e9grons progressivement dans nos projets.<\/p>\n<p><\/p>\n<p>Th\u00e8me de la pr\u00e9sentation : Processus de d\u00e9veloppement avec Docker et Gitlab CI. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/e30c4757e4bda1bcc3e20b16e8e2709e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>C'est ma deuxi\u00e8me pr\u00e9sentation sur Docker. Au moment de la premi\u00e8re pr\u00e9sentation, nous utilisions Docker uniquement dans le d\u00e9veloppement sur les machines des d\u00e9veloppeurs. Le nombre d'employ\u00e9s utilisant Docker \u00e9tait d'environ 2-3 personnes. Petit \u00e0 petit, nous avons accumul\u00e9 de l'exp\u00e9rience et progress\u00e9 un peu plus loin. Lien vers notre <noindex><a rel=\"nofollow\" href=\"https:\/\/www.slideshare.net\/gled\/docker-development-70411088\">premi\u00e8re pr\u00e9sentation<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Que contiendra cette pr\u00e9sentation ? Nous partagerons notre exp\u00e9rience sur les obstacles rencontr\u00e9s et comment nous avons r\u00e9solu certains probl\u00e8mes. Ce n'\u00e9tait pas toujours id\u00e9al, mais cela nous a permis d'avancer.<\/p>\n<p><\/p>\n<p>Notre devise : dockeriser tout ce qui nous passe par les mains.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/25ae4f97f1c502384abfe697bac502b1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Quels probl\u00e8mes r\u00e9solvons-nous ?<\/p>\n<p><\/p>\n<p>Lorsque plusieurs \u00e9quipes sont pr\u00e9sentes dans l'entreprise, le programmeur est une ressource partag\u00e9e. Il arrive qu'un programmeur soit extrait d'un projet et affect\u00e9 temporairement \u00e0 un autre projet.<\/p>\n<p><\/p>\n<p>Pour qu'un programmeur puisse s'int\u00e9grer rapidement, il doit t\u00e9l\u00e9charger le code source du projet et mettre en place un environnement le plus rapidement possible afin de r\u00e9soudre les probl\u00e8mes du projet.<\/p>\n<p><\/p>\n<p>En g\u00e9n\u00e9ral, si l'on commence de z\u00e9ro, la documentation dans le projet est rare. Les informations sur la configuration ne sont disponibles que pour les v\u00e9t\u00e9rans. Les employ\u00e9s configurent leur poste de travail en un ou deux jours. Pour acc\u00e9l\u00e9rer ce processus, nous avons utilis\u00e9 Docker.<\/p>\n<p><\/p>\n<p>La raison suivante concerne la normalisation des param\u00e8tres en d\u00e9veloppement. D'apr\u00e8s mon exp\u00e9rience, les d\u00e9veloppeurs prennent souvent des initiatives. Dans un cas sur cinq, un domaine personnalis\u00e9 est introduit, par exemple vasya.dev. \u00c0 c\u00f4t\u00e9, se trouve le voisin Petya, qui a le domaine petya.dev. Ils d\u00e9veloppent un site ou un composant du syst\u00e8me en utilisant ce nom de domaine.<\/p>\n<p><\/p>\n<p>Lorsque le syst\u00e8me se d\u00e9veloppe et que ces noms de domaine commencent \u00e0 figurer dans les configurations, un conflit d'environnements de d\u00e9veloppement se produit et le chemin du site est r\u00e9\u00e9crit.<\/p>\n<p><\/p>\n<p>Il en va de m\u00eame pour les param\u00e8tres de la base de donn\u00e9es. Certaines personnes ne pensent pas \u00e0 la s\u00e9curit\u00e9 et travaillent avec un mot de passe root vide. D'autres, lors de l'installation, la configuration MySQL a exig\u00e9 un mot de passe, qui s'est r\u00e9v\u00e9l\u00e9 \u00eatre 123. Il arrive souvent que la configuration de la base de donn\u00e9es change constamment en fonction des commits du d\u00e9veloppeur. Quelqu'un a corrig\u00e9, quelqu'un ne l'a pas fait. Il y avait des astuces o\u00f9 nous avons sorti une configuration de test dans <code>.gitignore<\/code> et chaque d\u00e9veloppeur devait installer la base de donn\u00e9es. Cela compliquait le processus de d\u00e9marrage. Il faut, entre autres, se rappeler de la base de donn\u00e9es. La base de donn\u00e9es doit \u00eatre initialis\u00e9e, il faut indiquer un mot de passe, un utilisateur \u00e0 cr\u00e9er, une table, etc.<\/p>\n<p><\/p>\n<p>Un autre probl\u00e8me est la diversit\u00e9 des versions des biblioth\u00e8ques. Il arrive souvent qu'un d\u00e9veloppeur travaille sur diff\u00e9rents projets. Il y a un projet Legacy, qui a commenc\u00e9 il y a cinq ans (de 2017 \u2014 note de la r\u00e9daction). Lors du d\u00e9marrage, nous avons commenc\u00e9 avec MySQL 5.5. Il y a aussi des projets modernes, o\u00f9 nous essayons d'int\u00e9grer des versions de MySQL plus r\u00e9centes, comme 5.7 ou plus (en 2017 \u2014 note de la r\u00e9daction).<\/p>\n<p><\/p>\n<p>Celui qui travaille avec MySQL sait que ces biblioth\u00e8ques entra\u00eenent des d\u00e9pendances. Il est assez probl\u00e9matique de lancer deux bases en m\u00eame temps. Du moins, il est probl\u00e9matique de connecter de vieux clients \u00e0 une nouvelle base de donn\u00e9es. Cela engendre \u00e0 son tour plusieurs probl\u00e8mes.<\/p>\n<p><\/p>\n<p>Le prochain probl\u00e8me survient lorsque le d\u00e9veloppeur travaille sur sa machine locale, utilisant des ressources locales, des fichiers locaux et de la RAM locale. Toute interaction pendant le d\u00e9veloppement des solutions se d\u00e9roule dans le cadre de ce qui fonctionne sur une seule machine. Par exemple, nous pouvons avoir 3 serveurs backend en production, mais le d\u00e9veloppeur enregistre des fichiers dans le r\u00e9pertoire racine, et c'est de l\u00e0 qu'Nginx prend les fichiers pour r\u00e9pondre aux demandes. Lorsque ce code atteint la production, il s'av\u00e8re que le fichier est pr\u00e9sent sur l'un des 3 serveurs.<\/p>\n<p><\/p>\n<p>Actuellement, le d\u00e9veloppement des microservices est en plein essor. Lorsque nous divisons nos grandes applications en petits composants interagissant entre eux. Cela permet de s\u00e9lectionner des technologies sp\u00e9cifiques pour chaque ensemble de t\u00e2ches. Cela permet \u00e9galement de r\u00e9partir le travail et les zones de responsabilit\u00e9 entre les d\u00e9veloppeurs.<\/p>\n<p><\/p>\n<p>Un d\u00e9veloppeur frontend travaillant en JS n'influence pratiquement pas le backend. Le d\u00e9veloppeur backend, quant \u00e0 lui, d\u00e9veloppe, dans notre cas, avec Ruby on Rails et ne g\u00eane pas le frontend. L'interaction s'effectue via l'API.<\/p>\n<p><\/p>\n<p>Comme bonus, gr\u00e2ce \u00e0 Docker, nous avons pu optimiser les ressources sur Staging. Chaque projet, en raison de sa sp\u00e9cificit\u00e9, n\u00e9cessitait des configurations particuli\u00e8res. Il fallait physiquement allouer soit un serveur virtuel et les configurer s\u00e9par\u00e9ment, soit partager un environnement variable, ce qui pouvait influencer les projets les uns sur les autres selon les versions des biblioth\u00e8ques.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/fa5c99f90faef84a356d4791fd915830.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Outils. Que utilisons-nous ? <\/p>\n<p><\/p>\n<ul>\n<li>Docker lui-m\u00eame. Les d\u00e9pendances d'une application sont d\u00e9crites dans le Dockerfile. <\/li>\n<li>Docker-compose est le lien qui regroupe plusieurs de nos applications Docker.<\/li>\n<li>Nous utilisons GitLab pour stocker le code source.<\/li>\n<li>Nous utilisons GitLab-CI pour l'int\u00e9gration continue.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/b6041827a6ba928e0d33add6b79c581c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>La pr\u00e9sentation se compose de deux parties.<\/p>\n<p><\/p>\n<p>La premi\u00e8re partie expliquera comment nous avons lanc\u00e9 Docker sur les machines des d\u00e9veloppeurs.<\/p>\n<p><\/p>\n<p>La deuxi\u00e8me partie expliquera comment interagir avec GitLab, comment nous lan\u00e7ons les tests et comment nous d\u00e9ployons en Staging.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/45746d3323d35e0d18f066c8bfcb2214.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Docker est une technologie qui permet de d\u00e9crire (en utilisant une approche d\u00e9clarative) les composants n\u00e9cessaires. Voici un exemple de Dockerfile. Ici, nous d\u00e9clarons que nous h\u00e9ritons de l'image Docker officielle Ruby:2.3.0. Elle contient Ruby version 2.3 pr\u00e9install\u00e9. Nous installons les biblioth\u00e8ques n\u00e9cessaires ainsi que NodeJS. Nous d\u00e9crivons que nous cr\u00e9ons un r\u00e9pertoire. <code>\/app<\/code>Nous d\u00e9finissons le r\u00e9pertoire app comme le r\u00e9pertoire de travail. Dans ce r\u00e9pertoire, nous pla\u00e7ons le Gemfile et le Gemfile.lock minimaux n\u00e9cessaires. Ensuite, nous ex\u00e9cutons la construction des projets qui installent cette image de d\u00e9pendances. Nous indiquons que le conteneur sera pr\u00eat \u00e0 \u00e9couter sur le port externe 3000. La derni\u00e8re commande est celle qui lance directement notre application. Si nous ex\u00e9cutons la commande de lancement du projet, l'application tentera de s'ex\u00e9cuter et lancera la commande sp\u00e9cifi\u00e9e.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/ba503c305ae90f49b39f4ae2cbda1668.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>C'est un exemple minimal d'un fichier docker-compose. Dans ce cas, nous montrons comment se fait la liaison de deux conteneurs. Il s'agit directement du service de base de donn\u00e9es et du service web. Nos applications web n\u00e9cessitent dans la plupart des cas une base de donn\u00e9es pour stocker des donn\u00e9es en tant que backend. Comme nous utilisons MySQL, nous avons un exemple avec MySQL \u2014 mais rien ne nous emp\u00eache d'utiliser une autre base de donn\u00e9es (PostgreSQL, Redis).<\/p>\n<p><\/p>\n<p>Nous prenons de la source officielle sur Docker Hub l'image MySQL 5.7.14 sans modifications. L'image responsable de notre application web est construite \u00e0 partir du r\u00e9pertoire actuel. Elle construit notre image lors du premier d\u00e9marrage. Ensuite, elle ex\u00e9cute la commande que nous effectuons ici. Si nous revenons en arri\u00e8re, nous verrons que la commande de d\u00e9marrage a \u00e9t\u00e9 d\u00e9finie via Puma. Puma est un service \u00e9crit en Ruby. Dans le deuxi\u00e8me cas, nous red\u00e9finissons. Cette commande peut \u00eatre arbitraire selon nos besoins ou nos t\u00e2ches.<\/p>\n<p><\/p>\n<p>Nous d\u00e9crivons \u00e9galement qu'il est n\u00e9cessaire de transf\u00e9rer le port de notre machine h\u00f4te de d\u00e9veloppeur de 3000 au port 3000 du conteneur. Cela est r\u00e9alis\u00e9 automatiquement \u00e0 l'aide d'iptables et de son propre m\u00e9canisme qui est int\u00e9gr\u00e9 directement dans Docker. <\/p>\n<p><\/p>\n<p>Le d\u00e9veloppeur peut \u00e9galement, comme auparavant, se connecter \u00e0 n'importe quelle adresse IP disponible, par exemple, l'adresse locale 127.0.0.1 ou l'adresse IP externe de la machine.<\/p>\n<p><\/p>\n<p>La derni\u00e8re ligne indique que le conteneur web d\u00e9pend du conteneur db. Lorsque nous lan\u00e7ons le conteneur web, docker-compose lancera d'abord notre base de donn\u00e9es. Une fois que la base de donn\u00e9es a d\u00e9marr\u00e9 (en r\u00e9alit\u00e9 \u2014 apr\u00e8s le d\u00e9marrage du conteneur ! Ceci ne garantit pas que la BDD est pr\u00eate), notre application, notre backend sera lanc\u00e9.<\/p>\n<p><\/p>\n<p>Cela permet d'\u00e9viter les erreurs lorsque la base de donn\u00e9es n'est pas d\u00e9marr\u00e9e et permet d'\u00e9conomiser des ressources lorsque nous arr\u00eatons le conteneur de bases de donn\u00e9es, lib\u00e9rant ainsi des ressources pour d'autres projets. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/4acbcf5de89b98db055e8abc419202de.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Quels sont les avantages de l'utilisation de la conteneurisation des bases de donn\u00e9es dans le projet ? Nous fixons la version de MySQL pour tous les d\u00e9veloppeurs. Cela permet d'\u00e9viter certaines erreurs qui peuvent survenir en cas de divergence des versions, lorsque la syntaxe, la configuration et les param\u00e8tres par d\u00e9faut changent. Cela permet de sp\u00e9cifier des noms d'h\u00f4te communs pour la base de donn\u00e9es, le login et le mot de passe. Nous nous \u00e9loignons du d\u00e9sordre des noms et des conflits dans les fichiers de configuration qui existaient auparavant. <\/p>\n<p><\/p>\n<p>Nous avons la possibilit\u00e9 d'utiliser une configuration plus optimale pour l'environnement de d\u00e9veloppement, qui diff\u00e8re de la configuration par d\u00e9faut. MySQL est par d\u00e9faut configur\u00e9 pour de faibles machines, et ses performances sont tr\u00e8s basses \u00e0 la sortie de la bo\u00eete.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/417d77a06b18e2df9b71440c0f2a1653.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Docker permet d'utiliser l'interpr\u00e9teur Python, Ruby, NodeJS, PHP dans la version requise. Nous nous d\u00e9barrassons de la n\u00e9cessit\u00e9 d'utiliser un gestionnaire de versions. Auparavant, pour Ruby, nous utilisions un package rpm qui permettait de changer de version selon le projet. Cela permet \u00e9galement de migrer le code et de le versionner avec ses d\u00e9pendances gr\u00e2ce \u00e0 un conteneur Docker. Nous n'avons pas de probl\u00e8me pour comprendre la version tant de l'interpr\u00e9teur que du code. Pour mettre \u00e0 jour la version, il faut supprimer l'ancien conteneur et lever un nouveau conteneur. Si quelque chose se passe mal, nous pouvons retirer le nouveau conteneur et remettre l'ancien.<\/p>\n<p><\/p>\n<p>Apr\u00e8s la construction de l'image, les conteneurs, tant en d\u00e9veloppement qu'en production, seront identiques. Cela est particuli\u00e8rement pertinent pour les grandes installations.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/185a1bfe257f7e3e0eecdc6e0e0d330f.jpg\" style=\"display:block;margin: 0 auto;\" \/> Nous utilisons JavaScript et NodeJS dans le frontend.<\/p>\n<p><\/p>\n<p>Actuellement, notre dernier projet est sur ReactJS. Le d\u00e9veloppeur a lanc\u00e9 tous les conteneurs et a d\u00e9velopp\u00e9 en utilisant le rechargement \u00e0 chaud.<\/p>\n<p><\/p>\n<p>Ensuite, une t\u00e2che est lanc\u00e9e pour compiler le JavaScript, et le code compil\u00e9 en statique est fourni via nginx pour \u00e9conomiser des ressources.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/4c2e28319d56d7fc81845b4133a1bfe6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Voici un sch\u00e9ma de notre dernier projet.<\/p>\n<p><\/p>\n<p>Quelles sont les t\u00e2ches que nous avons r\u00e9solues ? Nous avons eu besoin de construire un syst\u00e8me qui interagit avec des appareils mobiles. Ils re\u00e7oivent des donn\u00e9es. L'une des possibilit\u00e9s est d'envoyer des notifications push \u00e0 cet appareil. <\/p>\n<p><\/p>\n<p>Que avons-nous fait \u00e0 cet \u00e9gard ?<\/p>\n<p><\/p>\n<p>Nous avons divis\u00e9 l'application en plusieurs composants : une partie administrative en JS, un backend qui fonctionne via une interface REST sous Ruby on Rails. Le backend interagit avec la base de donn\u00e9es. Le r\u00e9sultat g\u00e9n\u00e9r\u00e9 est renvoy\u00e9 au client. L'interface d'administration, le backend et la base de donn\u00e9es interagissent par l'interface REST.<\/p>\n<p><\/p>\n<p>Nous avons \u00e9galement eu besoin d'envoyer des notifications Push. Auparavant, nous avions un projet qui mettait en \u0153uvre un m\u00e9canisme responsable de la livraison des notifications sur les plateformes mobiles. <\/p>\n<p><\/p>\n<p>Nous avons d\u00e9velopp\u00e9 ce sch\u00e9ma : l'op\u00e9rateur interagit avec l'interface admin via le navigateur, l'interface admin interagit avec le backend, une t\u00e2che est d\u00e9finie pour envoyer des notifications Push.<\/p>\n<p><\/p>\n<p>Les notifications Push interagissent avec un autre composant, qui est d\u00e9velopp\u00e9 en NodeJS.<\/p>\n<p><\/p>\n<p>Des files d'attente sont mises en place et ensuite le m\u00e9canisme d'envoi des notifications se poursuit.<\/p>\n<p><\/p>\n<p>Deux bases de donn\u00e9es sont repr\u00e9sent\u00e9es ici. Actuellement, nous utilisons 2 bases de donn\u00e9es ind\u00e9pendantes avec Docker, qui ne sont pas li\u00e9es entre elles, sauf par leur r\u00e9seau virtuel commun, tandis que les donn\u00e9es physiques sont stock\u00e9es dans diff\u00e9rents r\u00e9pertoires sur la machine du d\u00e9veloppeur.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/dfde59db7e6886d2d851dcf884049318.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>C'est la m\u00eame chose en chiffres. Ici, la r\u00e9utilisation du code est importante.<\/p>\n<p><\/p>\n<p>Si auparavant nous parlions de r\u00e9utilisation du code sous forme de biblioth\u00e8ques, dans cet exemple, notre service responsable des notifications Push est r\u00e9utilis\u00e9 comme un serveur complet. Il fournit une API. Et notre nouveau d\u00e9veloppement interagit avec lui.<\/p>\n<p><\/p>\n<p>\u00c0 l'\u00e9poque, nous utilisions la version 4 de NodeJS. Maintenant (en 2017 \u2014 note de l'\u00e9diteur), dans les nouveaux d\u00e9veloppements, nous utilisons la version 7 de NodeJS. Il n'y a pas de probl\u00e8me \u00e0 utiliser les nouvelles versions des biblioth\u00e8ques dans les nouveaux composants. <\/p>\n<p><\/p>\n<p>Si n\u00e9cessaire, nous pouvons proc\u00e9der \u00e0 un refactoring et mettre \u00e0 jour la version de NodeJS pour le service des notifications Push. <\/p>\n<p><\/p>\n<p>Et si nous pouvons maintenir la compatibilit\u00e9 au niveau de l'API, nous pourrions le remplacer dans d'autres projets qui ont \u00e9t\u00e9 utilis\u00e9s auparavant.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/5c58c65be078a5a1b9fc17ee2e7b4ad4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Que faut-il pour ajouter Docker ? Nous ajoutons \u00e0 notre r\u00e9f\u00e9rentiel un Dockerfile qui d\u00e9crit les d\u00e9pendances n\u00e9cessaires. Dans cet exemple, les composants sont r\u00e9partis logiquement. C'est le minimum requis pour un d\u00e9veloppeur backend.<\/p>\n<p><\/p>\n<p>Lors de la cr\u00e9ation d'un nouveau projet, nous cr\u00e9ons un Dockerfile, d\u00e9crivons l'\u00e9cosyst\u00e8me n\u00e9cessaire (Python, Ruby, NodeJS). Dans docker-compose, nous d\u00e9crivons la d\u00e9pendance requise \u2014 la base de donn\u00e9es. Nous pr\u00e9cisons qu'il faut une base de telle version, avec les donn\u00e9es stock\u00e9es \u00e0 tel endroit.<\/p>\n<p><\/p>\n<p>Nous utilisons un troisi\u00e8me conteneur s\u00e9par\u00e9 avec nginx pour servir les fichiers statiques. La possibilit\u00e9 de t\u00e9l\u00e9charger des images est pr\u00e9vue. Le backend les place dans un volume pr\u00e9alablement pr\u00e9par\u00e9, qui est \u00e9galement mont\u00e9 dans le conteneur avec nginx, qui sert les fichiers statiques.<\/p>\n<p><\/p>\n<p>Pour stocker la configuration de nginx et mysql, nous avons ajout\u00e9 un dossier Docker dans lequel nous conservons les configurations n\u00e9cessaires. Lorsque le d\u00e9veloppeur fait un git clone du d\u00e9p\u00f4t sur sa machine, il obtient d\u00e9j\u00e0 un projet pr\u00eat pour le d\u00e9veloppement local. Il n'y a pas de question concernant le port \u00e0 utiliser ou les param\u00e8tres \u00e0 appliquer.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/e7a6b308a75cacf8ce60687a9e6081dd.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ensuite, nous avons plusieurs composants : admin, inform-API, notifications push.<\/p>\n<p><\/p>\n<p>Pour lancer tout cela, nous avons cr\u00e9\u00e9 un autre d\u00e9p\u00f4t que nous avons nomm\u00e9 dockerized-app. Actuellement, nous utilisons plusieurs d\u00e9p\u00f4ts pour chaque composant. Ils se distinguent simplement par leur logique \u2014 dans GitLab, cela appara\u00eet comme un dossier, et sur la machine du d\u00e9veloppeur comme un dossier pour un projet sp\u00e9cifique. \u00c0 un niveau inf\u00e9rieur se trouvent les composants qui seront regroup\u00e9s.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/f4e2c45c8ec20fca0bac74b3a3892543.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Voici un exemple du contenu de dockerized-app. Nous y pla\u00e7ons \u00e9galement le r\u00e9pertoire Docker, o\u00f9 nous stockons les configurations n\u00e9cessaires pour l'interaction de tous les composants. Il y a un README.md qui d\u00e9crit bri\u00e8vement comment d\u00e9marrer le projet.<\/p>\n<p><\/p>\n<p>Ici, nous avons appliqu\u00e9 deux fichiers docker-compose. Cela a \u00e9t\u00e9 fait pour avoir la possibilit\u00e9 de d\u00e9marrer de mani\u00e8re progressive. Lorsque le d\u00e9veloppeur travaille avec le c\u0153ur, il n'a pas besoin de notifications push, il lance simplement le fichier docker-compose, ce qui permet d'\u00e9conomiser des ressources.<\/p>\n<p><\/p>\n<p>Si une int\u00e9gration avec les notifications push est n\u00e9cessaire, alors docker-compose.yaml et docker-compose-push.yaml sont lanc\u00e9s.<\/p>\n<p><\/p>\n<p>Comme docker-compose.yaml et docker-compose-push.yaml se trouvent dans le m\u00eame dossier, un r\u00e9seau virtuel unique est automatiquement cr\u00e9\u00e9.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/535019c82c72c1602176fbaf4aa5640f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Description des composants. C'est un fichier plus d\u00e9taill\u00e9 qui g\u00e8re l'assemblage des composants. Qu'est-ce qui est notable ici ? Nous introduisons le composant load balancer.<\/p>\n<p><\/p>\n<p>C'est une image Docker pr\u00eate, qui ex\u00e9cute nginx et une application qui \u00e9coute le socket Docker. Il r\u00e9g\u00e9n\u00e8re dynamiquement la configuration de nginx \u00e0 mesure que les conteneurs sont ajout\u00e9s ou supprim\u00e9s. L'interaction avec les composants est r\u00e9partie sur des noms de domaine de troisi\u00e8me niveau.<\/p>\n<p><\/p>\n<p>Pour l'environnement de d\u00e9veloppement, nous utilisons le domaine .dev \u2014 api.informer.dev. Les applications avec le domaine .dev sont accessibles sur la machine locale du d\u00e9veloppeur.<\/p>\n<p><\/p>\n<p>Ensuite, les configurations sont transmises \u00e0 chaque projet et tous les projets sont lanc\u00e9s ensemble simultan\u00e9ment.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/bc1e11e6f1fd1c837d2c8087d04145c4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Si nous devions l'illustrer graphiquement, le client serait notre navigateur ou un outil \u00e0 partir duquel nous faisons des requ\u00eates au load balancer.<\/p>\n<p><\/p>\n<p>Le load balancer d\u00e9termine, en fonction du nom de domaine, \u00e0 quel conteneur il doit s'adresser.<\/p>\n<p><\/p>\n<p>Cela peut \u00eatre nginx, qui sert les fichiers JS de l'interface d'administration. Cela peut \u00eatre nginx, qui sert l'API ou des fichiers statiques, qui sont servis par nginx sous forme de t\u00e9l\u00e9chargement d'images.<\/p>\n<p><\/p>\n<p>Le sch\u00e9ma montre que les conteneurs sont regroup\u00e9s dans un r\u00e9seau virtuel et sont cach\u00e9s derri\u00e8re un proxy.<\/p>\n<p><\/p>\n<p>Sur la machine du d\u00e9veloppeur, on peut acc\u00e9der au conteneur en connaissant l'IP, mais nous ne l'appliquons pas vraiment. Il n'y a pratiquement jamais besoin d'acc\u00e8s direct.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/2908c31fd9d3c79f6189bdbeeb6d028f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Quel exemple regarder pour dockeriser votre application ? \u00c0 mon avis, un bon exemple est l'image Docker officielle pour MySQL.<\/p>\n<p><\/p>\n<p>C'est assez complexe. Il y a de nombreuses versions. Mais sa fonctionnalit\u00e9 permet de r\u00e9pondre \u00e0 de nombreux besoins qui peuvent survenir lors du d\u00e9veloppement ult\u00e9rieur. Si vous passez du temps \u00e0 comprendre comment tout cela interagit, je pense qu'il n'y aura pas de probl\u00e8mes avec l'impl\u00e9mentation autonome.<\/p>\n<p><\/p>\n<p>Sur hub.docker.com, il y a g\u00e9n\u00e9ralement des liens vers github.com, o\u00f9 se trouvent les donn\u00e9es brutes pour assembler l'image par vous-m\u00eame.<\/p>\n<p><\/p>\n<p>Ensuite, dans ce d\u00e9p\u00f4t, il y a un script docker-endpoint.sh qui est responsable de l'initialisation initiale et de la gestion du lancement de l'application.<\/p>\n<p><\/p>\n<p>Cet exemple inclut \u00e9galement une option de configuration via des variables d'environnement. En d\u00e9finissant une variable d'environnement lors du lancement d'un conteneur unique ou via docker-compose, nous pouvons indiquer que nous devons d\u00e9finir un mot de passe vide pour docker ou un autre que nous souhaitons pour root sur MySQL.<\/p>\n<p><\/p>\n<p>Il est possible de cr\u00e9er un mot de passe al\u00e9atoire. Nous indiquons qu'un utilisateur est n\u00e9cessaire, qu'il faut d\u00e9finir un mot de passe pour cet utilisateur et qu'une base de donn\u00e9es doit \u00eatre cr\u00e9\u00e9e.<\/p>\n<p><\/p>\n<p>Dans nos projets, nous avons unifi\u00e9 un peu le Dockerfile qui est responsable de l'initialisation. Nous l'avons adapt\u00e9 \u00e0 nos besoins pour simplement \u00e9tendre les droits de l'utilisateur que l'application utilise. Cela a permis de cr\u00e9er facilement une base de donn\u00e9es depuis la console de l'application. Dans les applications Ruby, il y a des commandes pour cr\u00e9er, modifier et supprimer des bases de donn\u00e9es.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/4a9b56e21819d28dd39753134d23fee4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Cet exemple montre \u00e0 quoi ressemble une version sp\u00e9cifique de MySQL sur github.com. Le Dockerfile peut \u00eatre ouvert et consult\u00e9 pour voir comment l'installation se d\u00e9roule.<\/p>\n<p><\/p>\n<p>Le script docker-endpoint.sh est responsable du point d'entr\u00e9e. Lors de l'initialisation initiale, certaines actions de pr\u00e9paration sont requises, et toutes ces actions sont mises en \u0153uvre dans le script d'initialisation.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/4153fa46526f3d802931dd1db48b08cd.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Passons \u00e0 la deuxi\u00e8me partie.<\/p>\n<p><\/p>\n<p>Pour le stockage des codes sources, nous sommes pass\u00e9s \u00e0 GitLab. C'est un syst\u00e8me assez puissant qui dispose d'une interface visuelle.<\/p>\n<p><\/p>\n<p>Un des composants de GitLab est GitLab CI. Cela permet de d\u00e9crire une suite de commandes qui seront utilis\u00e9es pour organiser un syst\u00e8me de livraison de code ou pour ex\u00e9cuter des tests automatis\u00e9s.<\/p>\n<p><\/p>\n<p>Pr\u00e9sentation sur GitLab CI 2 <noindex><a rel=\"nofollow\" href=\"https:\/\/goo.gl\/uohKjI\">https:\/\/goo.gl\/uohKjI<\/a><\/noindex> \u2014 pr\u00e9sentation du Ruby Russia club \u2014 assez d\u00e9taill\u00e9e et susceptible de vous int\u00e9resser.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/5d26d20500f34eeb9768e6c3d91bbefa.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Maintenant, nous allons examiner ce qui est n\u00e9cessaire pour activer GitLab CI. Pour d\u00e9marrer GitLab CI, il suffit de placer un fichier .gitlab-ci.yml \u00e0 la racine du projet.<\/p>\n<p><\/p>\n<p>Ici, nous d\u00e9crivons ce que nous voulons ex\u00e9cuter en termes de s\u00e9quence d'\u00e9tats comme des tests, des d\u00e9ploiements.<\/p>\n<p><\/p>\n<p>Nous ex\u00e9cutons des scripts qui d\u00e9clenchent directement la construction de notre application avec docker-compose. C'est un exemple de backend.<\/p>\n<p><\/p>\n<p>Ensuite, nous indiquons qu'il est n\u00e9cessaire d'ex\u00e9cuter les migrations pour modifier la base de donn\u00e9es et de r\u00e9aliser les tests.<\/p>\n<p><\/p>\n<p>Si les scripts s'ex\u00e9cutent correctement et ne renvoient pas de code d'erreur, le syst\u00e8me passe \u00e0 la deuxi\u00e8me phase du d\u00e9ploiement.<\/p>\n<p><\/p>\n<p>La phase de d\u00e9ploiement est actuellement mise en \u0153uvre pour staging. Nous n'avons pas organis\u00e9 de red\u00e9marrage sans interruption.<\/p>\n<p><\/p>\n<p>Nous \u00e9teignons tous les conteneurs de force, puis nous relan\u00e7ons tous les conteneurs, construits lors de la premi\u00e8re \u00e9tape de test.<\/p>\n<p><\/p>\n<p>Nous ex\u00e9cutons d\u00e9j\u00e0 pour l'environnement variable actuel les migrations de bases de donn\u00e9es qui ont \u00e9t\u00e9 \u00e9crites par les d\u00e9veloppeurs.<\/p>\n<p><\/p>\n<p>Il y a une note stipulant que cela ne doit \u00eatre appliqu\u00e9 que pour la branche master.<\/p>\n<p><\/p>\n<p>Lors de la modification d'autres branches, cela ne s'ex\u00e9cute pas.<\/p>\n<p><\/p>\n<p>Il est possible d'organiser des d\u00e9ploiements par branches.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/8a5b880bd9a0d4bab0b276568e2ba413.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pour organiser cela davantage, nous devons installer GitLab Runner.<\/p>\n<p><\/p>\n<p>C'est un utilitaire \u00e9crit en Golang. Il s'agit d'un fichier unique, comme c'est courant dans le monde de Golang, et il n'y a pas besoin de d\u00e9pendances.<\/p>\n<p><\/p>\n<p>Lors du lancement, nous enregistrons le GitLab Runner.<\/p>\n<p><\/p>\n<p>Nous obtenons la cl\u00e9 dans l'interface Web de GitLab.<\/p>\n<p><\/p>\n<p>Ensuite, nous ex\u00e9cutons la commande d'initialisation dans la ligne de commande.<\/p>\n<p><\/p>\n<p>Nous configurons le GitLab Runner en mode dialogue (Shell, Docker, VirtualBox, SSH).<\/p>\n<p><\/p>\n<p>Le code sur GitLab Runner s'ex\u00e9cutera \u00e0 chaque commit en fonction de la configuration de .gitlab-ci.yml.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/37c8ac7499f0cfba2eb07a84083e44e1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Voici \u00e0 quoi cela ressemble visuellement dans GitLab via l'interface web. Une fois que nous avons connect\u00e9 GitLab CI, un drapeau appara\u00eet, indiquant l'\u00e9tat actuel du build.<\/p>\n<p><\/p>\n<p>Nous voyons qu'il y a eu un commit il y a 4 minutes, passant tous les tests sans probl\u00e8mes.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/33ac79c45f0651a5f8bde75092c4ac44.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nous pouvons examiner les builds plus en d\u00e9tail. Ici, nous voyons que deux \u00e9tats ont d\u00e9j\u00e0 \u00e9t\u00e9 atteints : l'\u00e9tat de test et l'\u00e9tat de d\u00e9ploiement sur staging.<\/p>\n<p><\/p>\n<p>Si nous cliquons sur un build sp\u00e9cifique, nous y trouverons la sortie de la console des commandes qui ont \u00e9t\u00e9 ex\u00e9cut\u00e9es en suivant le fichier .gitlab-ci.yml.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/d26dd28708c7fc8a409af4be4d48f502.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Voici l'historique de notre produit. Nous voyons qu'il y a eu des tentatives r\u00e9ussies. Lorsque les tests \u00e9chouent, la proc\u00e9dure ne passe pas \u00e0 l'\u00e9tape suivante et le code sur staging n'est pas mis \u00e0 jour.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/ee7bd81dc283c7af0c194779d4230780.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Quelles t\u00e2ches avons-nous d\u00fb r\u00e9soudre sur staging lors de l'int\u00e9gration de Docker ? Notre syst\u00e8me est compos\u00e9 de plusieurs composants et nous avons eu besoin de red\u00e9marrer uniquement les parties mises \u00e0 jour dans le d\u00e9p\u00f4t, plut\u00f4t que l'ensemble du syst\u00e8me.<\/p>\n<p><\/p>\n<p>Pour cela, nous avons d\u00fb organiser le tout dans des dossiers s\u00e9par\u00e9s.<\/p>\n<p><\/p>\n<p>Une fois cela fait, nous avons rencontr\u00e9 le probl\u00e8me que Docker-compose cr\u00e9e pour chaque dossier son propre espace r\u00e9seau, ne voyant pas les composants voisins.<\/p>\n<p><\/p>\n<p>Pour contourner cela, nous avons cr\u00e9\u00e9 un r\u00e9seau dans Docker manuellement. Dans Docker-compose, nous avons sp\u00e9cifi\u00e9 d'utiliser ce r\u00e9seau pour ce projet.<\/p>\n<p><\/p>\n<p>Ainsi, chaque composant d\u00e9marrant avec ce r\u00e9seau peut voir les composants d'autres parties du syst\u00e8me.<\/p>\n<p><\/p>\n<p>Le prochain probl\u00e8me est la s\u00e9paration de staging entre plusieurs projets.<\/p>\n<p><\/p>\n<p>Pour que tout soit bien organis\u00e9 et le plus proche possible de la production, il est bon d'utiliser le port 80 ou 443, qui sont largement utilis\u00e9s dans le WEB.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/f863cf1833271bf132455a70ad7d2706.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Comment avons-nous r\u00e9solu cela ? Nous avons attribu\u00e9 un GitLab Runner \u00e0 tous les grands projets.<\/p>\n<p><\/p>\n<p>GitLab permet de lancer plusieurs GitLab Runners distribu\u00e9s qui prendront les t\u00e2ches de mani\u00e8re al\u00e9atoire et les ex\u00e9cuteront.<\/p>\n<p><\/p>\n<p>Pour \u00e9viter le chaos, nous avons limit\u00e9 notre groupe de projets \u00e0 un seul GitLab Runner, qui g\u00e8re nos volumes sans probl\u00e8me.<\/p>\n<p><\/p>\n<p>Nous avons d\u00e9plac\u00e9 nginx-proxy dans un script de d\u00e9marrage s\u00e9par\u00e9, dans lequel nous avons d\u00e9fini les r\u00e9seaux de tous les projets. <\/p>\n<p><\/p>\n<p>Notre projet a un r\u00e9seau, tandis que le r\u00e9partiteur en a plusieurs nomm\u00e9s d'apr\u00e8s les projets, pouvant proxy par les noms de domaine.<\/p>\n<p><\/p>\n<p>Nous recevons des requ\u00eates sur le port 80 du domaine, qui sont g\u00e9r\u00e9es par un groupe de conteneurs d\u00e9di\u00e9s \u00e0 ce domaine.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/25c769f029b272a17fd06bbe60cf0ea0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Quels autres probl\u00e8mes y a-t-il eu ? C'est que par d\u00e9faut tous les conteneurs s'ex\u00e9cutent sous l'utilisateur root. Ce root n'est pas le m\u00eame root que celui de l'h\u00f4te du syst\u00e8me.<\/p>\n<p><\/p>\n<p>Cependant, si l'on entre dans le conteneur, on devient root et le fichier que nous cr\u00e9ons dans ce conteneur obtient des droits root.<\/p>\n<p><\/p>\n<p>Si un d\u00e9veloppeur est entr\u00e9 dans le conteneur et a ex\u00e9cut\u00e9 certaines commandes qui g\u00e9n\u00e8rent des fichiers, puis qu'il sort du conteneur, il se retrouve avec un fichier dans son r\u00e9pertoire de travail auquel il n'a pas acc\u00e8s.<\/p>\n<p><\/p>\n<p>Comment peut-on r\u00e9soudre cela ? On peut ajouter des utilisateurs qui seront dans le conteneur.<\/p>\n<p><\/p>\n<p>Quels probl\u00e8mes sont survenus lorsque nous avons ajout\u00e9 un utilisateur ?<\/p>\n<p><\/p>\n<p>En cr\u00e9ant un utilisateur, il arrive souvent que l'ID du groupe (UID) et l'ID de l'utilisateur (GID) ne co\u00efncident pas.<\/p>\n<p><\/p>\n<p>Pour r\u00e9soudre ce probl\u00e8me, nous utilisons dans le conteneur des utilisateurs avec l'ID 1000.<\/p>\n<p><\/p>\n<p>Dans notre cas, cela correspond au fait que presque tous les d\u00e9veloppeurs utilisent le syst\u00e8me d'exploitation Ubuntu. Et sur Ubuntu, le premier utilisateur a l'ID 1000.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/d4911374e4953fdcd807c387efeafec3.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Quels sont nos projets ?<\/p>\n<p><\/p>\n<p>Relire la documentation sur Docker. Le projet est en d\u00e9veloppement actif, la documentation change. Les informations obtenues il y a deux ou trois mois commencent d\u00e9j\u00e0 \u00e0 devenir obsol\u00e8tes. <\/p>\n<p><\/p>\n<p>Certaines des probl\u00e8mes que nous avons r\u00e9solus sont probablement d\u00e9j\u00e0 r\u00e9gl\u00e9s par les moyens standards.<\/p>\n<p><\/p>\n<p>Nous avons vraiment envie d'aller plus loin et de passer directement \u00e0 l'orchestration.<\/p>\n<p><\/p>\n<p>Un des exemples est le m\u00e9canisme int\u00e9gr\u00e9 \u00e0 Docker appel\u00e9 Docker Swarm, qui est fourni par d\u00e9faut. Nous avons envie de lancer quelque chose en production bas\u00e9 sur la technologie Docker Swarm.<\/p>\n<p><\/p>\n<p>La g\u00e9n\u00e9ration de conteneurs complique le travail avec les logs. Actuellement, les logs sont isol\u00e9s. Ils sont \u00e9parpill\u00e9s \u00e0 travers les conteneurs. L'une des t\u00e2ches est de rendre l'acc\u00e8s aux logs plus facile via une interface web.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Le processus de d\u00e9veloppement et de test avec Docker et Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/cff8c72dd8af7de1fa0227601bd1d69c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Source : <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/449742\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u0430 \u0421\u0438\u0433\u0430\u0447\u0435\u0432\u0430 \u0438\u0437 Inventos &#171;\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Docker + Gitlab CI&#187; \u0422\u0435, \u043a\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 \u0431\u0430\u0437\u0435 Docker + Gitlab CI \u0447\u0430\u0441\u0442\u043e \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u044e\u0442 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0432\u043e\u043f\u0440\u043e\u0441\u044b. \u0421 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u0442\u044c? \u041a\u0430\u043a \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c? \u041a\u0430\u043a \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c? \u042d\u0442\u043e\u0442 \u0434\u043e\u043a\u043b\u0430\u0434 \u0445\u043e\u0440\u043e\u0448 \u0442\u0435\u043c, \u0447\u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":24326,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-32526","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u0430 \u0421\u0438\u0433\u0430\u0447\u0435\u0432\u0430 \u0438\u0437 Inventos &quot;\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Docker + Gitlab CI&quot; \u0422\u0435, \u043a\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"fr_FR\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Docker \u0438 Gitlab CI | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u0430 \u0421\u0438\u0433\u0430\u0447\u0435\u0432\u0430 \u0438\u0437 Inventos &quot;\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Docker + Gitlab CI&quot; \u0422\u0435, \u043a\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:47:32+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:47:32+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Processus de d\u00e9veloppement et de test avec Docker et Gitlab CI | ProHoster","description":"Je propose de consulter l'analyse de la pr\u00e9sentation d'Alexandre Sigatchev d'Inventos \"Le processus de d\u00e9veloppement et de test avec Docker + Gitlab CI\". Pour ceux qui commencent \u00e0 mettre en \u0153uvre le processus de d\u00e9veloppement.","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"fr_FR","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Docker \u0438 Gitlab CI | ProHoster","og:description":"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u0430 \u0421\u0438\u0433\u0430\u0447\u0435\u0432\u0430 \u0438\u0437 Inventos &quot;\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Docker + Gitlab CI&quot; \u0422\u0435, \u043a\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438.","og:url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:47:32+00:00","article:modified_time":"2019-10-31T18:47:32+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"32526","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 11:18:24","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 02:57:22","updated":"2026-01-21 11:18:24","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/32526","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/comments?post=32526"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/32526\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media\/24326"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=32526"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=32526"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=32526"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}