<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Developpement sur Olivier DOSSMANN</title>
    <link>https://olivier.dossmann.net/tags/developpement/</link>
    <description>Contenu récent dans Developpement sur Olivier DOSSMANN</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>fr</language>
    <copyright>© 2005-2026 Olivier DOSSMANN</copyright>
    <lastBuildDate>Sun, 18 May 2025 13:55:39 +0200</lastBuildDate><atom:link href="https://olivier.dossmann.net/tags/developpement/index.xml" rel="self" type="application/rss+xml" />
    <item>
	    <title>Ce que j&#39;aurais voulu savoir sur Gitlab CI</title>
      <link>https://olivier.dossmann.net/2025/05/ce-que-jaurais-voulu-savoir-sur-gitlab-ci/</link>
      <pubDate>Sun, 18 May 2025 13:55:39 +0200</pubDate>
      
      <guid>https://olivier.dossmann.net/2025/05/ce-que-jaurais-voulu-savoir-sur-gitlab-ci/</guid>
      <description>&lt;h1 id=&#34;introduction&#34;&gt;Introduction&lt;/h1&gt;
&lt;p&gt;Il y a quelques mois &lt;a href=&#34;https://olivier.dossmann.net/2024/10/mes_conseils_pour_reussir_une_formation_bootcamp/&#34;&gt;je parlais de ma formation Bootcamp pour devenir Ingénieur DevOps&lt;/a&gt;. J&amp;rsquo;y ai utilisé - à nouveau - &lt;strong&gt;Gitlab CI&lt;/strong&gt; (Continuous Integration). Vous savez, cet &lt;strong&gt;outil permettant d&amp;rsquo;exécuter des actions&lt;/strong&gt; après avoir envoyé votre code/dépôt sur la plateforme Gitlab ?&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est très utile, par exemple pour &lt;strong&gt;lancer les tests&lt;/strong&gt; sur votre code, vérifier que &lt;strong&gt;le code s&amp;rsquo;exécute dans un environnement précis&lt;/strong&gt; ou tout simplement vérifier que &lt;strong&gt;le code compile&lt;/strong&gt;. Et si votre dépôt n&amp;rsquo;est pas du code, par exemple un site web, vous pouvez tester les liens morts ; voire publier votre site ! &lt;strong&gt;Les possibilités sont - finalement - nombreuses&lt;/strong&gt; !&lt;/p&gt;
&lt;p&gt;En revanche, un tel outil est parfois déstabilisant. Et des cheveux, j&amp;rsquo;en ai arrachés ! J&amp;rsquo;aurais apprécié tomber sur un article explicatif. Avec des astuces. Peut-être que le présent article m&amp;rsquo;aurait convenu, qui sait !&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;aurai par exemple aimé savoir comment &lt;strong&gt;publier facilement un site web&lt;/strong&gt;, &lt;strong&gt;tester localement&lt;/strong&gt; le fichier &lt;em&gt;.gitlab-ci.yml&lt;/em&gt; avant de l&amp;rsquo;envoyer sur Gitlab, connaître &lt;strong&gt;plus d&amp;rsquo;astuces&lt;/strong&gt; pour les mots clés Gitlab, savoir &lt;strong&gt;utiliser Docker dans Gitlab CI&lt;/strong&gt; et ce que sont les &lt;strong&gt;composants réutilisables&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Ce sont ainsi tous les sujets que nous allons aborder aujourd&amp;rsquo;hui.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/nature/raton_laveur.jpg&#34; alt=&#34;Un visage de Raton Laveur&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Photo trouvée sur le &lt;a href=&#34;https://www.flickr.com/photos/131830853@N05/&#34;&gt;profil de didier.camus sur Flickr&lt;/a&gt;&lt;/em&gt; sous Licence Œuvre du domaine public.&lt;/p&gt;
&lt;h1 id=&#34;publier-rapidement-un-site-statique&#34;&gt;Publier rapidement un site statique&lt;/h1&gt;
&lt;p&gt;Gitlab met à disposition des utilisateurs un &lt;strong&gt;espace permettant d&amp;rsquo;héberger des sites webs statiques&lt;/strong&gt;. Incroyable n&amp;rsquo;est-ce pas ? Cet espace est &lt;a href=&#34;https://docs.gitlab.com/user/project/pages/&#34; title=&#34;Voir la documentation de Gitlab concernant Gitlab Pages&#34;&gt;Gitlab Pages&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Comment cela fonctionne ? Il suffit de créer un dépôt Gitlab, d&amp;rsquo;ajouter un fichier &lt;strong&gt;.gitlab-ci.yml&lt;/strong&gt; contenant la section suivante :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;busybox&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;pages&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;stage&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;deploy&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;script&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- echo &amp;#34;The site will be deployed to $CI_PAGES_URL&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;artifacts&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;paths&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- public&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;rules&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;if&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Code récupéré du projet &lt;a href=&#34;https://gitlab.com/pages/plain-html&#34;&gt;https://gitlab.com/pages/plain-html&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Cela signifie qu&amp;rsquo;au terme de la CI/CD (dans l&amp;rsquo;étape nommée &lt;em&gt;deploy&lt;/em&gt;), &lt;strong&gt;le contenu du dossier public sera publié sur Gitlab Pages&lt;/strong&gt;. À quelle adresse ? Imaginons que vous partez d&amp;rsquo;un dépôt dont l&amp;rsquo;adresse est : &lt;code&gt;https://gitlab.com/blankoworld/monprojet/&lt;/code&gt;, l&amp;rsquo;adresse URL d&amp;rsquo;accès à votre site publié sera : &lt;code&gt;https://blankoworld.gitlab.io/monprojet/&lt;/code&gt;. Pratique non ?&lt;/p&gt;
&lt;p&gt;Astuce : Si votre dépôt est privé, vous pouvez quand même rendre votre site public. Il suffit d&amp;rsquo;aller dans &lt;strong&gt;Settings &amp;gt; General&lt;/strong&gt;, Section « &lt;strong&gt;Visibility, project features, permissions&lt;/strong&gt; » et dans le sous-titre « &lt;strong&gt;Pages&lt;/strong&gt; », activez la fonctionnalité. Et dans le menu déroulant à côté, choisissez « &lt;strong&gt;Everyone&lt;/strong&gt; ». N&amp;rsquo;oubliez pas de &lt;strong&gt;sauvegarder&lt;/strong&gt; cette configuration. Le code sera privé, le site web statique public !&lt;/p&gt;
&lt;p&gt;Pour &lt;strong&gt;plus d&amp;rsquo;exemple&lt;/strong&gt;, veuillez vous rendre sur la page Gitlab présentant la &lt;a href=&#34;https://gitlab.com/pages&#34; title=&#34;Liste d&#39;exemple de projets utilisant Gitlab Pages&#34;&gt;liste de projets utilisant Gitlab Pages&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;tester-avant-denvoyer-sur-le-dépôt-&#34;&gt;Tester avant d&amp;rsquo;envoyer sur le dépôt ?&lt;/h1&gt;
&lt;p&gt;Le truc vraiment embêtant avec les fichiers &lt;em&gt;.gitlab-ci.yml&lt;/em&gt;, c&amp;rsquo;est qu&amp;rsquo;&lt;strong&gt;on ne peut pas les tester sur notre machine&lt;/strong&gt; (localement). Pour avancer il faut :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;modifier le fichier &lt;em&gt;.gitlab-ci.yml&lt;/em&gt;,&lt;/li&gt;
&lt;li&gt;le valider (faire un commit),&lt;/li&gt;
&lt;li&gt;l&amp;rsquo;envoyer sur Gitlab,&lt;/li&gt;
&lt;li&gt;patienter que la pipeline se lance (et parfois se termine),&lt;/li&gt;
&lt;li&gt;bénéficier du résultat ou, dans la plupart des cas, recommencer à l&amp;rsquo;étape 1…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;À une époque on pouvait utiliser une commande &lt;code&gt;gitlab-runner exec&lt;/code&gt; en local. Mais celle-ci a été supprimée : &lt;a href=&#34;https://gitlab.com/gitlab-org/gitlab-runner/-/commit/f8508c924f80b104ec7353353e6ad0edb5daae66&#34;&gt;https://gitlab.com/gitlab-org/gitlab-runner/-/commit/f8508c924f80b104ec7353353e6ad0edb5daae66&lt;/a&gt; .&lt;/p&gt;
&lt;p&gt;Suivant ce que nous faisons dans la CI/CD de Gitlab, il est possible d&amp;rsquo;utiliser un outil bien pratique nommé &lt;strong&gt;gitlab-ci-local&lt;/strong&gt; : &lt;a href=&#34;https://github.com/firecow/gitlab-ci-local&#34; title=&#34;Se rendre sur la page Github du projet gitlab-ci-local&#34;&gt;gitlab-ci-local&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Vous trouverez quelques détails de &lt;a href=&#34;https://olivier.dossmann.net/wiki/developpement/gitlab-ci-local/&#34; title=&#34;Visiter le recueil d&#39;astuces d&#39;Olivier concernant l&#39;outil gitlab-ci-local&#34;&gt;gitlab-ci-local sur mon recueil d&amp;rsquo;astuces&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;généralités&#34;&gt;Généralités&lt;/h1&gt;
&lt;p&gt;Voici quelques pistes intéressantes sur le sujet Gitlab :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Une &lt;strong&gt;documentation de départ&lt;/strong&gt; est : &lt;a href=&#34;https://docs.gitlab.com/topics/build_your_application/&#34;&gt;https://docs.gitlab.com/topics/build_your_application/&lt;/a&gt;. Elle permet d&amp;rsquo;en savoir plus sur la &lt;a href=&#34;https://docs.gitlab.com/ci/yaml/&#34; title=&#34;Lire la documentation officielle de Gitlab concernant la syntaxe du fichier *gitlab-ci.yml*&#34;&gt;syntaxe de gitlab-ci.yaml&lt;/a&gt;, les &lt;a href=&#34;https://docs.gitlab.com/ci/variables/predefined_variables/&#34; title=&#34;En savoir plus sur les variables pré-définies dans la CI Gitlab&#34;&gt;variables pré-définies&lt;/a&gt; ou encore le &lt;a href=&#34;https://docs.gitlab.com/ci/pipelines/pipeline_architectures/#basic-pipelines&#34; title=&#34;Découvrir les pipelines de Gitlab CI&#34;&gt;fonctionnement d&amp;rsquo;un pipeline dans Gitlab CI&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;Toujours utiles : les actions que je nomme comme « &lt;strong&gt;globales&lt;/strong&gt; ». Par exemple les mots clés &lt;code&gt;image&lt;/code&gt;, &lt;code&gt;variables&lt;/code&gt; ou &lt;code&gt;before_script&lt;/code&gt; peuvent &lt;strong&gt;être utilisés en début du fichier&lt;/strong&gt; pour définir des actions ou des valeurs qui &lt;strong&gt;seront utilisées dans toutes les étapes du pipeline&lt;/strong&gt;. Ce qui peut être un avantage, ou un inconvénient. Exemple : &lt;code&gt;image: ubuntu:latest&lt;/code&gt; va définir que toutes les étapes se lanceront dans un docker partant de l&amp;rsquo;image Ubuntu,&lt;/li&gt;
&lt;li&gt;Entrées/sorties : &lt;strong&gt;un artefact = une sortie&lt;/strong&gt;. C&amp;rsquo;est à dire des fichiers utilisables/disponibles pour les étapes suivantes (donc en &lt;strong&gt;entrée pour les autres étapes&lt;/strong&gt;) en utilisant le mot clé &lt;strong&gt;dependencies&lt;/strong&gt; (Cf. &lt;a href=&#34;https://docs.gitlab.com/ci/jobs/job_artifacts/#fetching-artifacts)&#34;&gt;https://docs.gitlab.com/ci/jobs/job_artifacts/#fetching-artifacts)&lt;/a&gt;. Sauf si &lt;code&gt;dependencies = []&lt;/code&gt; est utilisé.&lt;/li&gt;
&lt;li&gt;Utiliser des &lt;strong&gt;variables globales en début du fichier&lt;/strong&gt; (par exemple pour les numéros de versions) fait gagner du temps sur le long terme. Exemple :&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;variables&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;DOCKER_VERSION&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;27.3.1&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;UBUNTU_VERSION&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;24.04&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Concernant le &lt;strong&gt;mot clé script&lt;/strong&gt; :
&lt;ul&gt;
&lt;li&gt;si on veut écrire plusieurs lignes, utiliser la syntaxe suivante :&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;script&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- echo &amp;#34;première étape des scripts&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- |&lt;span style=&#34;color:#4070a0;font-style:italic&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#4070a0;font-style:italic&#34;&gt;    echo &amp;#34;première ligne&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#4070a0;font-style:italic&#34;&gt;    echo &amp;#34;seconde ligne&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#4070a0;font-style:italic&#34;&gt;    echo &amp;#34;etc.&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;limiter à 10 lignes max&lt;/strong&gt;imum,&lt;/li&gt;
&lt;li&gt;si on utilise la syntaxe pour écrire plusieurs lignes, le &lt;strong&gt;debug&lt;/strong&gt; est plus &lt;strong&gt;difficile&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Pour &lt;strong&gt;organiser les étapes&lt;/strong&gt;, on peut donner à chacune d&amp;rsquo;elle une &lt;strong&gt;étape pré-requise en utilisant le mot clé « &lt;a href=&#34;https://docs.gitlab.com/ci/yaml/#needs&#34; title=&#34;En savoir plus sur le mot clé needs dans la documentation de Gitlab&#34;&gt;needs&lt;/a&gt; »&lt;/strong&gt;, cela permet de chaîner les étapes dans un certain ordre. Exemple : si on veut que l&amp;rsquo;étape « deploy » se fasse après « compile », alors à la fin de l&amp;rsquo;étape « deploy » on met &lt;code&gt;needs: [compile]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;le-cas-docker&#34;&gt;Le Cas Docker&lt;/h1&gt;
&lt;h2 id=&#34;création-dune-image-docker-dans-un-conteneur-docker&#34;&gt;Création d&amp;rsquo;une image Docker… dans un conteneur Docker&lt;/h2&gt;
&lt;p&gt;Dans la situation où vous voudriez &lt;strong&gt;fabriquer des images Docker&lt;/strong&gt;, vous allez être confrontés à plusieurs problématiques :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;il faut utiliser des commandes &lt;code&gt;docker&lt;/code&gt; pour créer des images,&lt;/li&gt;
&lt;li&gt;mais la plupart des Gitlab Runner exécutent les étapes de Gitlab CI dans un Docker,&lt;/li&gt;
&lt;li&gt;donc on se retrouve à vouloir exécuter des commandes &lt;code&gt;docker&lt;/code&gt; dans un environnement Docker.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Vous voyez le problème ?&lt;/p&gt;
&lt;p&gt;Pour contourner cette situation il suffit d&amp;rsquo;&lt;strong&gt;utiliser &lt;a href=&#34;https://docs.gitlab.com/ci/docker/using_docker_build/#use-docker-in-docker&#34; title=&#34;Se rendre sur la documentation officielle de Gitlab CI au sujet de Docker-in-Docker&#34;&gt;Docker-in-Docker&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;En somme le début du fichier &lt;em&gt;.gitlab-ci.yml&lt;/em&gt; ressemblera à :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;variables&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;DOCKER_VERSION&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;27.4.1&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;docker:$DOCKER_VERSION&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;services&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- docker:$DOCKER_VERSION-dind&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;sidentifier&#34;&gt;S&amp;rsquo;identifier&lt;/h2&gt;
&lt;p&gt;Pour utiliser les dépôts de conteneurs de Gitlab, rien de plus simple il suffit d&amp;rsquo;écrire le code suivant dans le fichier &lt;em&gt;.gitlab-ci.yml&lt;/em&gt; :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;before_script&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- docker info&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- echo &amp;#34;$CI_REGISTRY_PASSWORD&amp;#34; | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Nul besoin de renseigner les variables. Elles sont renseignées par Gitlab CI.&lt;/p&gt;
&lt;h2 id=&#34;construire-limage&#34;&gt;Construire l&amp;rsquo;image&lt;/h2&gt;
&lt;p&gt;Pour construire l&amp;rsquo;image cela va ressembler à :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;variables&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;CONTAINER_TEST_IMAGE&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;build-image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;stage&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;build&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;script&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- docker pull &amp;#34;$CONTAINER_TEST_IMAGE&amp;#34; || true&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- docker build --build-arg BUILDKIT_INLINE_CACHE=1 -t $CONTAINER_TEST_IMAGE .&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- docker push $CONTAINER_TEST_IMAGE&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On part du principe que &lt;strong&gt;le fichier Dockerfile est situé à la racine&lt;/strong&gt; de votre projet Gitlab.&lt;/p&gt;
&lt;p&gt;CONTAINER_TEST_IMAGE est une variable &lt;strong&gt;globale&lt;/strong&gt; construite à partir des &lt;a href=&#34;https://docs.gitlab.com/ci/variables/predefined_variables/&#34; title=&#34;En savoir plus sur les variables pré-définies de Gitlab CI dans la documentation officielle de Gitlab&#34;&gt;&lt;strong&gt;variables pré-définies&lt;/strong&gt; de Gitlab CI&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;pousser-limage-sur-le-dépôt&#34;&gt;Pousser l&amp;rsquo;image sur le dépôt&lt;/h2&gt;
&lt;p&gt;Dans cette situation nous sommes contents d&amp;rsquo;avoir déjà ajouté l&amp;rsquo;authentification aux dépôts de conteneurs Gitlab.&lt;/p&gt;
&lt;p&gt;Cette fois on fait une étape pour récupérer l&amp;rsquo;image précédente et lui donner un nouveau nom :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;push-image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;stage&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;push&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;script&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- export IMAGE_TAG=&amp;#34;$(date +&amp;#39;%Y%m%d&amp;#39;)-${CI_COMMIT_SHORT_SHA}&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- docker pull $CONTAINER_TEST_IMAGE&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- docker tag $CONTAINER_TEST_IMAGE $CI_REGISTRY_IMAGE:$IMAGE_TAG&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- docker push $CI_REGISTRY_IMAGE:$IMAGE_TAG&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;rules&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- &lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;if&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;$CI_COMMIT_BRANCH == &amp;#34;main&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;L&amp;rsquo;idée est :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;de &lt;strong&gt;créer un nom de tag&lt;/strong&gt; pour l&amp;rsquo;image (variable IMAGE_TAG),&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;récupérer l&amp;rsquo;image précédente&lt;/strong&gt; - puisque les étapes d&amp;rsquo;un fichier &lt;em&gt;.gitlab-ci.yml&lt;/em&gt; s&amp;rsquo;exécutent dans des conteneurs isolés les uns des autres,&lt;/li&gt;
&lt;li&gt;apposer un &lt;strong&gt;nouveau tag&lt;/strong&gt; sur l&amp;rsquo;image récupérée,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;publier le résultat&lt;/strong&gt; en poussant l&amp;rsquo;image ainsi étiquetée.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ceci ne s&amp;rsquo;exécute que si la branche est nommée &lt;strong&gt;main&lt;/strong&gt;. Donc chaque commit sur cette branche générera une image Docker et un tag.&lt;/p&gt;
&lt;h2 id=&#34;ordre-dexécution-des-étapes&#34;&gt;Ordre d&amp;rsquo;exécution des étapes&lt;/h2&gt;
&lt;p&gt;Afin que les deux étapes précédentes s&amp;rsquo;exécutent dans un certain ordre, &lt;strong&gt;ne pas oublier les lignes suivantes&lt;/strong&gt; dans le fichier &lt;em&gt;.gitlab-ci.yml&lt;/em&gt; :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;stages&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- build&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- push&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;comme-si-ça-ne-suffisait-pas&#34;&gt;Comme si ça ne suffisait pas…&lt;/h2&gt;
&lt;p&gt;En outre, voici d&amp;rsquo;&lt;strong&gt;autres éléments à rajouter&lt;/strong&gt; dans son fichier &lt;em&gt;.gitlab-ci.yml&lt;/em&gt; :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;variables&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#60a0b0;font-style:italic&#34;&gt;# Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;DOCKER_HOST&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;tcp://docker:2376&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;DOCKER_TLS_CERTDIR&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;/certs&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ces lignes permettent de renseigner un &lt;strong&gt;autre accès à l&amp;rsquo;API Docker&lt;/strong&gt; pour lancer les commandes &lt;code&gt;docker&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&#34;les-composants-réutilisables&#34;&gt;Les composants réutilisables&lt;/h1&gt;
&lt;p&gt;Gitlab CI offre la possibilité d&amp;rsquo;utiliser des &lt;a href=&#34;https://docs.gitlab.com/ci/components/&#34;&gt;&lt;strong&gt;composants réutilisables&lt;/strong&gt;&lt;/a&gt; pour agrémenter les étapes de son fichier &lt;em&gt;.gitlab-ci.yml&lt;/em&gt;. Ceci évite de réinventer la roue (en codant soi-même).&lt;/p&gt;
&lt;p&gt;Plusieurs composants sont disponibles sur la &lt;a href=&#34;https://gitlab.com/components&#34;&gt;page Gitlab components&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Exemple d&amp;rsquo;utilisation d&amp;rsquo;un composant :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;include&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;- &lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;component&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;gitlab.com/components/container-scanning/container-scanning@5.1.0&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;C&amp;rsquo;est très utile dans certaines situations comme pour tester des fichiers Terraform (avec &lt;a href=&#34;https://gitlab.com/components/opentofu&#34;&gt;le composant OpenTofu&lt;/a&gt;), &lt;a href=&#34;https://gitlab.com/components/go&#34;&gt;le composant Go&lt;/a&gt;, &lt;a href=&#34;https://gitlab.com/components/go&#34;&gt;le composant Rust&lt;/a&gt; ou même utiliser les &lt;a href=&#34;https://gitlab.com/components/autodevops&#34;&gt;fonctionnalités Autodevops de Gitlab&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Au premier abord Gitlab CI paraît complexe et maigre en fonctionnalités. Cependant la lecture de la &lt;strong&gt;documentation (très fournie&lt;/strong&gt; !) donne rapidement un aperçu bien plus avantageux de cet outil. On y découvre les composants réutilisables, les mots clés &lt;code&gt;image&lt;/code&gt;, &lt;code&gt;variables&lt;/code&gt;, &lt;code&gt;before_script&lt;/code&gt;, les artefacts (sorties), les variables globales, le déploiement de sites statiques et j&amp;rsquo;en passe !&lt;/p&gt;
&lt;p&gt;Certaines difficultés telles que Docker viennent s&amp;rsquo;immiscer dans nos essais. Mais &lt;strong&gt;une fois les obstacles franchis c&amp;rsquo;est un outil très satisfaisant&lt;/strong&gt;. Je l&amp;rsquo;apprécie.&lt;/p&gt;
&lt;p&gt;Je serais ravi de tomber plus souvent sur des articles décrivant ses fonctionnalités. J&amp;rsquo;espère participer à une diffusion plus grande de la connaissance Gitlab CI et, qui sait, peut-être partagerais-je prochainement d&amp;rsquo;autres astuces ?&lt;/p&gt;
</description>
    </item>
    
    <item>
	    <title>Cookiecutter-trognon pour initialiser mes scripts Bash</title>
      <link>https://olivier.dossmann.net/2024/04/cookiecutter_pour_initialiser_mes_scripts_bash/</link>
      <pubDate>Sun, 28 Apr 2024 13:20:47 +0200</pubDate>
      
      <guid>https://olivier.dossmann.net/2024/04/cookiecutter_pour_initialiser_mes_scripts_bash/</guid>
      <description>&lt;h1 id=&#34;introduction&#34;&gt;Introduction&lt;/h1&gt;
&lt;p&gt;Pour la petite histoire, l&amp;rsquo;année dernière je lisais l&amp;rsquo;&lt;a href=&#34;https://www.deblan.io/post/647/modele-pour-demarrer-script-shell&#34;&gt;article de deblan sur la création d&amp;rsquo;un modèle de script Shell&lt;/a&gt; sur le &lt;a href=&#34;https://www.journalduhacker.net/&#34;&gt;journalduhacker&lt;/a&gt;. Cela m&amp;rsquo;a rappelé que tôt ou tard dans &lt;strong&gt;la quête de l&amp;rsquo;automatisation&lt;/strong&gt; on arrive toujours à faire &lt;strong&gt;nos propres modèles de scripts&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;La plupart de &lt;strong&gt;mes projets utilisent&lt;/strong&gt; le modèle de script &lt;a href=&#34;https://github.com/blankoworld/trognon&#34;&gt;&lt;strong&gt;Trognon&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Comment, en partant de ce modèle, pourrais-je automatiser la création de nouvelles commandes ? C&amp;rsquo;est là qu&amp;rsquo;entre en jeu &lt;a href=&#34;https://cookiecutter.readthedocs.io/en/stable/&#34;&gt;cookiecutter&lt;/a&gt;, une commande et une méthode permettant de &lt;strong&gt;transformer n&amp;rsquo;importe lequel de vos projet en template&lt;/strong&gt; pour les suivants !&lt;/p&gt;
&lt;p&gt;Nous commencerons par voir le résultat de l&amp;rsquo;adaptation d&amp;rsquo;un script avec &lt;a href=&#34;https://cookiecutter.readthedocs.io/en/stable/&#34;&gt;cookiecutter&lt;/a&gt;. Ensuite nous verrons ce qu&amp;rsquo;est &lt;a href=&#34;https://cookiecutter.readthedocs.io/en/stable/&#34;&gt;cookiecutter&lt;/a&gt;. Finalement nous expliquerons comment adapter son projet avec &lt;a href=&#34;https://cookiecutter.readthedocs.io/en/stable/&#34;&gt;cookiecutter&lt;/a&gt; en présentant le cas pratique de &lt;a href=&#34;https://github.com/blankoworld/cookiecutter-trognon&#34;&gt;cookiecutter-trognon&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/objets/lapins_chocolat.jpg&#34; alt=&#34;Des lapins de Pâques en chocolat, industrialisés et dupliqués à l&amp;rsquo;infini&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Photo trouvée sur le &lt;a href=&#34;https://flickr.com/photos/cogdog/52726715586/&#34;&gt;profil de Alan Levine sur Flickr&lt;/a&gt;&lt;/em&gt; sous Domaine public.&lt;/p&gt;
&lt;h1 id=&#34;le-résultat-cookiecutter-trognon&#34;&gt;Le résultat : cookiecutter-trognon&lt;/h1&gt;
&lt;p&gt;Pour une fois nous commencerons par la fin, c&amp;rsquo;est à dire le résultat ! &lt;strong&gt;L&amp;rsquo;automatisation de Trognon a donné un dépôt&lt;/strong&gt; : &lt;a href=&#34;https://github.com/blankoworld/cookiecutter-trognon&#34;&gt;cookiecutter-trognon&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Grâce à lui, créer un nouveau script Bash suivant le modèle de Trognon revient à taper les commandes suivantes :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#60a0b0;font-style:italic&#34;&gt;# Installe cookiecutter sur notre machine (à ne faire que la première fois)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pipx install cookiecutter
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#60a0b0;font-style:italic&#34;&gt;# Utilise mon dépôt Github de cookiecutter-trognon comme modèle&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cookiecutter gh:blankoworld/cookiecutter-trognon
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ensuite 2 questions sont posées pour définir :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;le &lt;strong&gt;nom du dossier&lt;/strong&gt; dans lequel ma commande se trouvera&lt;/li&gt;
&lt;li&gt;le &lt;strong&gt;nom&lt;/strong&gt; souhaité pour la &lt;strong&gt;commande&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Évidemment j&amp;rsquo;ai défini les questions à poser et ce que je faisais des réponses dans le résultat. C&amp;rsquo;est là tout l&amp;rsquo;intérêt de cookiecutter : &lt;strong&gt;vous définissez les questions à poser, les réponses possibles&lt;/strong&gt; s&amp;rsquo;il en est, quoi faire des réponses et &lt;strong&gt;où les utiliser dans vos templates&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Voyons donc cookiecutter.&lt;/p&gt;
&lt;h1 id=&#34;présentation-de-cookiecutter&#34;&gt;Présentation de cookiecutter&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://cookiecutter.readthedocs.io/en/stable/&#34;&gt;cookiecutter&lt;/a&gt; est &lt;strong&gt;un outil Python qui duplique un répertoire&lt;/strong&gt;, vous pose des questions et modifie le duplicat en remplaçant certaines chaînes de caractères par les réponses données aux questions.&lt;/p&gt;
&lt;p&gt;Il sait agir de manière conditionnelle : c&amp;rsquo;est-à-dire qu&amp;rsquo;il peut aussi &lt;strong&gt;ajouter/enlever des pans de code/texte en fonction de la valeur d&amp;rsquo;une variable&lt;/strong&gt;. Ceci grâce au &lt;a href=&#34;https://jinja.palletsprojects.com/&#34;&gt;moteur de template Jinja&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Autrement dit : vous définissez les fichiers dont vous avez besoin (parfois un copier/coller suffit), puis vous insérez dans vos fichiers des chaînes de caractères que vous souhaitez remplacer dans le projet. Vous pouvez également définir des valeurs conditionnelles. Par exemple : si je souhaite avoir une licence MIT, alors le fichier LICENSE contiendra un certain texte. Si je choisis la licence &lt;a href=&#34;https://fr.wikipedia.org/wiki/WTFPL&#34;&gt;LPRÀB/WTFPL&lt;/a&gt;, alors j&amp;rsquo;aurais un autre texte.&lt;/p&gt;
&lt;p&gt;Un exemple concret serait plus parlant, essayons avec &lt;a href=&#34;https://github.com/blankoworld/cookiecutter-trognon&#34;&gt;cookiecutter-trognon&lt;/a&gt; !&lt;/p&gt;
&lt;h1 id=&#34;comment-transformer-trognon-en-cookiecutter-trognon&#34;&gt;Comment transformer Trognon en cookiecutter-trognon ?&lt;/h1&gt;
&lt;h2 id=&#34;en-rapide&#34;&gt;En rapide&lt;/h2&gt;
&lt;p&gt;Pour rendre un projet compatible avec cookiecutter, il va falloir suivre quelques étapes clés :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Créer un &lt;strong&gt;nouveau répertoire&lt;/strong&gt; pour votre projet,&lt;/li&gt;
&lt;li&gt;Y créer un fichier nommé &lt;strong&gt;cookiecutter.json&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;Créer &lt;strong&gt;un répertoire nommé &lt;code&gt;{{ cookiecutter.project_slug }}&lt;/code&gt;&lt;/strong&gt; (oui oui, &lt;strong&gt;AVEC&lt;/strong&gt; les accolades),&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Déposer les fichiers nécessaires&lt;/strong&gt; au projet &lt;strong&gt;dans le répertoire &lt;code&gt;{{ cookiecutter.project_slug }}&lt;/code&gt;&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;Remplacer dans les fichiers tous les mots à adapter à chaque nouveau projet : pour cela utiliser les mots clés fournis dans le fichier &lt;em&gt;cookiecutter.json&lt;/em&gt; (&lt;strong&gt;variables&lt;/strong&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Dans le cas de Trognon, j&amp;rsquo;ai déposé les fichiers du projet dans le répertoire &lt;code&gt;{{ cookiecutter.project_slug }}&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;cookiecutterjson-la-configuration-du-projet&#34;&gt;cookiecutter.json, la configuration du projet&lt;/h2&gt;
&lt;p&gt;J&amp;rsquo;ai ensuite rempli le fichier &lt;code&gt;cookiecutter.json&lt;/code&gt; tel que montré ici :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;&amp;#34;project_name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;Mon projet&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;&amp;#34;__project_slug&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;{{ cookiecutter.project_name.lower().replace(&amp;#39; &amp;#39;, &amp;#39;_&amp;#39;).replace(&amp;#39;-&amp;#39;, &amp;#39;_&amp;#39;) }}&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;&amp;#34;command_shortname&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;CommandePrincipale&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;&amp;#34;__command_slug&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;{{ cookiecutter.command_shortname.lower().replace(&amp;#39; &amp;#39;, &amp;#39;_&amp;#39;).replace(&amp;#39;-&amp;#39;, &amp;#39;_&amp;#39;) }}&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;&amp;#34;__prompts__&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;&amp;#34;project_name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;Choisissez un nom de projet court&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;&amp;#34;command_shortname&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;Que voudriez-vous comme nom court de commande ?&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Je défini des variables&lt;/strong&gt; comme :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;project_name&lt;/strong&gt; : le nom du projet, avec comme valeur par défaut &lt;code&gt;Mon projet&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;command_shortname&lt;/strong&gt; : le nom de la commande Bash que nous utiliserons.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;D&amp;rsquo;autres variables ne demanderont rien à l&amp;rsquo;utilisateur car elles commencent par deux espaces soulignes &lt;code&gt;__&lt;/code&gt;. Je parle bien entendu de &lt;code&gt;__project_slug&lt;/code&gt;, &lt;code&gt;__command_slug&lt;/code&gt; et &lt;code&gt;__prompts__&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Cependant &lt;code&gt;__prompts__&lt;/code&gt; a une particularité : il permet de &lt;strong&gt;personnaliser la question posée&lt;/strong&gt; pour chaque variable.&lt;/p&gt;
&lt;p&gt;Ainsi pour définir &lt;code&gt;project_name&lt;/code&gt;, l&amp;rsquo;utilisateur verra la question suivante : &lt;code&gt;Choisissez un nom de projet court&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;remplacer-des-mots-par-des-variables&#34;&gt;Remplacer des mots par des variables&lt;/h2&gt;
&lt;p&gt;Maintenant que le fichier &lt;code&gt;cookiecutter.json&lt;/code&gt; possède des mots clés spécifiques (des variables), nous allons pouvoir modifier les fichiers de notre projet pour contenir des « mots-clés ». Par exemple voici le début du fichier &lt;em&gt;README.md&lt;/em&gt; de Trognon (&lt;strong&gt;AVANT&lt;/strong&gt; modifications) :&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# Trognon

Un lanceur de commandes personnalisées pour votre projet de développement.

Exemple : 

# Affiche l&amp;#39;aide
./agnes help

# Installe votre projet (vous devez définir ce que `install` fait)
./agnes install

# créé un dump de la base de données
./agnes dump
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ce qui donne le fichier README.md suivant dans notre projet cookiecutter-trognon (&lt;strong&gt;APRÈS&lt;/strong&gt; modifications) :&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# {{ cookiecutter.project_name }}

Un lanceur de commandes personnalisées pour votre projet de développement.

Exemple : 

# Affiche l&amp;#39;aide
./{{ cookiecutter.__command_slug }} help

# Installe votre projet (vous devez définir ce que `install` fait)
./{{ cookiecutter.__command_slug }} install

# créé un dump de la base de données
./{{ cookiecutter.__command_slug }} dump
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Nous avons ainsi remplacé respectivement le titre du fichier et les commandes d&amp;rsquo;exemple en &lt;code&gt;{{ cookiecutter.project_name }}&lt;/code&gt; et &lt;code&gt;{{ cookiecutter.__command_slug }}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Vous pouvez en savoir plus sur &lt;a href=&#34;https://cookiecutter.readthedocs.io/en/stable/index.html&#34;&gt;la documentation officielle de cookiecutter&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;J&amp;rsquo;espère qu&amp;rsquo;à travers cet article vous aurez compris l&amp;rsquo;&lt;strong&gt;avantage d&amp;rsquo;utiliser cookiecutter&lt;/strong&gt; et que vous &lt;strong&gt;envisagerez à l&amp;rsquo;avenir de l&amp;rsquo;intégrer dans votre processus d&amp;rsquo;automatisation&lt;/strong&gt; de la génération initiale de vos projets et de vos scripts.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;informatique énonce souvent d&amp;rsquo;éviter de réinventer la roue ; je pense que &lt;strong&gt;cookiecutter est l&amp;rsquo;outil indispensable&lt;/strong&gt; pour favoriser ce concept.&lt;/p&gt;
&lt;p&gt;Une fois ce processus de création automatisé, vous vous rendrez compte que vous générerez plus souvent des scripts/projets, que vous vous concentrerez uniquement sur le contenu du projet et pas sur tout l&amp;rsquo;environnement autour : c&amp;rsquo;est un gain de temps et de qualité ! Une &lt;strong&gt;belle valeur ajoutée&lt;/strong&gt; en somme.&lt;/p&gt;
</description>
    </item>
    
    <item>
	    <title>La Genèse d&#39;un projet</title>
      <link>https://olivier.dossmann.net/2023/09/la-gen%C3%A8se-dun-projet/</link>
      <pubDate>Wed, 13 Sep 2023 12:13:23 +0200</pubDate>
      
      <guid>https://olivier.dossmann.net/2023/09/la-gen%C3%A8se-dun-projet/</guid>
      <description>&lt;p&gt;Il y a quelques temps je lançais un billet sur &lt;a href=&#34;https://olivier.dossmann.net/2023/01/la-gachette-qui-publie-mon-blog/&#34;&gt;le projet Gachette&lt;/a&gt; qui permet de publier mon blog. Dans la même lancée &lt;strong&gt;je souhaite aujourd&amp;rsquo;hui vous présenter un autre projet&lt;/strong&gt; sur lequel je travaille de temps en temps : &lt;strong&gt;&lt;a href=&#34;https://github.com/blankoworld/genese&#34;&gt;Genèse&lt;/a&gt;&lt;/strong&gt;. Genèse est assez difficile à définir. Cependant je l&amp;rsquo;imagine comme une &lt;strong&gt;commande unique pour permettre à plusieurs développeurs de travailler sur un environnement commun&lt;/strong&gt; et en lançant &lt;strong&gt;une instance par&lt;/strong&gt; &lt;em&gt;ticket&lt;/em&gt;/problème relevé.&lt;/p&gt;
&lt;p&gt;Cet outil, bien qu&amp;rsquo;il soit &lt;strong&gt;utile et facile à utiliser&lt;/strong&gt;, demande un minimum d&amp;rsquo;explication pour comprendre à la fois le concept et l&amp;rsquo;utilité réelle.&lt;br /&gt;
C&amp;rsquo;est pourquoi je vais avant tout poser la problématique principale qui a initiée le projet, puis montrer quelques usages intéressants qui sont plus parlants et finalement tenter d&amp;rsquo;expliquer son fonctionnement en interne.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/lieux/genesis.jpg&#34; alt=&#34;Explosion d&amp;rsquo;artifice au dessus de l&amp;rsquo;eau&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Photo trouvée sur le &lt;a href=&#34;https://flickr.com/photos/23024164@N06/&#34;&gt;profil de Damian Gadal sur Flickr&lt;/a&gt;&lt;/em&gt; sous licence CC BY 2.0.&lt;/p&gt;
&lt;h1 id=&#34;ce-qui-a-initié-le-projet&#34;&gt;Ce qui a initié le projet&lt;/h1&gt;
&lt;p&gt;De &lt;a href=&#34;https://olivier.dossmann.net/cv/&#34;&gt;nombreuses années d&amp;rsquo;expérience professionnelle dans le domaine informatique&lt;/a&gt; m&amp;rsquo;ont amené à rencontrer plusieurs problèmes et à réfléchir sur énormément de sujets.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;un d&amp;rsquo;eux se porte sur l&amp;rsquo;environnement de travail : je parle de l&amp;rsquo;environnement système utilisé pour travailler sur un projet. J&amp;rsquo;ai relevé quelques éléments intéressants, similaires à des postulats :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;on essaie souvent de se rapprocher de l&amp;rsquo;environnement système de la production : ceci pour repérer assez tôt d&amp;rsquo;éventuels problèmes&lt;/li&gt;
&lt;li&gt;plus l&amp;rsquo;environnement entre collègues est similaire, mieux nous travaillons : si un collaborateur rencontre un problème il peut se tourner vers le reste de l&amp;rsquo;équipe pour avoir de l&amp;rsquo;aide&lt;/li&gt;
&lt;li&gt;nous en arrivons souvent à faire un fichier docker-compose.yml pour cela : peut-être est-ce initialement plus facile de partager un fichier léger (docker-compose.yml) qu&amp;rsquo;une machine virtuelle entière ?&lt;/li&gt;
&lt;li&gt;quand on nouveau collaborateur arrive dans l&amp;rsquo;équipe, il a pas mal de choses à apprendre sur le projet. Et il peine souvent - en plus de toutes les choses à apprendre - à devoir installer l&amp;rsquo;environnement initial&lt;/li&gt;
&lt;li&gt;on utilise souvent un fichier docker-compose.yml très proche entre plusieurs projets : ce qui est normal puisqu&amp;rsquo;on utilise très souvent des technologies similaires qu&amp;rsquo;on maîtrise pour les vendre à nos clients&lt;/li&gt;
&lt;li&gt;on travaille souvent sur plusieurs &lt;em&gt;tickets&lt;/em&gt;, c&amp;rsquo;est à dire plusieurs problèmes émis par le client. Chaque fois que nous démarrons un nouveau ticket, dans l&amp;rsquo;idéal, nous devrions avoir un environnement sain et propre pour ne pas avoir de fioritures de nos travaux précédents&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En discutant avec &lt;a href=&#34;https://www.richard-dern.fr/&#34;&gt;Richard Dern&lt;/a&gt; (qui a d&amp;rsquo;ailleurs &lt;a href=&#34;https://www.richard-dern.fr/blog/2023/09/03/nouveau-site-en-ligne/&#34;&gt;fait une refonte de son site web avec un nouveau moteur de blog&lt;/a&gt;), nous avons réfléchi à un outil capable de résoudre plusieurs de ces problématiques. Le fil rouge était :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;les environnements doivent &lt;strong&gt;rester isolés&lt;/strong&gt; : utilisation d&amp;rsquo;un fichier docker-compose.yml pour générer un environnement&lt;/li&gt;
&lt;li&gt;création d&amp;rsquo;un &lt;strong&gt;répertoire unique pour chaque nouveau ticket/projet/autre&lt;/strong&gt; afin de garder quelque chose de sain et propre&lt;/li&gt;
&lt;li&gt;éviter de devoir se répéter entre plusieurs projets : &lt;strong&gt;mettre en commun&lt;/strong&gt; les éléments qui le peuvent, comme par exemple le type de base de données&lt;/li&gt;
&lt;li&gt;permettre à &lt;strong&gt;plusieurs utilisateurs de travailler sur la même machine&lt;/strong&gt; : nommage des environnements d&amp;rsquo;une manière particulière (avec le nom de l&amp;rsquo;utilisateur par exemple)&lt;/li&gt;
&lt;li&gt;permettre à chaque développeur de &lt;strong&gt;personnaliser son environnement&lt;/strong&gt; : par exemple s&amp;rsquo;il souhaite avoir une interface web pour la base de données, qu&amp;rsquo;il puisse rajouter l&amp;rsquo;outil qu&amp;rsquo;il souhaite&lt;/li&gt;
&lt;li&gt;si nous travaillons sur 2 tickets d&amp;rsquo;un même projet, sachant que l&amp;rsquo;environnement est similaire pour un même projet, ces deux environnements doivent pouvoir exister en même temps : s&amp;rsquo;ils utilisent les mêmes ports d&amp;rsquo;adresses, cela va échouer. Il faut donc des &lt;strong&gt;ports aléatoires&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;si les ports sont aléatoires, alors il faut un accès facile à chacun des environnements, par exemple à l&amp;rsquo;aide d&amp;rsquo;une &lt;strong&gt;interface Web commune&lt;/strong&gt; à tous ces environnements&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C&amp;rsquo;est assez difficile à se l&amp;rsquo;imaginer sans des explications, une démonstration et/ou quelqu&amp;rsquo;un qui nous guide pour nous montrer le fonctionnement, alors je vais vous présenter un cas d&amp;rsquo;usage.&lt;/p&gt;
&lt;h1 id=&#34;usage-et-exemple-de-genèse&#34;&gt;Usage et exemple de Genèse&lt;/h1&gt;
&lt;p&gt;Imaginons un cas d&amp;rsquo;usage typique : un client détient une application web (faite avec un &lt;a href=&#34;https://fr.m.wikipedia.org/wiki/Framework&#34;&gt;framework&lt;/a&gt;) qui utilise une base de données MySQL. Appelons cette application : memory_game.&lt;/p&gt;
&lt;p&gt;Il est très probable que nous ayons d&amp;rsquo;autres clients qui utilisent MySQL. Et il est très probable que notre client fera des tickets de bugs que nous aurons à résoudre. Nous aurons probablement plusieurs collaborateurs (pour lesquels nous allons répartir les tickets).&lt;/p&gt;
&lt;p&gt;Il utilise un fichier docker-compose.yml avec le contenu suivant :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;version&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;services&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;php&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;toasterlint/php-apache-mysql&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;ports&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;8888:80&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;volumes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- ./:/var/www/html&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;db&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;mysql&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;command&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;--default-authentication-plugin=mysql_native_password&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;restart&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;always&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;environment&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;mot2passe&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;MYSQL_DATABASE&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;maBdd&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;volumes&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;- ./base_de_donnees:/docker-entrypoint-initdb.d&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On comprend donc qu&amp;rsquo;il y a :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;un service (nommé db) pour une base de données MySQL,&lt;/li&gt;
&lt;li&gt;un service (nommé php) pour l&amp;rsquo;application écrite en PHP sur le port 8888.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Avec Genèse&lt;/strong&gt;, générer un nouvel environnement de développement reviendrait à faire :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#60a0b0;font-style:italic&#34;&gt;# Génère un docker-compose.yml dans le dossier instances/memory_game à partir du profil nommé memory_game&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./genese -p memory_game
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;instances/memory_game est un répertoire de travail&lt;/strong&gt; :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;avec le dépôt de version du projet memory_game,&lt;/li&gt;
&lt;li&gt;un fichier docker-compose.yml prévu pour lancer un environnement complet,&lt;/li&gt;
&lt;li&gt;et un fichier &lt;strong&gt;.env&lt;/strong&gt; contenant des variables permettant au projet d&amp;rsquo;être autonome.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si l&amp;rsquo;exécutable &lt;em&gt;./genese&lt;/em&gt; venait à disparaître, le dossier reste fonctionnel pour travailler (avec Docker Compose évidemment).&lt;/p&gt;
&lt;p&gt;Si on travaille sur plusieurs problèmes en parallèle, on peut vouloir créer un dossier par problème. Imaginons le &lt;strong&gt;ticket 42&lt;/strong&gt; et le &lt;strong&gt;ticket 16&lt;/strong&gt; :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#60a0b0;font-style:italic&#34;&gt;# Génère une instance du projet dans le dossier instances/ticket42&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./genese -p memory_game -n ticket42
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#60a0b0;font-style:italic&#34;&gt;# Même chose avec le dossier instances/ticket16&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./genese -p memory_game -n ticket16
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Il faut récupérer une branche spéciale du service memory_game ?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#60a0b0;font-style:italic&#34;&gt;# Récupère dans le dépôt Git fourni dans le service memory_game la branche maBrancheSpeciale&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bb60d5&#34;&gt;BRANCHE_MEMORY_GAME&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;maBrancheSpeciale&amp;#34;&lt;/span&gt; ./genese -p memory_game -n essaiautrebranche
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Vous découvrirez dans un prochain article à quel usage je réserve cela &amp;#x1f609;&lt;/p&gt;
&lt;p&gt;Quelles sont les instances dont je dispose ?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#60a0b0;font-style:italic&#34;&gt;# Liste l&amp;#39;ensemble des instances&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./genese -i
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Et j&amp;rsquo;obtiens une liste des dossiers ayant été créés.&lt;/p&gt;
&lt;p&gt;Si je veux supprimer une instance spécifique :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#60a0b0;font-style:italic&#34;&gt;# Supprimer l&amp;#39;instance ticket16&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./genese -s ticket16
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Et si on veut avoir une visualisation des instances lancées, d&amp;rsquo;accéder à leur détail, éteindre un conteneur, le rallumer, regarder les fichiers de journalisation (logs) ou encore entrer dans un conteneur avec une invite de commande, on peut &lt;strong&gt;utiliser l&amp;rsquo;interface Web Portainer&lt;/strong&gt; fournie avec Genèse. Cela ressemble à quelque chose comme :&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/screenshots/portainer.png&#34; alt=&#34;Impression écran d&amp;rsquo;une liste d&amp;rsquo;instances lancées sur la machine locale&#34;&gt;&lt;/p&gt;
&lt;p&gt;Seriez-vous curieux de savoir comment cela fonctionne (sans entrer dans le technique évidemment !) ?&lt;/p&gt;
&lt;h1 id=&#34;comment-ça-marche-&#34;&gt;Comment ça marche ?&lt;/h1&gt;
&lt;p&gt;Nous allons voir que Genèse s&amp;rsquo;appuie sur quelques éléments clés comme :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;l&amp;rsquo;instance : version autonome et isolée, située dans le dossier &lt;strong&gt;instance&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;le service : la description nécessaire pour générer un service, par exemple MySQL,&lt;/li&gt;
&lt;li&gt;le profil : contient une liste de services permettant de démarrer une instance.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Prenons l&amp;rsquo;exemple précédent, nous aurons :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;deux services :
&lt;ul&gt;
&lt;li&gt;l&amp;rsquo;un nommé &lt;code&gt;mysql&lt;/code&gt; pour la base de données,&lt;/li&gt;
&lt;li&gt;l&amp;rsquo;autre nommé &lt;code&gt;memory_game&lt;/code&gt; pour notre application,&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;un profil nommé &lt;code&gt;memory_game&lt;/code&gt; qui liste les services &lt;code&gt;mysql&lt;/code&gt; et &lt;code&gt;memory_game&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Chaque fois que nous lancerons la commande &lt;code&gt;./genese&lt;/code&gt; avec le profil &lt;code&gt;memory_game&lt;/code&gt; nous aurons la possibilité de générer une instance avec un nom spécifique.&lt;/p&gt;
&lt;p&gt;Comment cela peut-il fonctionner ? Les services ont une structure permettant de décrire :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;la &lt;strong&gt;partie du fichier docker-compose.yml&lt;/strong&gt; qui va être utilisée,&lt;/li&gt;
&lt;li&gt;la possibilité de donner le &lt;strong&gt;dépôt Git utilisé&lt;/strong&gt; pour récupérer les sources du projet et la &lt;strong&gt;branche par défaut&lt;/strong&gt; à récupérer,&lt;/li&gt;
&lt;li&gt;la possibilité de donner un dossier &lt;code&gt;extras&lt;/code&gt; permettant de &lt;strong&gt;surcharger les sources du projet récupéré&lt;/strong&gt; (par exemple pour mettre des fichiers de configuration),&lt;/li&gt;
&lt;li&gt;la possibilité d&amp;rsquo;&lt;strong&gt;agir à des moments clés de la génération de l&amp;rsquo;instance via des déclencheurs&lt;/strong&gt; qui sont des scripts pour :
&lt;ul&gt;
&lt;li&gt;procéder à des changements &lt;strong&gt;AVANT&lt;/strong&gt; le &lt;strong&gt;lancement des conteneurs Docker&lt;/strong&gt;, par exemple modifier des fichiers de configuration,&lt;/li&gt;
&lt;li&gt;agir &lt;strong&gt;APRÈS le lancement des conteneurs&lt;/strong&gt;, par exemple pour lancer des commandes dans les conteneurs Docker lancés,&lt;/li&gt;
&lt;li&gt;afficher des informations &lt;strong&gt;à la fin du processus de création de l&amp;rsquo;instance&lt;/strong&gt;, par exemple pour afficher les ports utilisés par les différents conteneurs&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;À cela s&amp;rsquo;ajoute &lt;strong&gt;une interface Web&lt;/strong&gt; (&lt;a href=&#34;https://www.portainer.io/&#34; title=&#34;Interface Web de contrôle des instances Docker lancées&#34;&gt;Portainer&lt;/a&gt;) permettant de contrôler les instances lancées et accéder à des fonctionnalités particulières de Docker.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/blankoworld/genese#readme&#34;&gt;La documentation de Genèse&lt;/a&gt; devrait se charger bien mieux que moi pour les détails techniques et les possibilités de cet outil.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Malgré l&amp;rsquo;exemple d&amp;rsquo;utilisation et quelques détails sur son fonctionnement, Genèse mérite qu&amp;rsquo;on s&amp;rsquo;y attarde : nous n&amp;rsquo;avons gratté que la surface.&lt;/p&gt;
&lt;p&gt;Cela ressemble à un framework pour des profils de personnes de type &lt;a href=&#34;https://fr.wikipedia.org/wiki/Devops&#34;&gt;devops&lt;/a&gt; afin de leur fournir un outil unique ; à la fois déployer des instances pour les développeurs ; et des instances de type test pour les personnes fonctionnelles.&lt;/p&gt;
&lt;p&gt;Je ne sais pas comment suggérer de passer un peu de temps sur l&amp;rsquo;outil pour comprendre que c&amp;rsquo;est un bon investissement de temps. Surtout pour des personnes d&amp;rsquo;un profil DevOps et qui connaissent le scripting Bash. J&amp;rsquo;espère que la curiosité vous piquera au vif !&lt;/p&gt;
&lt;p&gt;Nous nous retrouverons très probablement pour en reparler dans un cadre différent encore.&lt;/p&gt;
</description>
    </item>
    
    <item>
	    <title>Déploiement d&#39;une application Crystal en production</title>
      <link>https://olivier.dossmann.net/2018/10/d%C3%A9ploiement-dune-application-crystal-en-production/</link>
      <pubDate>Sun, 07 Oct 2018 15:29:39 +0200</pubDate>
      
      <guid>https://olivier.dossmann.net/2018/10/d%C3%A9ploiement-dune-application-crystal-en-production/</guid>
      <description>&lt;h3 id=&#34;introduction&#34;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Le mois dernier &lt;a href=&#34;https://olivier.dossmann.net/2018/09/installation-de-pixelfed-une-alternative-%C3%A0-instagram/&#34; title=&#34;Lire mon article sur l&#39;installation de PixelFed&#34;&gt;je parlais de l&amp;rsquo;installation de PixelFed&lt;/a&gt;, un outil récent avec peu de documentation. Aujourd&amp;rsquo;hui je voudrais installer en production un site web développé avec Amber, un framework du langage Crystal pour développer rapidement des sites webs.&lt;/p&gt;
&lt;p&gt;Force est de constater que souvent &lt;a href=&#34;https://docs.amberframework.org/amber/deployment/manual-deploy&#34;&gt;les tutoriels proposés&lt;/a&gt; ne correspondent pas à mes attentes. J&amp;rsquo;ai décidé de vous livrer aujourd&amp;rsquo;hui le résultat de mes enquêtes sur le sujet !&lt;/p&gt;
&lt;p&gt;Après une présentation du framework Amber, je listerai rapidement les étapes à suivre pour déployer son application sur un serveur.&lt;/p&gt;
&lt;p&gt;Un &lt;a href=&#34;https://olivier.dossmann.net/wiki/services/deploiement_amber/&#34; title=&#34;En savoir plus sur le déploiement d&#39;une application Amber en mode production&#34;&gt;tutoriel plus détaillé pour Amber est disponible sur mon wiki&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/logos/amber.jpg&#34; alt=&#34;Logo d&amp;rsquo;Amber, similaire à un Crystal sur fond orange&#34; title=&#34;Logo d&#39;Amber framework&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;au-sujet-damber&#34;&gt;Au sujet d&amp;rsquo;Amber&lt;/h3&gt;
&lt;p&gt;C&amp;rsquo;est un framework web. C&amp;rsquo;est à dire un outil pour simplifier la création de sites Web. Il peut aussi bien faire des sites vitrines que des applications webs ou des API web. Il est donc multifonctions.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://amberframework.org/&#34; title=&#34;Aller sur la page officielle d&#39;Amber&#34;&gt;Amber&lt;/a&gt; est écrit en &lt;a href=&#34;https://crystal-lang.org/&#34; title=&#34;Découvrir la page officielle du langage Crystal&#34;&gt;Crystal&lt;/a&gt;, un langage dont la syntaxe est similaire à &lt;a href=&#34;https://fr.wikipedia.org/wiki/Ruby&#34; title=&#34;Découvrir Ruby sur Wikipédia&#34;&gt;Ruby&lt;/a&gt;, mais dont l&amp;rsquo;application résultante est plus rapide. Ça dépotte !&lt;/p&gt;
&lt;p&gt;Pourquoi je parle de Ruby aussi ? Parce qu&amp;rsquo;il possède un outil formidable très connu pour créer des sites webs : &lt;a href=&#34;https://rubyonrails.org/&#34; title=&#34;En savoir plus sur Ruby On Rails&#34;&gt;Ruby On Rails&lt;/a&gt;. Déjà très intéressant pour créer des sites webs, il était normal que les développeurs Crystal s&amp;rsquo;attardent à la création d&amp;rsquo;un outil similaire : Amber !&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai déjà utilisé Ruby On Rails, alors je me suis dis pourquoi pas tenter Amber ? Allons-y !&lt;/p&gt;
&lt;h3 id=&#34;déploiement-en-bref&#34;&gt;Déploiement, en bref&lt;/h3&gt;
&lt;p&gt;Je rappelle qu&amp;rsquo;un &lt;a href=&#34;https://olivier.dossmann.net/wiki/services/deploiement_amber/&#34; title=&#34;En savoir plus sur le déploiement d&#39;une application Amber en mode production&#34;&gt;tutoriel plus détaillé pour Amber est disponible sur mon wiki&lt;/a&gt;. Et le &lt;a href=&#34;https://docs.amberframework.org/amber/getting-started/quick-start&#34; title=&#34;Suivre le tutoriel de la documentation officielle d&#39;Amber pour installer et créer un nouveau projet&#34;&gt;&amp;ldquo;Quick Start&amp;rdquo; d&amp;rsquo;Amber explique très bien comment créer un projet&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Pour déployer Amber, il faut suivre quelques étapes clés :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;créer une base de données &lt;strong&gt;sur le serveur&lt;/strong&gt; et garder en tête l&amp;rsquo;identifiant, le mot de passe et la base de donnée associée&lt;/li&gt;
&lt;li&gt;configurer le mode production &lt;strong&gt;sur notre machine&lt;/strong&gt; et garder quelque part la clé située dans le fichier &lt;strong&gt;.encryption_key&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;compiler &lt;strong&gt;sur notre machine&lt;/strong&gt; l&amp;rsquo;application en mode &lt;strong&gt;--release&lt;/strong&gt;, mais &lt;strong&gt;aussi amber&lt;/strong&gt; lui même. Si votre machine et le serveur sont d&amp;rsquo;architectures différentes, pensez à &lt;a href=&#34;https://crystal-lang.org/docs/syntax_and_semantics/cross-compilation.html&#34; title=&#34;En savoir plus sur la compilation croisée de Crystal&#34;&gt;la compilation croisée d&amp;rsquo;application Crystal (en)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;copie de &lt;strong&gt;certains dossiers&lt;/strong&gt; de votre application &lt;strong&gt;vers le serveur&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;migration du schéma de la base de données &lt;strong&gt;sur le serveur&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;création d&amp;rsquo;un fichier systemd &lt;strong&gt;sur le serveur&lt;/strong&gt; pour le lancement/arrêt du service (votre site web)&lt;/li&gt;
&lt;li&gt;lancement de votre service &lt;strong&gt;sur le serveur&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;configuration et relance de Nginx en association avec votre site web &lt;strong&gt;sur le serveur&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Je vous donne ce qui est généralement important ci-dessous.&lt;/p&gt;
&lt;p&gt;La configuration de la connexion dans le fichier de production :&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;database_url: postgres://amber_user:mot2passe@localhost:5432/amber_production
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Savoir quels fichiers copier :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;bin/&lt;/li&gt;
&lt;li&gt;config/environments/.production.enc et QUE celui-là (les autres sont inutiles pour la production)&lt;/li&gt;
&lt;li&gt;db/&lt;/li&gt;
&lt;li&gt;public/&lt;/li&gt;
&lt;li&gt;src/locales/&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On oublie souvent de déployer la base (en mettant la clé située dans le fichier .encryption_key) :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bb60d5&#34;&gt;AMBER_ENV&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;production &lt;span style=&#34;color:#bb60d5&#34;&gt;AMBER_ENCRYPTION_KEY&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;oliBK0J9-HrSK1K8VPTtsMERyj2as1mUZqvPqfKGGeQ&amp;#34;&lt;/span&gt; ./bin/amber db migrate
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Avec un fichier systemd bien rempli, notamment les variables d&amp;rsquo;environnement :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;[Unit]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;Description&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;Lance le framework web Amber pour le site monsite.tld&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;After&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;network.target&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;[Service]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;Type&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;simple&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;User&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;http&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;WorkingDirectory&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;/srv/www/monsite&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;Environment&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;AMBER_ENV=production&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;Environment&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;PORT=3002&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;Environment&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;AMBER_ENCRYPTION_KEY=oliBK0J9-HrSK1K8VPTtsMERyj2as1mUZqvPqfKGGeQ&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;ExecStart&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;/home/www/monsite/bin/tutamber&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;Restart&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;always&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;[Install]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;WantedBy&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;multi-user.target&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Et finalement on se mange souvent sur une configuration Nginx pourrie, mais on commence simple :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-nginx&#34; data-lang=&#34;nginx&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;server&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;listen&lt;/span&gt;      &lt;span style=&#34;color:#4070a0&#34;&gt;*:80&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;listen&lt;/span&gt;      &lt;span style=&#34;color:#4070a0&#34;&gt;[::]:80&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;server_name&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;monsite.domaine.tld&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;root&lt;/span&gt;        &lt;span style=&#34;color:#4070a0&#34;&gt;/srv/www/monsite&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;index&lt;/span&gt;       &lt;span style=&#34;color:#4070a0&#34;&gt;index.html&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;proxy_set_header&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;X-Real-IP&lt;/span&gt;  &lt;span style=&#34;color:#bb60d5&#34;&gt;$remote_addr&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;location&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;/&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;proxy_set_header&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;Host&lt;/span&gt; &lt;span style=&#34;color:#bb60d5&#34;&gt;$host&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;proxy_pass&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;http://127.0.0.1:3002&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Et voilà !&lt;/p&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Le déploiement d&amp;rsquo;une application Amber n&amp;rsquo;est pas plus compliquée qu&amp;rsquo;un autre service. Mais il faut avouer qu&amp;rsquo;elle n&amp;rsquo;est pas si bien détaillée sur le site même d&amp;rsquo;Amber. Le projet est encore jeune, tout autant que le langage Crystal lui-même. Avec mon tutoriel vous savez quoi faire : installer des sites Amber partout &amp;#x1f602;.&lt;/p&gt;
&lt;p&gt;Cependant je vous conseille vivement de tester Crystal, Amber et d&amp;rsquo;autres éléments de la communauté : c&amp;rsquo;est facile à écrire, c&amp;rsquo;est réactif, bien pensé, avec une communauté active, des personnes gentilles qui répondent aux questions, c&amp;rsquo;est top !&lt;/p&gt;
</description>
    </item>
    
    <item>
	    <title>Développer pour Arduino en ligne de commande</title>
      <link>https://olivier.dossmann.net/2015/10/d%C3%A9velopper-pour-arduino-en-ligne-de-commande/</link>
      <pubDate>Sun, 18 Oct 2015 11:12:18 +0100</pubDate>
      
      <guid>https://olivier.dossmann.net/2015/10/d%C3%A9velopper-pour-arduino-en-ligne-de-commande/</guid>
      <description>&lt;h3 id=&#34;introduction&#34;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;L&amp;rsquo;Arduino est une carte électronique assez connue permettant grossomodo de transformer n&amp;rsquo;importe quel objet en objet intelligent puisque vous allez pouvoir programmer ce dernier afin d&amp;rsquo;avoir des comportements spécifiques suivant les données reçues par un certain nombre de capteurs.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://www.arduino.cc/new_home/assets/illu-arduino-UNO.png&#34; alt=&#34;Image d&amp;rsquo;une carte électronique Arduino&#34; title=&#34;Notre carte Arduino&#34;&gt;&lt;/p&gt;
&lt;p&gt;Arduino permet de réunir le monde de l&amp;rsquo;informatique à celui de l&amp;rsquo;électronique et favorise le DIY (Do It Yourself = fait le toi-même).&lt;/p&gt;
&lt;p&gt;Le &lt;a href=&#34;http://arduino.cc&#34; title=&#34;Se rendre sur le site officiel Arduino&#34;&gt;site officiel d&amp;rsquo;Arduino&lt;/a&gt; propose de nombreuses documentations et surtout un logiciel pour développer, compiler et envoyer sur l&amp;rsquo;Arduino votre programme. C&amp;rsquo;est une interface simple, claire, compatible Windows, MacOSX et GNU/Linux car développée en Java. Cependant, je préfère très - ou trop ? - souvent développer des programmes sous VIM en mode console et faire les compilations et l&amp;rsquo;envoi en ligne de commande. Et je ne suis pas le seul. Voilà pourquoi j&amp;rsquo;ai décidé de vous partager mon environnement de travail pour Arduino.&lt;/p&gt;
&lt;h3 id=&#34;sommaire&#34;&gt;Sommaire&lt;/h3&gt;
&lt;p&gt;Programmer pour Arduino se résume finalement comme beaucoup d&amp;rsquo;autres projets aux 3 actions suivantes :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;développer un programme sur son éditeur préféré&lt;/li&gt;
&lt;li&gt;compiler le programme (parfois sur le même éditeur)&lt;/li&gt;
&lt;li&gt;envoyer le résultat en production. Dans notre cas ce sera dans l&amp;rsquo;Arduino&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si la première étape est facile pour tout le monde, puisque chacun a probablement déjà son éditeur préféré, les 2 dernières étapes sont moins simples.&lt;/p&gt;
&lt;p&gt;Sous GNU/Linux, et plus particulièrement sous une distribution dérivée Debian, cela se résume quasiment à :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;installer les paquets &lt;strong&gt;arduino-core&lt;/strong&gt; et &lt;strong&gt;arduino-mk&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;initialiser des variables dans son &lt;strong&gt;.bashrc&lt;/strong&gt;, &lt;strong&gt;.zshrc&lt;/strong&gt; ou tout autre invite de commande&lt;/li&gt;
&lt;li&gt;savoir créer pour chacun de ses projets Arduino un fichier Makefile&lt;/li&gt;
&lt;li&gt;savoir quelle commande utiliser pour compiler et pour envoyer le résultat sur l&amp;rsquo;arduino&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Passons donc à la préparation de l&amp;rsquo;environnement&lt;/p&gt;
&lt;h3 id=&#34;installation-et-configuration&#34;&gt;Installation et configuration&lt;/h3&gt;
&lt;p&gt;Comme vous l&amp;rsquo;avez vu, nous commençons par l&amp;rsquo;installation des paquets &lt;strong&gt;arduino-core&lt;/strong&gt; et &lt;strong&gt;arduino-mk&lt;/strong&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt-get install arduino-core arduino-mk
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ceci devrait, entre autre, installer &lt;strong&gt;avrdude&lt;/strong&gt; qui nous facilitera l&amp;rsquo;envoi sur l&amp;rsquo;Arduino.&lt;/p&gt;
&lt;p&gt;Ensuite nous éditons le fichier de configuration de notre shell préféré, ici &lt;strong&gt;.bashrc&lt;/strong&gt; afin d&amp;rsquo;y initialiser les variables suivantes :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ARDUINO_DIR : le dossier dans lequel a été installé &lt;strong&gt;arduino-core&lt;/strong&gt; qui contient, entre autres les bibliothèques nécessaires à la programmation d&amp;rsquo;un Arduino&lt;/li&gt;
&lt;li&gt;ARDMK_DIR : le dossier dans lequel a été installé &lt;strong&gt;arduino-mk&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;AVR_TOOLS_DIR : le dossier dans lequel chercher l&amp;rsquo;outil &lt;strong&gt;avrdude&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Chez moi cela donne quelque chose comme :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export ARDUINO_DIR=&amp;quot;/usr/share/arduino&amp;quot;
export ARDMK_DIR=&amp;quot;/usr/share/arduino&amp;quot;
export AVR_TOOLS_DIR=&amp;quot;/usr&amp;quot;
export ISP_PORT=&amp;quot;/dev/ttyACM0&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;À noter que j&amp;rsquo;ai rajouté la variable &lt;strong&gt;ISP_PORT&lt;/strong&gt; pour définir d&amp;rsquo;emblée le port de communication avec mon Arduino. Ce n&amp;rsquo;est donc pas obligatoire dans votre cas (comme nous le verrons par la suite).&lt;/p&gt;
&lt;p&gt;Passons à l&amp;rsquo;utilisation de tout cela.&lt;/p&gt;
&lt;h3 id=&#34;utilisation&#34;&gt;Utilisation&lt;/h3&gt;
&lt;p&gt;Si nous devions résumer une utilisation simple de cet environnement, voici les étapes que nous ferions :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;créer un dossier pour notre projet&lt;/li&gt;
&lt;li&gt;créer un fichier avec l&amp;rsquo;extension &lt;strong&gt;.ino&lt;/strong&gt; et remplir ledit fichier avec un programme&lt;/li&gt;
&lt;li&gt;créer un fichier &lt;strong&gt;Makefile&lt;/strong&gt; dans le dossier du projet&lt;/li&gt;
&lt;li&gt;y ajouter quelques variables&lt;/li&gt;
&lt;li&gt;lancer la commande &lt;strong&gt;make&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;brancher l&amp;rsquo;Arduino et faire un &lt;strong&gt;make upload&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Et le tour est joué !&lt;/p&gt;
&lt;p&gt;Je pense que le point à éclaircir ici est celui du fichier &lt;strong&gt;Makefile&lt;/strong&gt; à remplir. Rien ne vaut un bon vieil exemple de mon fichier Makefile pour le projet Blink qui fait clignoter la LED 13 de mon Arduino MEGA 2560 :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BOARD_TAG = mega2560
ARDUINO_LIBS = 
ARDUINO_PORT = /dev/ttyACM0

include /usr/share/arduino/Arduino.mk
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rien de plus, rien de moins. Avec ça, un simple &lt;strong&gt;make &amp;amp;&amp;amp; make upload&lt;/strong&gt; devrait faire l&amp;rsquo;affaire &amp;#x1f603;&lt;/p&gt;
&lt;h3 id=&#34;les-commandes-disponibles&#34;&gt;Les commandes disponibles&lt;/h3&gt;
&lt;p&gt;Le fichier &lt;strong&gt;Makefile&lt;/strong&gt; inclut celui fournit par le paquet &lt;strong&gt;arduino-mk&lt;/strong&gt;. Et ce dernier est rempli de commandes en tous genre. Le mieux pour s&amp;rsquo;en rendre compte est de lancer la commande suivante dans votre projet :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make help
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Vous aurez tout un tas de commandes possibles. Par exemple je souhaitais connaître les valeurs possibles de la variable BOARD_TAG, ayant un modèle spécial d&amp;rsquo;Arduino. J&amp;rsquo;ai donc fait :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make show_boards
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ce qui m&amp;rsquo;a permis de savoir que le modèle &lt;em&gt;mega2560&lt;/em&gt; était disponible.&lt;/p&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Je trouve ce fichier Makefile parfait pour développer en toute sérénité sans avoir à installer l&amp;rsquo;environnement Java nécessaire au programme conseillé par Arduino et tout en gardant son outil de développement favori.&lt;/p&gt;
&lt;p&gt;Petit bonus pour ceux qui aiment s&amp;rsquo;amuser avec la sortie série d&amp;rsquo;un Arduino : si votre programme ajoute des &lt;strong&gt;Serial.print()&lt;/strong&gt;, vous pouvez voir la sortie de votre Arduino en utilisant le logiciel &lt;strong&gt;minicom&lt;/strong&gt; de la manière suivante :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;minicom -b 9600 -o -D /dev/ttyACM0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ça me rappelle mes débuts sous la carte Efika tiens !&lt;/p&gt;
</description>
    </item>
    
    <item>
	    <title>Installations multiples de Dokuwiki, script de mise à jour</title>
      <link>https://olivier.dossmann.net/2014/04/installations-multiples-de-dokuwiki-script-de-mise-%C3%A0-jour/</link>
      <pubDate>Mon, 14 Apr 2014 18:54:54 +0100</pubDate>
      
      <guid>https://olivier.dossmann.net/2014/04/installations-multiples-de-dokuwiki-script-de-mise-%C3%A0-jour/</guid>
      <description>&lt;h3 id=&#34;introduction&#34;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://dokuwiki.org/&#34; title=&#34;Se rendre sur le site officiel de Dokuwiki&#34;&gt;Dokuwiki&lt;/a&gt; est un outil formidable qui permet de créer un wiki simplement avec un serveur ayant PHP.&lt;/p&gt;
&lt;p&gt;Il est tellement formidable que je l&amp;rsquo;ai installé dans quasiment chacun de mes projets. Seulement voilà, sa qualité est telle qu&amp;rsquo;il est régulièrement mis à jour ; ce qui me demande beaucoup de temps à chaque nouvelle version pour mettre à jour mes multiples installations.&lt;/p&gt;
&lt;h3 id=&#34;recherche-dune-solution&#34;&gt;Recherche d&amp;rsquo;une solution&lt;/h3&gt;
&lt;p&gt;Je me suis dit récemment qu&amp;rsquo;il y avait forcément d&amp;rsquo;autres personnes qui avaient le même problème que moi. Et j&amp;rsquo;ai eu raison, d&amp;rsquo;autres personnes comme &lt;a href=&#34;http://blog.jthoenes.net/2010/01/24/a-ruby-script-for-upgrading-multiple-dokuwiki-installations/&#34; title=&#34;En savoir plus sur l&#39;article de Johannes Thönes au sujet de l&#39;installation de multiples Dokuwiki&#34;&gt;Johannes Thönes explique comment mettre à jour de multiples installations de Dokuwiki à l&amp;rsquo;aide d&amp;rsquo;un script&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;le-couac&#34;&gt;Le couac&lt;/h3&gt;
&lt;p&gt;Cependant, en voyant &lt;a href=&#34;https://gist.github.com/jthoenes/285219&#34; title=&#34;Étudier le code de Johannes Thönes sur Github&#34;&gt;le script de Johannes Thönes&lt;/a&gt;, je me suis vite rendu compte qu&amp;rsquo;il n&amp;rsquo;était plus fonctionnel sur les versions courantes de Dokuwiki.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai donc mis la main à la pâte et &lt;a href=&#34;https://gist.github.com/blankoworld/10530850/revisions&#34; title=&#34;Étudier les différences entre le script mis à jour par Olivier DOSSMANN et celui de Johannes Thönes sur Github&#34;&gt;je vous ai mis à jour le script de mise à jour de multiples installations de Dokuwiki&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Tout content de moi, je tente de lancer le script sur ma machine distante et BAM. Cela ne fonctionne pas à cause de dépendances avec le &lt;strong&gt;gem libarchive&lt;/strong&gt;. Impossible de l&amp;rsquo;installer/compiler sous GNU/Linux Debian. Alors que sous Ubuntu cela passait sans problème. &lt;strong&gt;Sgrumblblbl&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Ainsi je me suis lancé dans une tâche inutile, ardue, futile, mais tellement enrichissante : la création d&amp;rsquo;un &lt;strong&gt;script BASH&lt;/strong&gt; pour mettre à jour de multiples installations de Dokuwiki.&lt;/p&gt;
&lt;h3 id=&#34;mettre-à-jour-ses-dokuwiki-à-laide-dun-script-bash&#34;&gt;Mettre à jour ses Dokuwiki à l&amp;rsquo;aide d&amp;rsquo;un script Bash&lt;/h3&gt;
&lt;p&gt;Après tout, me suis-je dis, Dokuwiki donne les commandes pour GNU/Linux, 80% des serveurs sont sous GNU/Linux, et puis cela demande moins de dépendances branlantes d&amp;rsquo;avoir BASH que d&amp;rsquo;avoir un script Ruby, non ?&lt;/p&gt;
&lt;p&gt;Quoiqu&amp;rsquo;il en soit, &lt;a href=&#34;https://github.com/blankoworld/divers/blob/master/upgrade_dokuwiki.sh&#34; title=&#34;Découvrir le script d&#39;Olivier DOSSMANN pour mettre à jour de multiples installations de Dokuwiki&#34;&gt;j&amp;rsquo;ai écrit un script BASH pour mettre à jour de multiples installations de Dokuwiki&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Tout ce que je demande pour que cela fonctionne, c&amp;rsquo;est :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;d&amp;rsquo;avoir CURL installé sur votre machine&lt;/li&gt;
&lt;li&gt;d&amp;rsquo;avoir BASH (évidemment)&lt;/li&gt;
&lt;li&gt;de modifier le fichier pour renseigner vos installations de Dokuwiki&lt;/li&gt;
&lt;li&gt;lancer le script avec un utilisateur ayant les permissions totales sur les installations de Dokuwiki&lt;/li&gt;
&lt;li&gt;donner le lien, en argument au lancement du script, de la &lt;a href=&#34;http://download.dokuwiki.org&#34; title=&#34;Vérifier la dernière version de Dokuwiki&#34;&gt;dernière version de Dokuwiki&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ce que fait le script :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vérifie l&amp;rsquo;existence des répertoires d&amp;rsquo;installation&lt;/li&gt;
&lt;li&gt;Vérifie la présence de CURL&lt;/li&gt;
&lt;li&gt;Crée un répertoire temporaire et en donne l&amp;rsquo;adresse absolue&lt;/li&gt;
&lt;li&gt;Télécharge la dernière version de Dokuwiki et l&amp;rsquo;extraie dans le dossier temporaire&lt;/li&gt;
&lt;li&gt;Télécharge un fichier contenant la liste des fichiers obsolètes dans Dokuwiki&lt;/li&gt;
&lt;li&gt;Pour chacun de vos Dokuwiki :
&lt;ul&gt;
&lt;li&gt;Création d&amp;rsquo;un répertoire de sauvegarde dans le répertoire temporaire crée précédemment&lt;/li&gt;
&lt;li&gt;Copie de sauvegarde de vos fichiers dans le répertoire temporaire&lt;/li&gt;
&lt;li&gt;Copie des nouveaux fichiers Dokuwiki dans votre répertoire d&amp;rsquo;installation de Dokuwiki&lt;/li&gt;
&lt;li&gt;Suppression des fichiers de Dokuwiki obsolètes&lt;/li&gt;
&lt;li&gt;Mise à jour du message apparaissant à l&amp;rsquo;écran sur l&amp;rsquo;interface de Dokuwiki&lt;/li&gt;
&lt;li&gt;Changement des permissions de votre installation de Dokuwiki avec l&amp;rsquo;utilisateur www-data et le groupe www-data (peut être changé dans le script)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Première utilisation, première joie, première pause pendant que ça met à jour alors que nous sommes dans le fauteuil, peinard.&lt;/p&gt;
&lt;p&gt;Je conseille évidemment ce script à tout le monde et suis curieux de savoir s&amp;rsquo;il servira à plus d&amp;rsquo;un !&lt;/p&gt;
&lt;h3 id=&#34;liens-utiles&#34;&gt;Liens utiles&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://dokuwiki.org/&#34; title=&#34;Se rendre sur le site officiel de Dokuwiki&#34;&gt;Dokuwiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://download.dokuwiki.org&#34; title=&#34;Vérifier la dernière version de Dokuwiki&#34;&gt;Dernière version de Dokuwiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://blog.jthoenes.net/2010/01/24/a-ruby-script-for-upgrading-multiple-dokuwiki-installations/&#34; title=&#34;En savoir plus sur l&#39;article de Johannes Thönes au sujet de l&#39;installation de multiples Dokuwiki&#34;&gt;Johannes Thönes explique comment mettre à jour de multiples installations de Dokuwiki à l&amp;rsquo;aide d&amp;rsquo;un script&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gist.github.com/jthoenes/285219&#34; title=&#34;Étudier le code de Johannes Thönes sur Github&#34;&gt;Script de Johannes Thönes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gist.github.com/blankoworld/10530850/revisions&#34; title=&#34;Étudier les différences entre le script mis à jour par Olivier DOSSMANN et celui de Johannes Thönes sur Github&#34;&gt;Mise à jour du script de Johannes Thönes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/blankoworld/divers/blob/master/upgrade_dokuwiki.sh&#34; title=&#34;Découvrir le script d&#39;Olivier DOSSMANN pour mettre à jour de multiples installations de Dokuwiki&#34;&gt;Script BASH pour mettre à jour de multiples installations de Dokuwiki&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
	    <title>Voici Docker, plus léger et plus simple qu&#39;une machine virtuelle</title>
      <link>https://olivier.dossmann.net/2014/04/voici-docker-plus-l%C3%A9ger-et-plus-simple-quune-machine-virtuelle/</link>
      <pubDate>Thu, 03 Apr 2014 13:20:30 +0100</pubDate>
      
      <guid>https://olivier.dossmann.net/2014/04/voici-docker-plus-l%C3%A9ger-et-plus-simple-quune-machine-virtuelle/</guid>
      <description>&lt;h3 id=&#34;introduction&#34;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://olivier.dossmann.net/2014/03/serveur-de-machines-virtuelles-avec-virtualbox/&#34; title=&#34;Lire l&#39;article Serveur de machines virtuelles avec VirtualBox&#34;&gt;Nous parlions précédemment de VirtualBox pour créer des machines virtuelles&lt;/a&gt; sur sa machine. C&amp;rsquo;est une solution pratique qui permet de tester un environnement sans avoir à installer quoique ce soit de plus que VirtualBox sur sa machine et sans perdre de données. Un environnement fermé.&lt;/p&gt;
&lt;p&gt;Mais quand il s&amp;rsquo;agit de lancer plusieurs services sur une machine (un serveur web, un serveur de base de données, une application web, etc.) cela devient tout de suite lourd et consommateur de mémoire vive + espace disque.&lt;/p&gt;
&lt;p&gt;Des solutions alternatives existent, comme l&amp;rsquo;utilisation de LXC qui sont des conteneurs qui utilisent communément le noyau Linux mais fonctionnent à peu de choses prêts comme ce que nous appelons des &lt;strong&gt;chroots&lt;/strong&gt;. Cependant cette solution n&amp;rsquo;est pas si simple car il faut gérer les conteneurs, leur lancement, etc.&lt;/p&gt;
&lt;p&gt;Une solution plus simple, se basant sur les LXC existe : &lt;a href=&#34;http://docker.io&#34; title=&#34;Visiter la page officielle de Docker.&#34;&gt;Docker&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/logos/docker.png&#34; alt=&#34;Logo de Docker&#34; title=&#34;Logo du projet Docker&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;présentation-de-docker&#34;&gt;Présentation de Docker&lt;/h3&gt;
&lt;p&gt;Pour &lt;a href=&#34;https://www.docker.io/learn_more/&#34; title=&#34;Leanr more about Docker&#34;&gt;en savoir plus sur Docker&lt;/a&gt;, il faut se rendre sur la &lt;a href=&#34;https://www.docker.io/learn_more/&#34; title=&#34;Learn more about Docker&#34;&gt;page prévue à cet effet sur le site officiel&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Mais pour vous résumer un peu ce que j&amp;rsquo;en ai compris :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Docker permet de créer des applications dans un conteneur&lt;/li&gt;
&lt;li&gt;Un conteneur est plus léger en terme de taille et en terme de consommation mémoire qu&amp;rsquo;une machine virtuelle entière&lt;/li&gt;
&lt;li&gt;Les conteneurs peuvent être construits à partir d&amp;rsquo;un simple fichier nommé le Dockerfile&lt;/li&gt;
&lt;li&gt;Les conteneurs peuvent être partagés via un dépôt public (&lt;a href=&#34;http://index.docker.io&#34; title=&#34;Trouver un docker particulier&#34;&gt;Index Docker&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;La création d&amp;rsquo;un conteneur peut se faire via l&amp;rsquo;utilisation de &lt;strong&gt;commit&lt;/strong&gt;, ce qui permet de versionner les conteneurs&lt;/li&gt;
&lt;li&gt;La création d&amp;rsquo;un conteneur peut se faire via l&amp;rsquo;héritage d&amp;rsquo;un autre conteneur&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ainsi :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;faire tourner plusieurs conteneurs est plus léger que créer plusieurs machines virtuelles&lt;/li&gt;
&lt;li&gt;le versionnement de ses conteneurs permet de redémarrer depuis un précédent commit, de rejouer certaines choses ou améliorer des conteneurs précédents&lt;/li&gt;
&lt;li&gt;le Dockerfile est un simple fichier, ce qui permet de partager/déplacer une application contenue dans un conteneur de manière très rapide&lt;/li&gt;
&lt;li&gt;plus de soucis avec les collègues au sujet d&amp;rsquo;un environnement différent d&amp;rsquo;un développeur à l&amp;rsquo;autre : tout le monde utilise la même version du conteneur&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Vous l&amp;rsquo;aurez compris, cela n&amp;rsquo;a que des avantages - quasiment.&lt;/p&gt;
&lt;h3 id=&#34;installation-et-utilisation&#34;&gt;Installation et utilisation&lt;/h3&gt;
&lt;p&gt;Le site de Docker nous apprend &lt;a href=&#34;https://www.docker.io/gettingstarted/&#34; title=&#34;Getting started on Docker&#34;&gt;comment installer et utiliser Docker en quelques points&lt;/a&gt;, mais aussi &lt;a href=&#34;https://olivier.dossmann.net/wiki/virtualisation/docker/&#34; title=&#34;Apprendre à installer et utiliser Docker sur Debian AMD64&#34;&gt;la page Docker de mon Recueil d&amp;rsquo;astuces&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ce que je pense qu&amp;rsquo;il faut au minimum retenir ce sont les commandes suivantes :&lt;/p&gt;
&lt;pre name=&#34;code&#34; class=&#34;bash&#34;&gt;
# Créer un nouveau conteneur basé sur Ubuntu
docker run -i -t ubuntu /bin/bash
# Voir les conteneurs lancés
docker ps
# Voir tout les conteneurs crées
docker ps -a
# Voir les images disponibles sur notre machine (à partir desquelles créer de nouveaux conteneurs)
docker images
# Supprimer un conteneur (ID est l&#39;identifiant donné par la commande docker ps -a)
docker rm ID
# Donner un nom à son conteneur (--name). Utile à la place d&#39;utiliser un ID
docker run -i -t --name SuperNom ubuntu /bin/bash
&lt;/pre&gt;
&lt;p&gt;Et évidemment, le plus intéressant est de regarder &lt;a href=&#34;http://index.docker.io&#34; title=&#34;Découvrir de nouveaux fichiers Docker&#34;&gt;l&amp;rsquo;index des fichiers Docker disponibles&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;quelques-regrets&#34;&gt;Quelques regrets&lt;/h3&gt;
&lt;p&gt;En faisant quelques conteneurs Docker, on peut regretter :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;le fait qu&amp;rsquo;il faille utiliser supervisord de manière systématique pour lancer plusieurs services dans un conteneurs.&lt;/li&gt;
&lt;li&gt;l&amp;rsquo;utilisation d&amp;rsquo;espace partagés ne nous prévient pas qu&amp;rsquo;on risque d&amp;rsquo;écraser nos propres données sur la machine hôte&lt;/li&gt;
&lt;li&gt;ne fonctionne que sur architecture am64&lt;/li&gt;
&lt;li&gt;ne fonctionne que pour Linux (puisque basé sur LXC), donc sous windows il faut utiliser une machine virtuelle avec Ubuntu&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si on se soustrait de ses inconvénients, cela reste un outil intéressant !&lt;/p&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Docker est un outil intéressant comparé à la gestion, la création et l&amp;rsquo;utilisation de conteneurs LXC, c&amp;rsquo;est une surcouche très attrayante.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;apprécie qu&amp;rsquo;on puisse générer un environnement commun à l&amp;rsquo;ensemble d&amp;rsquo;une équipe de développeurs afin qu&amp;rsquo;ils aient toujours les mêmes bibliothèques et outils. En revanche, pour de la production je ne trouve pas cela encore assez au point car réussir à lancer plusieurs services sur un conteneur est vite décourageant et demande pas mal de connaissances !&lt;/p&gt;
&lt;p&gt;Mon utilisation de Docker resterait donc du côté développement, afin d&amp;rsquo;utiliser un fichier simple qui génère un environnement complet de développement et de déploiement local d&amp;rsquo;un ou plusieurs services. Par exemple pour avoir un serveur OpenERP ou bien un serveur postgreSQL.&lt;/p&gt;
&lt;p&gt;Je pense que ça peut-être déployé sur un serveur distant (machine virtuelle ou non) avec plusieurs conteneurs, un par service afin de permettre de déployé/déplacer un service rapidement, sans effort et sans pertes.&lt;/p&gt;
&lt;p&gt;Je verrais cela à l&amp;rsquo;utilisation, et je vous invite à en faire autant !&lt;/p&gt;
&lt;h3 id=&#34;liens-utiles&#34;&gt;Liens utiles&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.docker.io/learn_more/&#34; title=&#34;Learn more about Docker&#34;&gt;En savoir plus sur Docker (en)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://index.docker.io/&#34; title=&#34;Se rendre sur le site officiel des images Docker&#34;&gt;Index des images Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://olivier.dossmann.net/wiki/virtualisation/docker/&#34; title=&#34;En savoir plus sur Docker&#34;&gt;Docker sur mon Recueil d&amp;rsquo;astuces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://linuxfr.org/news/logiciels-pour-survivre-avec-docker&#34; title=&#34;Découvrir des logiciels permettant de gérer ses conteneurs Docker selon LinuxFR&#34;&gt;Pistes pour gérer ses conteneurs Docker selon LinuxFR&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
	    <title>Traduction de ses scripts Lua avec gettext</title>
      <link>https://olivier.dossmann.net/2013/09/traduction-de-ses-scripts-lua-avec-gettext/</link>
      <pubDate>Mon, 02 Sep 2013 18:32:01 +0100</pubDate>
      
      <guid>https://olivier.dossmann.net/2013/09/traduction-de-ses-scripts-lua-avec-gettext/</guid>
      <description>&lt;h3 id=&#34;introduction&#34;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;En ce moment j&amp;rsquo;avance sur un projet informatique écrit dans le language Lua. Je m&amp;rsquo;essaie ainsi à ce langage et en profite de sa puissance pour mes scripts de création de sites web comme &lt;a href=&#34;https://github.com/blankoworld/porteail&#34;&gt;PorteAil&lt;/a&gt; ou encore &lt;a href=&#34;https://github.com/blankoworld/makefly&#34;&gt;Makefly&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ainsi, pour l&amp;rsquo;un ou l&amp;rsquo;autre raison j&amp;rsquo;ai besoin de traduire les messages d&amp;rsquo;erreurs de l&amp;rsquo;application en la langue de l&amp;rsquo;utilisateur. Il y a probablement plusieurs méthodes, mais voici celle que j&amp;rsquo;utilise.&lt;/p&gt;
&lt;p&gt;Notez que je donne le détail complet du code dans &lt;a href=&#34;https://olivier.dossmann.net/wiki/developpement/lua_gettext/&#34;&gt;mon tutoriel sur Gettext pour Lua&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/nature/la_terre.jpg&#34; alt=&#34;La Terre&#34; title=&#34;Image de la Terre vue de l&#39;espace&#34;&gt;&lt;/p&gt;
&lt;p&gt;Image sous Licence Creative Commons CC-BY 2.0 trouvée sur une galerie photo de &lt;a href=&#34;http://www.flickr.com/photos/gsfc/&#34; title=&#34;Aller sur la galerie photo de gsfc&#34;&gt;gsfc&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;gettext&#34;&gt;Gettext&lt;/h3&gt;
&lt;p&gt;L&amp;rsquo;outil le plus utilisé selon Internet est &lt;a href=&#34;http://en.wikipedia.org/wiki/Gettext&#34;&gt;Gettext&lt;/a&gt;. Il permet de parcourir notre code afin d&amp;rsquo;en extraire les chaînes à traduire. Puis divers outils permettent de procéder à la traduction des chaînes, soit automatiquement, soit manuellement.&lt;/p&gt;
&lt;p&gt;Enfin l&amp;rsquo;outil va générer des fichiers binaires pour une rapidité accrue de traitement/lecture/rendu.&lt;/p&gt;
&lt;h3 id=&#34;implémentation&#34;&gt;Implémentation&lt;/h3&gt;
&lt;p&gt;Il n&amp;rsquo;y a pas d&amp;rsquo;implémentation à part entière pour Lua, il faut donc créer sa propre implémentation.&lt;/p&gt;
&lt;p&gt;En premier lieu on doit créer une fonction qui va lire nos chaînes et donner la traduction (en lisant le fichier binaire spécifique à la langue de l&amp;rsquo;utilisateur. Généralement c&amp;rsquo;est une fonction &lt;strong&gt;_&lt;/strong&gt; (espace souligné) qu&amp;rsquo;on utilise. Elle va lire le fameux fichier binaire (extension *.mo) de Gettext et donner le résultat.&lt;/p&gt;
&lt;p&gt;Sachant que nous voulons retourner les erreurs du programme/script en plusieurs langues, il va falloire initialiser la fonction avant le début de nos traitements.&lt;/p&gt;
&lt;p&gt;Vous pouvez voir tout ceci dans &lt;a href=&#34;https://olivier.dossmann.net/wiki/developpement/lua_gettext/&#34;&gt;le tutoriel sur Gettext pour Lua que je vous ai concocté&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;résumé&#34;&gt;Résumé&lt;/h3&gt;
&lt;p&gt;Si on devait synthétiser, voici ce qu&amp;rsquo;il faut faire :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;faire une fonction &lt;strong&gt;_&lt;/strong&gt; qui lit une chaîne et donne sa traduction&lt;/li&gt;
&lt;li&gt;faire une fonction qui lit un fichier *.mo et cherche une chaîne donnée pour en sortir son résultat&lt;/li&gt;
&lt;li&gt;initialiser le chargement du fichier *.mo et la fonction de traduction en début de script&lt;/li&gt;
&lt;li&gt;ajouter les chaînes à traduire dans des fonctions &lt;strong&gt;_()&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;parcourir notre code avec gettext pour récupérer les chaînes à traduire&lt;/li&gt;
&lt;li&gt;traduire&lt;/li&gt;
&lt;li&gt;convertir en fichier binaire&lt;/li&gt;
&lt;li&gt;joindre le binaire à notre programme et enlever les fichiers temporaire (*.po, *.pot, etc.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;En dehors de la lecture du fichier binaire de gettext qui se résoud facilement en cherchant sur Internet, l&amp;rsquo;implémentation fût facile et le résultat est au-delà de mes espérances.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;avantage d&amp;rsquo;avoir des fichiers à traduire au format *&lt;strong&gt;.po&lt;/strong&gt;, c&amp;rsquo;est que des interfaces graphiques simples telles que gTranslator ou poedit permettent à des non-initiés au code de programmation de traduire votre application sans avoir à lire du code.&lt;/p&gt;
&lt;p&gt;Des interfaces web permettent également de traduire en ligne sans installer quoique ce soit. C&amp;rsquo;est donc très utile pour des projets !&lt;/p&gt;
&lt;h3 id=&#34;liens-utiles&#34;&gt;Liens utiles&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://www.lua.org/&#34;&gt;Lua (site officiel)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://en.wikipedia.org/wiki/Gettext&#34;&gt;Gettext selon Wikipédia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://olivier.dossmann.net/wiki/developpement/lua_gettext/&#34;&gt;Tutoriel Gettext pour Lua sur le Recueil d&amp;rsquo;astuces d&amp;rsquo;Olivier&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
  </channel>
</rss>
