<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Logiciels sur Olivier DOSSMANN</title>
    <link>https://olivier.dossmann.net/tags/logiciels/</link>
    <description>Contenu récent dans Logiciels sur Olivier DOSSMANN</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>fr</language>
    <copyright>© 2005-2026 Olivier DOSSMANN</copyright>
    <lastBuildDate>Tue, 07 Apr 2026 17:19:03 +0200</lastBuildDate><atom:link href="https://olivier.dossmann.net/tags/logiciels/index.xml" rel="self" type="application/rss+xml" />
    <item>
	    <title>Premiers pas avec Hugo, moteur de blog statique</title>
      <link>https://olivier.dossmann.net/2026/04/premiers-pas-avec-hugo-moteur-de-blog-statique/</link>
      <pubDate>Tue, 07 Apr 2026 17:19:03 +0200</pubDate>
      
      <guid>https://olivier.dossmann.net/2026/04/premiers-pas-avec-hugo-moteur-de-blog-statique/</guid>
      <description>&lt;h1 id=&#34;introduction&#34;&gt;Introduction&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt; est un &lt;strong&gt;moteur de blog statique&lt;/strong&gt; célèbre pour sa rapidité et sa souplesse d&amp;rsquo;utilisation. Il permet de &lt;strong&gt;générer&lt;/strong&gt; un site web contenant &lt;strong&gt;des milliers d&amp;rsquo;articles en quelques secondes&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Qu&amp;rsquo;entends-tu par &lt;strong&gt;générer&lt;/strong&gt; un site web ?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Dire que c&amp;rsquo;est un moteur de site statique signifie que l&amp;rsquo;outil va prendre &lt;strong&gt;un répertoire&lt;/strong&gt; d&amp;rsquo;origine &lt;strong&gt;comme base pour compulser les données&lt;/strong&gt; et générer des pages webs comme par exemple &lt;strong&gt;des pages HTML, CSS, XML&lt;/strong&gt; ou encore du JS (mais d&amp;rsquo;autres formats sont possibles).&lt;/p&gt;
&lt;p&gt;Quel(s) avantage(s) à ce qu&amp;rsquo;il soit statique ? Une fois vos fichiers générés dans un dossier cible (par exemple un dossier nommé « public »), vous pouvez le déposer &lt;strong&gt;chez n&amp;rsquo;importe quel hébergeur web&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Imaginez votre blog, votre site vitrine ou un site professionnel : &lt;strong&gt;aucune dépendance&lt;/strong&gt;, &lt;strong&gt;pas de faille de sécurité&lt;/strong&gt; liée au langage ou au framework choisi pour publier le site, &lt;strong&gt;pas de surcoût&lt;/strong&gt; de serveur pour des environnements particuliers, &lt;strong&gt;pas de lenteurs&lt;/strong&gt; sur votre site pour calculer tous les éléments avant de les servir &lt;strong&gt;à chaque visiteur&lt;/strong&gt;, etc.&lt;/p&gt;
&lt;p&gt;En somme fournir un site web statique est &lt;strong&gt;très pratique, économique et facile&lt;/strong&gt;. D&amp;rsquo;autant qu&amp;rsquo;il existe des hébergeurs gratuits pour fournir vos fichiers HTML, CSS, XML, JS. Pourquoi ne pas en profiter ?&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://olivier.dossmann.net/2016/03/hugo_le_moteur_de_blog_statique_rapide_et_moderne/&#34;&gt;En 2016, j&amp;rsquo;ai fait le choix de migrer mon blog sur Hugo&lt;/a&gt;, j&amp;rsquo;ai donc un peu de bouteille dans son utilisation. J&amp;rsquo;ai d&amp;rsquo;ailleurs proposé un &lt;a href=&#34;https://github.com/blankoworld/hugo_theme_adam_eve/&#34;&gt;thème nommé Adam &amp;amp; Eve pour Hugo&lt;/a&gt; que j&amp;rsquo;utilise pour l&amp;rsquo;&lt;a href=&#34;https://olivier.dossmann.net/wiki&#34;&gt;espace Recueil de ce blog&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Aujourd&amp;rsquo;hui nous allons faire nos premiers pas dans la création d&amp;rsquo;un blog statique à l&amp;rsquo;aide d&amp;rsquo;Hugo. Nous parlerons de l&amp;rsquo;installation de l&amp;rsquo;outil, puis de la création du squelette principal, le choix d&amp;rsquo;un thème, la configuration du blog et la rédaction d&amp;rsquo;un article avant de générer notre premier blog Hugo &amp;#x1f60e;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/objets/voiture_gros_moteur.jpg&#34; alt=&#34;Une voiture bleue avec un énorme moteur qui dépasse de l&amp;rsquo;avant de la voiture en hauteur&#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/50826080@N00/&#34;&gt;profil de Stephen Bowler sur Flickr&lt;/a&gt;&lt;/em&gt; sous licence CC BY 2.0.&lt;/p&gt;
&lt;h1 id=&#34;installation&#34;&gt;Installation&lt;/h1&gt;
&lt;p&gt;Étant donné qu&amp;rsquo;&lt;strong&gt;&lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt;&lt;/strong&gt; est un &lt;strong&gt;outil qui s&amp;rsquo;utilise en ligne de commande&lt;/strong&gt;, il faut installer le binaire sur notre machine. En fonction de votre système d&amp;rsquo;exploitation la méthode diffère.&lt;/p&gt;
&lt;p&gt;La &lt;a href=&#34;https://gohugo.io/installation/&#34;&gt;&lt;strong&gt;documentation officielle&lt;/strong&gt; sur l&amp;rsquo;installation d&amp;rsquo;Hugo&lt;/a&gt; est bien faite. Je vous invite à &lt;strong&gt;la consulter promptement&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Si vous avez une distribution GNU/Linux, il existe sûrement un &lt;a href=&#34;https://gohugo.io/installation/linux/#repository-packages&#34;&gt;paquet spécifique d&amp;rsquo;Hugo pour votre distribution&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Par exemple &lt;strong&gt;sous ArchLinux&lt;/strong&gt; il me suffit de 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;sudo pacman -S hugo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Et le tour est joué !&lt;/p&gt;
&lt;p&gt;Une fois installée, vous pouvez taper la commande suivante dans une console pour vérifier que tout soit en ordre :&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;hugo version
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Cela &lt;strong&gt;affiche la version d&amp;rsquo;Hugo&lt;/strong&gt; que vous venez d&amp;rsquo;installer.&lt;/p&gt;
&lt;p&gt;Plusieurs méthodes permettent d&amp;rsquo;&lt;strong&gt;avoir des infos sur la commande &lt;code&gt;hugo&lt;/code&gt;&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;man hugo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hugo &lt;span style=&#34;color:#007020&#34;&gt;help&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ou tout simplement se rendre sur la &lt;a href=&#34;https://gohugo.io/documentation/&#34;&gt;&lt;strong&gt;documentation officielle d&amp;rsquo;Hugo&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;créer-un-nouveau-site&#34;&gt;Créer un nouveau site&lt;/h1&gt;
&lt;p&gt;Pour &lt;strong&gt;générer un nouveau site&lt;/strong&gt; nommé &lt;em&gt;superblog&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hugo new site superblog
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Hugo lui-même vous informe des étapes à suivre pour terminer votre projet de site, parmi :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;se rendre dans le nouveau répertoire,&lt;/li&gt;
&lt;li&gt;choisir et &lt;strong&gt;ajouter un thème&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;configurer le site&lt;/strong&gt; à l&amp;rsquo;aide du fichier &lt;strong&gt;hugo.toml&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;créer &lt;strong&gt;du contenu&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;vérifier le résultat avec un &lt;strong&gt;serveur local dédié&lt;/strong&gt; (rien que ça !).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Agissons de suite : rendez-vous dans le répertoire &lt;strong&gt;superblog&lt;/strong&gt; et passons au chapitre 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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#007020&#34;&gt;cd&lt;/span&gt; superblog
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;choisir-un-thème&#34;&gt;Choisir un thème&lt;/h1&gt;
&lt;p&gt;L&amp;rsquo;avantage d&amp;rsquo;avoir un outil très connu c&amp;rsquo;est de &lt;strong&gt;bénéficier d&amp;rsquo;innombrables thèmes proposés par la communauté&lt;/strong&gt;. Vous les retrouverez sur un &lt;a href=&#34;https://themes.gohugo.io/&#34;&gt;site officiel dédié aux thèmes prévus pour Hugo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Étant donné que le &lt;strong&gt;travail est fourni par la communauté&lt;/strong&gt;, leur qualité ou la couverture de fonctionnalités intégrées est dépendante du temps passé sur ces thèmes et le temps accordé à leur maintenance. Autrement dit : &lt;strong&gt;il y a à boire et à manger&lt;/strong&gt; là dedans !&lt;/p&gt;
&lt;p&gt;Parcourez l&amp;rsquo;&lt;a href=&#34;https://themes.gohugo.io/&#34;&gt;annuaire de thèmes Hugo&lt;/a&gt;, choisissez un thème, par exemple le &lt;a href=&#34;https://themes.gohugo.io/themes/hugo-theme-cleanwhite/&#34;&gt;thème Clean White pour Hugo&lt;/a&gt; et cliquez de droit sur le bouton « Download » pour copier l&amp;rsquo;adresse où se trouve le thème.&lt;/p&gt;
&lt;p&gt;Pour l&amp;rsquo;installer il suffira de taper la commande suivante dans le répertoire &lt;strong&gt;superblog&lt;/strong&gt; (exemple avec le thème &lt;em&gt;Clean White&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-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;# Nécessite d&amp;#39;avoir la commande `git` installée sur sa machine&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git init &lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; git submodule add https://github.com/zhaohuabing/hugo-theme-cleanwhite themes/cleanwhite
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On &lt;strong&gt;enregistre&lt;/strong&gt; ensuite &lt;strong&gt;le thème dans la configuration&lt;/strong&gt; de ce site - dont nous parlerons dans le chapitre 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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#007020&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;theme = &amp;#39;cleanwhite&amp;#39;&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; hugo.toml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Si vous êtes curieux du résultat&lt;/strong&gt;, vous pouvez directement lancer la commande 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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hugo serve -D
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;qui aura pour effet de &lt;strong&gt;lancer un serveur web en arrière plan&lt;/strong&gt; et de vous fournir une adresse URL où consulter votre nouveau site. Par exemple sur http://localhost:1313/. Pour arrêter le serveur, pressez simultanément les touches &lt;strong&gt;[Ctrl]+[c]&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Regardons de plus près la configuration du site.&lt;/p&gt;
&lt;h1 id=&#34;configuration-du-site-le-fichier-hugotoml&#34;&gt;Configuration du site, le fichier hugo.toml&lt;/h1&gt;
&lt;p&gt;La &lt;strong&gt;configuration principale de votre site&lt;/strong&gt; se trouve dans le &lt;strong&gt;fichier hugo.toml&lt;/strong&gt; (anciennement &lt;em&gt;config.toml&lt;/em&gt;). La &lt;a href=&#34;https://gohugo.io/configuration/&#34;&gt;documentation officielle sur le fichier hugo.toml&lt;/a&gt; vous donnera une idée de l&amp;rsquo;ampleur des possibilités qu&amp;rsquo;offre la configuration d&amp;rsquo;un site Hugo.&lt;/p&gt;
&lt;p&gt;Cantonnons-nous ici de quelques éléments seulement. Le contenu actuel du fichier &lt;strong&gt;hugo.toml&lt;/strong&gt; est :&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-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;baseURL = &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;https://example.org/&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;locale = &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;en-us&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;title = &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;My New Hugo Project&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;theme = &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;cleanwhite&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Les éléments sont plutôt parlants :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;baseURL&lt;/strong&gt; : va définir l&amp;rsquo;&lt;strong&gt;adresse URL finale&lt;/strong&gt; de votre site (par exemple pour mon blog ça sera &lt;a href=&#34;https://olivier.dossmann.net/)&#34;&gt;https://olivier.dossmann.net/)&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;locale&lt;/strong&gt; : définit le &lt;strong&gt;langage du site&lt;/strong&gt; au regard de la &lt;a href=&#34;https://datatracker.ietf.org/doc/html/rfc5646#section-2.1&#34;&gt;RFC5646&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;title&lt;/strong&gt; : est le &lt;strong&gt;titre affiché&lt;/strong&gt; sur le site,&lt;/li&gt;
&lt;li&gt;et &lt;strong&gt;theme&lt;/strong&gt; est l&amp;rsquo;adresse vers les fichiers du thème utilisé pour notre site.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Modifions le fichier &lt;em&gt;hugo.toml&lt;/em&gt; pour ressembler à ceci :&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-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;baseURL = &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;https://example.org/&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;locale = &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;fr&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;title = &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;Mon Super Blog&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;theme = &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;cleanwhite&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;enableEmoji = &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On relance le &lt;strong&gt;serveur local&lt;/strong&gt; intégré à Hugo pour voir le résultat :&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;# Faites Ctrl + c pour arrêter le serveur&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hugo serve -D
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On a rajouté une ligne &lt;code&gt;enableEmoji&lt;/code&gt; pour activer l&amp;rsquo;&lt;strong&gt;utilisation des emojis&lt;/strong&gt; dans les articles. Cf. la &lt;a href=&#34;https://gohugo.io/quick-reference/emojis/&#34;&gt;page de la documentation officielle consacrée à la liste des émojis disponibles sous Hugo&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;mon-premier-article&#34;&gt;Mon premier article&lt;/h1&gt;
&lt;p&gt;Commençons par créer ledit article :&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;# Très souvent les thèmes proposés n&amp;#39;utilisent que les articles situés dans le dossier &amp;#34;post&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hugo new content -k post post/mon_premier_post.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;L&amp;rsquo;extension &lt;code&gt;.md&lt;/code&gt; est ici nécessaire. L&amp;rsquo;option &lt;strong&gt;-k&lt;/strong&gt; va suggérer d&amp;rsquo;utiliser un template &lt;em&gt;post.md&lt;/em&gt; s&amp;rsquo;il existe. C&amp;rsquo;est ce qu&amp;rsquo;on appelle &lt;strong&gt;un archétype&lt;/strong&gt; : un fichier au &lt;a href=&#34;https://fr.wikipedia.org/wiki/Markdown&#34;&gt;format Markdown&lt;/a&gt; situé dans le dossier &lt;em&gt;themes/monTheme/archetypes/&lt;/em&gt; (par exemple &lt;code&gt;themes/cleanwhite/archetypes/post.md&lt;/code&gt;) qui sera copié en lieu et place de l&amp;rsquo;article demandé ; ici dans post/mon_premier_post.md. Les &lt;strong&gt;fichiers&lt;/strong&gt; sont &lt;strong&gt;toujours placés dans le dossier content&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Le fichier est &lt;strong&gt;placé dans le dossier content/post/mon_premier_post.md&lt;/strong&gt; dont voici le contenu :&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:#0e84b5;font-weight:bold&#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;title&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;       &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;An Example Post&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:#062873;font-weight:bold&#34;&gt;subtitle&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;&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:#062873;font-weight:bold&#34;&gt;description&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;&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:#062873;font-weight:bold&#34;&gt;date&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;2018-06-04&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;author&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;      &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;&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:#062873;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;       &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;&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:#062873;font-weight:bold&#34;&gt;tags&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;[&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;tag1&amp;#34;&lt;/span&gt;,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;tag2&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:#062873;font-weight:bold&#34;&gt;categories&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;  &lt;/span&gt;[&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;Tech&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#bbb&#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:#0e84b5;font-weight:bold&#34;&gt;---&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;Les articles auront &lt;strong&gt;toujours la même forme&lt;/strong&gt; :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Une entête&lt;/strong&gt; délimitée par une chaîne de caractère de début et de fin (ici &lt;code&gt;---&lt;/code&gt; en début et fin),&lt;/li&gt;
&lt;li&gt;Le &lt;strong&gt;contenu de l&amp;rsquo;article&lt;/strong&gt;, écrit au &lt;strong&gt;&lt;a href=&#34;https://fr.wikipedia.org/wiki/Markdown&#34;&gt;format Markdown&lt;/a&gt;&lt;/strong&gt; (par défaut).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Dans le cas présent, nous n&amp;rsquo;avons aucun contenu.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;article propose seulement une entête contenant des &lt;strong&gt;informations&lt;/strong&gt; qui seront &lt;strong&gt;utilisées comme méta-données de l&amp;rsquo;article&lt;/strong&gt; (par exemple son titre, une description, un sous-titre, l&amp;rsquo;auteur de l&amp;rsquo;article, éventuellement une image, des balises (tags) et des catégories). L&amp;rsquo;exemple utilise les tags nommés &lt;em&gt;tag1&lt;/em&gt; et &lt;em&gt;tag2&lt;/em&gt; ; et une catégorie &lt;em&gt;Tech&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Notez également la date fournie : on peut &lt;strong&gt;déterminer la date de publication d&amp;rsquo;un article&lt;/strong&gt;. Si c&amp;rsquo;est une date dans le futur, alors l&amp;rsquo;article ne sera pas publié - ce qui est très pratique !&lt;/p&gt;
&lt;p&gt;Pour empêcher également qu&amp;rsquo;un article soit publié, on peut rajouter une information comme :&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;draft&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;true&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;Ce qui aura pour effet, excepté si l&amp;rsquo;option &lt;code&gt;-D&lt;/code&gt; est ajoutée, de &lt;strong&gt;ne pas rendre disponible cet article&lt;/strong&gt; - très pratique aussi !&lt;/p&gt;
&lt;p&gt;Ajoutez quelques lignes à la fin du fichier (après les méta-données et la chaîne de caractère &lt;code&gt;---&lt;/code&gt;) pour regarder le résultat :&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-md&#34; data-lang=&#34;md&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000080;font-weight:bold&#34;&gt;# Titre 1
&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;Quelques lignes avec du texte en &lt;span style=&#34;font-weight:bold&#34;&gt;**gras**&lt;/span&gt;, ou &lt;span style=&#34;font-style:italic&#34;&gt;*italique*&lt;/span&gt;, c&amp;#39;est comme vous voulez.
&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:#000080;font-weight:bold&#34;&gt;# Titre 2
&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:#800080;font-weight:bold&#34;&gt;## Sous-titre
&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;Avec un lien vers [&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;mon blog&lt;/span&gt;](&lt;span style=&#34;color:#4070a0&#34;&gt;https://olivier.dossmann.net/&lt;/span&gt;).
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On vérifie à l&amp;rsquo;aide de la commande &lt;code&gt;hugo serve -D&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&#34;compilation-du-site&#34;&gt;Compilation du site&lt;/h1&gt;
&lt;p&gt;Maintenant que nous avons un site, un thème configuré dans le fichier &lt;em&gt;hugo.toml&lt;/em&gt; et un article, voyons l&amp;rsquo;&lt;strong&gt;étape de compilation&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;La compilation, avec Hugo, c&amp;rsquo;est le fait de &lt;strong&gt;prendre l&amp;rsquo;ensemble des fichiers&lt;/strong&gt; et informations du site et de &lt;strong&gt;les transformer en un dossier complet&lt;/strong&gt; qui &lt;strong&gt;fournit les pages Web&lt;/strong&gt; - et tout autre fichier nécessaire à l&amp;rsquo;élaboration du site. Hugo &lt;strong&gt;stocke le résultat&lt;/strong&gt; dans un &lt;strong&gt;dossier nommé &lt;code&gt;public&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Pour lancer la compilation complète, on peut, à la racine du site, taper la commande 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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hugo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Cette commande seule suffit à compiler l&amp;rsquo;ensemble du site et le rendre disponible dans le dossier &lt;em&gt;public&lt;/em&gt;. C&amp;rsquo;est le contenu de ce dernier que vous devez déposer dans l&amp;rsquo;espace fourni par votre hébergeur de site web.&lt;/p&gt;
&lt;p&gt;On peut agrémenter la commande de &lt;strong&gt;plusieurs options&lt;/strong&gt;, par exemple :&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;hugo -D --minify
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;L&amp;rsquo;option &lt;strong&gt;-D&lt;/strong&gt; va aussi &lt;strong&gt;compiler les articles dits « brouillons »&lt;/strong&gt; (ayant &lt;code&gt;draft: true&lt;/code&gt; dans la section des méta-données).&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;option &lt;strong&gt;&amp;ndash;minify&lt;/strong&gt; va &lt;strong&gt;réduire la taille des fichiers&lt;/strong&gt; en enlevant le plus possible les espaces, retour à la ligne et assimilés.&lt;/p&gt;
&lt;p&gt;Il y a énormément d&amp;rsquo;options et là encore la &lt;a href=&#34;https://gohugo.io/commands/hugo/&#34;&gt;documentation officielle d&amp;rsquo;Hugo sur la commande hugo&lt;/a&gt; permet d&amp;rsquo;en savoir plus.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;À travers &lt;strong&gt;quelques étapes simples&lt;/strong&gt;, nous avons vu comment &lt;strong&gt;installer la commande &lt;code&gt;hugo&lt;/code&gt;&lt;/strong&gt;, créer un &lt;strong&gt;nouveau site&lt;/strong&gt;, ajouter un &lt;strong&gt;thème&lt;/strong&gt;, &lt;strong&gt;configurer&lt;/strong&gt; le site, &lt;strong&gt;rédiger un article&lt;/strong&gt; et &lt;strong&gt;compiler&lt;/strong&gt; l&amp;rsquo;ensemble pour générer les fichiers suffisants pour &lt;strong&gt;créer un nouveau site web statique&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Hugo est un &lt;strong&gt;moteur de site statique&lt;/strong&gt; très &lt;strong&gt;riche&lt;/strong&gt; et bourré de &lt;strong&gt;fonctionnalités en tous genres&lt;/strong&gt; comme la gestion de contenu &lt;a href=&#34;https://gohugo.io/content-management/multilingual/&#34;&gt;&lt;strong&gt;multilingue&lt;/strong&gt;&lt;/a&gt;, l&amp;rsquo;usage de « &lt;a href=&#34;https://gohugo.io/shortcodes/&#34;&gt;&lt;strong&gt;bouts de code&lt;/strong&gt;&lt;/a&gt; » réemployables, le &lt;a href=&#34;https://gohugo.io/content-management/image-processing/&#34;&gt;&lt;strong&gt;redimensionnement des images&lt;/strong&gt;&lt;/a&gt;, les &lt;a href=&#34;https://gohugo.io/content-management/comments/&#34;&gt;&lt;strong&gt;commentaires&lt;/strong&gt;&lt;/a&gt;, la &lt;a href=&#34;https://gohugo.io/templates/rss/&#34;&gt;génération d&amp;rsquo;un ou plusieurs &lt;strong&gt;flux RSS&lt;/strong&gt;&lt;/a&gt;, la personnalisation des &lt;strong&gt;thèmes&lt;/strong&gt;, une &lt;a href=&#34;https://gohugo.io/templates/404/&#34;&gt;&lt;strong&gt;page 404 personnalisée&lt;/strong&gt;&lt;/a&gt;, l&amp;rsquo;usage de &lt;a href=&#34;https://gohugo.io/quick-reference/syntax-highlighting-styles/&#34;&gt;&lt;strong&gt;coloration syntaxique&lt;/strong&gt;&lt;/a&gt; pour les balises HTML code, le &lt;strong&gt;serveur web embarqué&lt;/strong&gt;, une &lt;a href=&#34;https://gohugo.io/host-and-deploy/&#34;&gt;commande de &lt;strong&gt;déploiement&lt;/strong&gt;&lt;/a&gt; et bien plus encore…&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est &lt;strong&gt;mon outil favori depuis 2016&lt;/strong&gt;. Je prévois cette année encore de concocter un article supplémentaire à son sujet qui dépendra du présent article qui, je l&amp;rsquo;espère, vous plaira.&lt;/p&gt;
&lt;p&gt;Qui sait, peut-être vous lancerez-vous, vous aussi, dans la création et la publication d&amp;rsquo;un blog - et cela gratuitement &amp;#x1f609;.&lt;/p&gt;
&lt;h1 id=&#34;liens-utiles&#34;&gt;Liens utiles&lt;/h1&gt;
&lt;p&gt;Voici les liens de l’article par ordre d’apparition :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gohugo.io/&#34;&gt;Site officiel du moteur de site statique Hugo&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://olivier.dossmann.net/2016/03/hugo_le_moteur_de_blog_statique_rapide_et_moderne/&#34;&gt;Article de 2016 sur ma migration vers Hugo comme moteur de blog statique&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/blankoworld/hugo_theme_adam_eve/&#34;&gt;Mon thème Hugo nommé Adam &amp;amp; Eve&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gohugo.io/installation/&#34;&gt;Documentation officielle sur l&amp;rsquo;installation d&amp;rsquo;Hugo&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gohugo.io/documentation/&#34;&gt;Documentation officielle d&amp;rsquo;Hugo&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://themes.gohugo.io/&#34;&gt;Annuaire des thèmes pour Hugo&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://themes.gohugo.io/themes/hugo-theme-cleanwhite/&#34;&gt;Thème Clean White pour Hugo&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gohugo.io/configuration/&#34;&gt;Documentation officielle sur le fichier de configuration hugo.toml&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://datatracker.ietf.org/doc/html/rfc5646#section-2.1&#34;&gt;RFC5646&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gohugo.io/quick-reference/emojis/&#34;&gt;Liste des émojis disponibles sous Hugo&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://fr.wikipedia.org/wiki/Markdown&#34;&gt;Le format Markdown&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gohugo.io/commands/hugo/&#34;&gt;Documentation officielle d&amp;rsquo;Hugo sur la commande &lt;code&gt;hugo&lt;/code&gt;&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gohugo.io/content-management/multilingual/&#34;&gt;Fonction multilingue d&amp;rsquo;Hugo&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gohugo.io/shortcodes/&#34;&gt;Les « bouts de code » sous Hugo&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gohugo.io/content-management/image-processing/&#34;&gt;Redimensionnement des images dans Hugo&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gohugo.io/content-management/comments/&#34;&gt;Fonction de commentaires dans Hugo&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gohugo.io/templates/rss/&#34;&gt;Les flux RSS dans Hugo&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gohugo.io/templates/404/&#34;&gt;La page 404 dans Hugo&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gohugo.io/quick-reference/syntax-highlighting-styles/&#34;&gt;Fonction de coloration syntaxique dans Hugo&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gohugo.io/host-and-deploy/&#34;&gt;La sous-commande &lt;code&gt;deploy&lt;/code&gt; dans Hugo&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
	    <title>Mon Labo K8S pour essayer des applications</title>
      <link>https://olivier.dossmann.net/2025/11/mon-labo-k8s-pour-essayer-des-applications/</link>
      <pubDate>Sun, 09 Nov 2025 06:25:39 +0100</pubDate>
      
      <guid>https://olivier.dossmann.net/2025/11/mon-labo-k8s-pour-essayer-des-applications/</guid>
      <description>&lt;h1 id=&#34;introduction&#34;&gt;Introduction&lt;/h1&gt;
&lt;p&gt;Quand on commence à étudier Kubernetes (k8s), on a &lt;strong&gt;besoin d&amp;rsquo;un environnement où tester&lt;/strong&gt; ce qu&amp;rsquo;on apprend. Les environnements possibles sont nombreux : &lt;a href=&#34;https://minikube.sigs.k8s.io/docs/&#34;&gt;Minikube&lt;/a&gt;, &lt;a href=&#34;https://kubernetes.io/fr/&#34;&gt;Kubernetes (k8s) officiel&lt;/a&gt;, &lt;a href=&#34;https://k0sproject.io/&#34;&gt;k0s&lt;/a&gt;, &lt;a href=&#34;https://k3s.io/&#34;&gt;k3s&lt;/a&gt;, etc. Cela ne s&amp;rsquo;arrête plus !&lt;/p&gt;
&lt;p&gt;Entre les &lt;strong&gt;difficultés à installer l&amp;rsquo;environnement&lt;/strong&gt; et celles à appliquer ce qu&amp;rsquo;on apprend, on ne s&amp;rsquo;en sort plus. Cela devient &lt;strong&gt;vite compliqué&lt;/strong&gt; au point de vouloir tout arrêter ; c&amp;rsquo;était mon cas.&lt;/p&gt;
&lt;p&gt;De plus je souhaitais avoir un environnement reproductible et spécifique à chacun de mes projets, de quoi travailler unitairement sur un service particulier.&lt;/p&gt;
&lt;p&gt;Avant de décrocher complètement, j&amp;rsquo;ai fait une pause, &lt;strong&gt;pris du recul&lt;/strong&gt; et étudié la question. Je vous relate ici le résultat de cette petite aventure dans le monde de Kubernetes et des outils envisagés pour &lt;strong&gt;créer un labo de développement&lt;/strong&gt; d&amp;rsquo;applications tournant sous Kubernetes.&lt;/p&gt;
&lt;p&gt;Dans un premier temps nous poserons le problème, après quoi nous étudierons quelques solutions pour finalement détailler le produit de cette pérégrination.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/objets/tubes_a_essai.jpg&#34; alt=&#34;Quelques tubes à essais avec une pipette vus de près&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Photo trouvée sur &lt;a href=&#34;https://www.publicdomainpictures.net/fr/view-image.php?image=45299&amp;amp;picture=tubes-a-essai&#34;&gt;publicdomainpictures.net&lt;/a&gt;&lt;/em&gt; sous Licence CC0 Public Domain.&lt;/p&gt;
&lt;h1 id=&#34;le-contexte&#34;&gt;Le contexte&lt;/h1&gt;
&lt;p&gt;Venant du &lt;a href=&#34;https://olivier.dossmann.net/tags/docker/&#34;&gt;monde de Docker et Docker Compose&lt;/a&gt;, il me semblait aller de soi d&amp;rsquo;étudier ensuite le monde de Kubernetes - qui utilise la conteneurisation. Seulement je ne pensais pas que l&amp;rsquo;installation même de &lt;strong&gt;Kubernetes était un cap à franchir&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Je souhaite en &lt;strong&gt;profiter pour migrer&lt;/strong&gt; petit à petit &lt;strong&gt;mes services sur Kubernetes&lt;/strong&gt;. Chacun d&amp;rsquo;eux devient donc un projet en soi. Et comme souvent, &lt;strong&gt;j&amp;rsquo;aime avoir un environnement spécifique de développement&lt;/strong&gt; pour créer les fichiers nécessaires à Kubernetes et permettre a posteriori d&amp;rsquo;améliorer le service. Je cherche donc à avoir un simili de docker-compose.yml pour chaque service et permettant de développer l&amp;rsquo;application dans un environnement Kubernetes propre.&lt;/p&gt;
&lt;p&gt;Au début on découvre &lt;a href=&#34;https://minikube.sigs.k8s.io/docs/&#34;&gt;&lt;strong&gt;Minikube&lt;/strong&gt;&lt;/a&gt;. Du moins c&amp;rsquo;est un outil très souvent conseillé. &lt;strong&gt;Pratique&lt;/strong&gt; sur une machine bureautique pour triturer rapidement quelques fichiers Kubernetes (des fichiers au format YAML). Il est &lt;strong&gt;bien documenté&lt;/strong&gt; et possède plusieurs plugins pour faciliter l&amp;rsquo;étude du Kubernetes en place ; par exemple un &lt;strong&gt;plugin Dashboard&lt;/strong&gt; permet de visualiser les métriques du serveur et les objets instanciés. J&amp;rsquo;ai la sensation que cet outil reste « trop spécifique ». Il ne représente pas totalement un « vrai » Kubernetes. Ça peut parfois causer des torts au moment de déployer sur un autre serveur Kubernetes. L&amp;rsquo;outil est également &lt;strong&gt;lourd&lt;/strong&gt; et relativement &lt;strong&gt;lent&lt;/strong&gt; pour instancier un nouvel environnement.&lt;/p&gt;
&lt;p&gt;Pourquoi ne pas tester un Kubernetes connu pour sa légèreté ? Par exemple &lt;a href=&#34;https://k3s.io/&#34;&gt;&lt;strong&gt;k3s&lt;/strong&gt;&lt;/a&gt;. D&amp;rsquo;autant qu&amp;rsquo;il s&amp;rsquo;installe rapidement à l&amp;rsquo;aide de &lt;a href=&#34;https://github.com/alexellis/k3sup&#34;&gt;&lt;strong&gt;k3sup&lt;/strong&gt;&lt;/a&gt; (qui fonctionne à merveille). Sur le papier c&amp;rsquo;est une bonne idée : &lt;strong&gt;léger, facile à installer&lt;/strong&gt;. En revanche il &lt;strong&gt;ne permet pas d&amp;rsquo;instancier un nouvel environnement&lt;/strong&gt; ; il faut donc jouer avec les namespaces Kubernetes. Rebelote : ce n&amp;rsquo;est pas un outil adapté à l&amp;rsquo;apprentissage de Kubernetes. Au départ on fait forcément des erreurs dues à l&amp;rsquo;incompréhension ou l&amp;rsquo;ignorance ; ce qui peut rendre l&amp;rsquo;environnement rapidement inutilisable.&lt;/p&gt;
&lt;p&gt;Après ces deux premières tentatives, je sais désormais ce que je veux :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;possibilité de &lt;strong&gt;créer un environnement « propre »&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;encore mieux s&amp;rsquo;il peut créer &lt;strong&gt;plusieurs environnements&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;si possible &lt;strong&gt;léger&lt;/strong&gt; (petit) - ce qui exclue les machines virtuelles,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;facile à installer&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;et &lt;strong&gt;rapide&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nous avons nos critères, il ne reste plus qu&amp;rsquo;à chercher le(s) outil(s) permettant de créer rapidement un environnement de développement autour de Kubernetes.&lt;/p&gt;
&lt;h1 id=&#34;solutions-étudiées&#34;&gt;Solutions étudiées&lt;/h1&gt;
&lt;p&gt;À la recherche des mots clés « lightweight » (similaire au mot léger) et « kubernetes » dans un moteur de recherche, on trouve plusieurs outils comme :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://microk8s.io/&#34;&gt;MicroK8S&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://k0sproject.io/&#34;&gt;k0s&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://k3s.io/&#34;&gt;k3s&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;et &lt;a href=&#34;https://kind.sigs.k8s.io/&#34;&gt;kind&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;k3s&lt;/strong&gt; a déjà été cité dans cet article. Il ne me convient pas pour un environnement de développement/d&amp;rsquo;étude concernant k8s. Il est sûrement très &lt;strong&gt;redoutable à l&amp;rsquo;installation rapide&lt;/strong&gt; sur une quantité importante de machines à l&amp;rsquo;aide de &lt;a href=&#34;https://github.com/alexellis/k3sup&#34;&gt;k3sup&lt;/a&gt;. Mais ce n&amp;rsquo;est pas le sujet de cet article.&lt;/p&gt;
&lt;p&gt;La liste mentionne également &lt;a href=&#34;https://microk8s.io/&#34;&gt;&lt;strong&gt;MicroK8S&lt;/strong&gt;&lt;/a&gt;, le petit rejeton de la famille Ubuntu, qui semble être une &lt;strong&gt;alternative à &lt;a href=&#34;https://minikube.sigs.k8s.io/docs/&#34;&gt;Minikube&lt;/a&gt;&lt;/strong&gt; avec des &lt;strong&gt;plugins&lt;/strong&gt; (Dashboard, DNS, registry, istio, etc.). Je pense qu&amp;rsquo;il est effectivement intéressant pour un usage complet entre des développeurs, une intégration continue (CI) / déploiement continue (CD) et plusieurs environnements allant jusqu&amp;rsquo;à des environnements dit « de production ». Je sens cependant que la similitude avec Minikube ne puisse me convenir. Je le &lt;strong&gt;laisse de côté pour l&amp;rsquo;instant&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://k0sproject.io/&#34;&gt;&lt;strong&gt;k0s&lt;/strong&gt;&lt;/a&gt;, quant à lui, semble être la &lt;strong&gt;solution idéale pour&lt;/strong&gt; une installation sur &lt;strong&gt;une machine physique&lt;/strong&gt;. À &lt;strong&gt;usage privé&lt;/strong&gt;. Bien qu&amp;rsquo;il semble &lt;strong&gt;léger, facile à installer&lt;/strong&gt; et utiliser, je comprends rapidement qu&amp;rsquo;il est fait pour avoir une installation unique sur une machine physique précise. Il &lt;strong&gt;ne répond pas à&lt;/strong&gt; mon critère de &lt;strong&gt;création multiple d&amp;rsquo;environnements&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Et un de plus en moins !&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Il reste le dernier de cette liste : &lt;a href=&#34;https://kind.sigs.k8s.io/&#34;&gt;&lt;strong&gt;kind&lt;/strong&gt;&lt;/a&gt;. A priori il semble &lt;strong&gt;léger&lt;/strong&gt;, prévu pour un usage &lt;strong&gt;spécifique au développement&lt;/strong&gt; ou de l&amp;rsquo;&lt;strong&gt;intégration continue&lt;/strong&gt; (CI) et &lt;strong&gt;utilise Docker&lt;/strong&gt; pour créer un cluster complet à chaque fois. Waouh, rien que ça ! Sur le papier, cet outil est &lt;strong&gt;très prometteur&lt;/strong&gt; car il répond aux critères précédemment listés :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;créer des environnements « propres » grâce à l&amp;rsquo;usage de Docker,&lt;/li&gt;
&lt;li&gt;ainsi il permet l&amp;rsquo;usage de plusieurs environnements,&lt;/li&gt;
&lt;li&gt;il est léger, petit,&lt;/li&gt;
&lt;li&gt;facile à installer puisque &lt;a href=&#34;https://aur.archlinux.org/packages/kind&#34;&gt;kind est disponible dans les dépôts AUR d&amp;rsquo;ArchLinux&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;et pour la rapidité nous verrons.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;À l&amp;rsquo;usage, kind (qui veut dire Kubernetes IN Docker) semble &lt;strong&gt;facile à prendre en main&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;# Créer un cluster nommé olivier&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kind create cluster --name olivier
&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;# Supprime le cluster nommé olivier&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kind delete cluster --name olivier
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Une fois le cluster créé, il s&amp;rsquo;agit simplement de jouer avec la commande &lt;code&gt;kubectl&lt;/code&gt; habituelle pour contacter le cluster. Et la commande étant à taper, je peux tout à fait &lt;strong&gt;scripter la création du cluster&lt;/strong&gt; et sa destruction.&lt;/p&gt;
&lt;p&gt;Il serait plus pratique de l&amp;rsquo;utiliser avec &lt;strong&gt;d&amp;rsquo;autres outils pour en faciliter l&amp;rsquo;usage&lt;/strong&gt;. J&amp;rsquo;ai donc cherché au fur et à mesure de nouveaux outils dont voici la liste :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ahmetb/kubectx&#34;&gt;&lt;strong&gt;kubectx&lt;/strong&gt;&lt;/a&gt; va permettre de &lt;strong&gt;commuter&lt;/strong&gt; d&amp;rsquo;&lt;strong&gt;un contexte Kubernetes&lt;/strong&gt; à un autre. Autrement dit passer d&amp;rsquo;un cluster à un autre facilement,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/yannh/kubeconform&#34;&gt;&lt;strong&gt;kubeconform&lt;/strong&gt;&lt;/a&gt; pour &lt;strong&gt;valider&lt;/strong&gt; nos fichiers YAML,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/stackrox/kube-linter&#34;&gt;&lt;strong&gt;kube-linter&lt;/strong&gt;&lt;/a&gt; pour pousser à l&amp;rsquo;usage des &lt;strong&gt;bonnes pratiques&lt;/strong&gt; en matière de rédaction de fichiers YAML,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://skaffold.dev/&#34;&gt;&lt;strong&gt;skaffold&lt;/strong&gt;&lt;/a&gt; pour &lt;strong&gt;surveiller&lt;/strong&gt; la moindre modification (équivalent d&amp;rsquo;un « watcher ») sur nos fichiers YAML et les déployer directement sur le cluster,&lt;/li&gt;
&lt;li&gt;et &lt;a href=&#34;https://fr.wikipedia.org/wiki/Make&#34;&gt;&lt;strong&gt;make&lt;/strong&gt;&lt;/a&gt; (avec un &lt;strong&gt;fichier Makefile&lt;/strong&gt;) pour mélanger tout ça.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mon idée est d&amp;rsquo;utiliser un fichier Makefile pour fournir plusieurs commandes permettant de créer le cluster, le détruire, vérifier les fichiers YAML ou encore lancer un déploiement automatique s&amp;rsquo;il y a des changements dans les fichiers en cours de développement.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;imagine quelque chose comme :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;make cluster&lt;/code&gt; pour &lt;strong&gt;créer un cluster&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;make dev&lt;/code&gt; pour lancer skaffold et &lt;strong&gt;écouter le moindre changement&lt;/strong&gt; sur le dossier de développement de l&amp;rsquo;application,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;make kubeconform&lt;/code&gt; pour &lt;strong&gt;vérifier&lt;/strong&gt; les fichiers une fois écrits,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;make lint&lt;/code&gt; pour vérifier les &lt;strong&gt;bonnes pratiques&lt;/strong&gt; avec kube-linter,&lt;/li&gt;
&lt;li&gt;et &lt;code&gt;make clean&lt;/code&gt; pour &lt;strong&gt;détruire le cluster&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tentons l&amp;rsquo;aventure et voyons le résultat !&lt;/p&gt;
&lt;h1 id=&#34;ce-que-jai-finalement-produit&#34;&gt;Ce que j&amp;rsquo;ai finalement produit&lt;/h1&gt;
&lt;h2 id=&#34;en-bref&#34;&gt;En bref&lt;/h2&gt;
&lt;p&gt;Le fichier &lt;strong&gt;Makefile&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-Makefile&#34; data-lang=&#34;Makefile&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bb60d5&#34;&gt;CLUSTER_NAME&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;:=&lt;/span&gt; k8s-dev-example
&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;KUBECTL&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;:=&lt;/span&gt; kubectl
&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;SKAFFOLD&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;:=&lt;/span&gt; skaffold
&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;KIND&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;:=&lt;/span&gt; kind
&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;KUBECONFORM&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;:=&lt;/span&gt; kubeconform
&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;KUSTOMIZE&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;:=&lt;/span&gt; kustomize
&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:#bb60d5&#34;&gt;NAMESPACES&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;:=&lt;/span&gt; dev
&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:#06287e&#34;&gt;.PHONY&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;:&lt;/span&gt; help
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#06287e&#34;&gt;help&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	@echo &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;Commandes disponibles :&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	@echo &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;  make cluster       - Crée un cluster Kind&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	@echo &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;  make namespaces    - Crée les namespaces Kubernetes (dev/staging/prod)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	@echo &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;  make dev           - Lance Skaffold pour l&amp;#39;env dev&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	@echo &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;  make kubeconform   - Lance kubeconform sur l&amp;#39;env de DEV&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	@echo &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;  make clean         - Supprime le cluster Kind&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 style=&#34;color:#06287e&#34;&gt;cluster&lt;/span&gt;&lt;span style=&#34;color:#666&#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;$(&lt;/span&gt;KIND&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;)&lt;/span&gt; create cluster --name &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;$(&lt;/span&gt;CLUSTER_NAME&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#666&#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;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#06287e&#34;&gt;namespaces&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	@for ns in &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;$(&lt;/span&gt;NAMESPACES&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;)&lt;/span&gt;; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;do&lt;/span&gt; &lt;span style=&#34;color:#4070a0;font-weight:bold&#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;$(&lt;/span&gt;KUBECTL&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;)&lt;/span&gt; get ns &lt;span style=&#34;color:#bb60d5&#34;&gt;$$&lt;/span&gt;ns &amp;gt;/dev/null 2&amp;gt;&amp;amp;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;||&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;$(&lt;/span&gt;KUBECTL&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;)&lt;/span&gt; create ns &lt;span style=&#34;color:#bb60d5&#34;&gt;$$&lt;/span&gt;ns; &lt;span style=&#34;color:#4070a0;font-weight:bold&#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;done&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:#06287e&#34;&gt;dev&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;:&lt;/span&gt; cluster namespaces
&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;$(&lt;/span&gt;SKAFFOLD&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;)&lt;/span&gt; dev
&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:#06287e&#34;&gt;kubeconform&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;:&lt;/span&gt; kubeconform-dev
&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:#06287e&#34;&gt;kubeconform-dev&lt;/span&gt;&lt;span style=&#34;color:#666&#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;$(&lt;/span&gt;KUSTOMIZE&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;)&lt;/span&gt; build overlays/dev | &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;$(&lt;/span&gt;KUBECONFORM&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;)&lt;/span&gt; -strict -summary -ignore-missing-schemas
&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:#06287e&#34;&gt;clean&lt;/span&gt;&lt;span style=&#34;color:#666&#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;$(&lt;/span&gt;KIND&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;)&lt;/span&gt; delete cluster --name &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;$(&lt;/span&gt;CLUSTER_NAME&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ce &lt;a href=&#34;https://gitlab.com/odtre/templates/k8s-dev-example/&#34;&gt;fichier Makefile est disponible sur le dépôt Gitlab d&amp;rsquo;ODTRE&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Il va utiliser deux dossiers principaux :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;base&lt;/strong&gt; qui contient les fichiers YAML de l&amp;rsquo;application qu&amp;rsquo;on souhaite implémenter sur Kubernetes,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;overlays/dev&lt;/strong&gt; qui contient un fichier kustomization.yaml pour surcharger le dossier &lt;em&gt;base&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Et 2 fichiers de configuration :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;kube-linter.yaml&lt;/strong&gt; avec votre configuration de l&amp;rsquo;outil,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;skaffold.yaml&lt;/strong&gt; avec le contenu suivant :&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;apiVersion&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;skaffold/v4beta13&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;kind&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;Config&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;metadata&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;name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;k8s-demo-app&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;manifests&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;kustomize&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;- ./overlays/dev&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:#60a0b0;font-style:italic&#34;&gt;# Exemple de redirection de port sur le service nommé dev-nginx (car l&amp;#39;overlay ajoute dev- devant tout)&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;portForward&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;resourceType&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;service&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;resourceName&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;dev-nginx&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;namespace&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;dev&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;port&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;80&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;localPort&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;4000&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;Cela permet de surveiller le dossier &lt;em&gt;./overlays/dev&lt;/em&gt; avec &lt;em&gt;kustomize&lt;/em&gt; pour interpréter les fichiers. Et il va ouvrir le &lt;strong&gt;port 4000&lt;/strong&gt; sur la machine locale pour &lt;strong&gt;rediriger sur le port 80&lt;/strong&gt; du service Nginx d&amp;rsquo;exemple (fourni dans le dépôt Gitlab mentionné précédemment).&lt;/p&gt;
&lt;h2 id=&#34;à-lusage&#34;&gt;À l&amp;rsquo;usage&lt;/h2&gt;
&lt;p&gt;Tout n&amp;rsquo;est pas parfait. Cependant ce fichier Makefile permet de lancer quelques commandes &lt;code&gt;make&lt;/code&gt; utiles :&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;# Lance l&amp;#39;environnement de DEV. Si le cluster n&amp;#39;existe pas : il le créé. Sinon il ignore.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;make dev
&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;# Vérifie la conformité des fichiers YAML en utilisant le dossier overlays/dev&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;make kubeconform
&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;# Détruit le cluster de DEV&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;make clean
&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;# Pousse à l&amp;#39;usage des bonnes pratiques sur les fichiers contenus dans le dossier ./base&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kube-linter lint --config kube-linter.yaml ./base
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pour toute aide supplémentaire, faites : &lt;code&gt;make help&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Ainsi &lt;strong&gt;il devient facile de travailler sur un nouvel environnement&lt;/strong&gt; :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;je copie les fichiers disponible sur un &lt;a href=&#34;https://gitlab.com/odtre/templates/k8s-dev-example/&#34;&gt;dépôt template sur Gitlab&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;j&amp;rsquo;ouvre le fichier Makefile en écriture,&lt;/li&gt;
&lt;li&gt;j&amp;rsquo;édite la ligne suivante pour adapter le nom du cluster de travail :&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;CLUSTER_NAME :&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; k8s-dev-example
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Et le tour est joué !&lt;/p&gt;
&lt;p&gt;Je suis assez &lt;strong&gt;satisfait de cet environnement&lt;/strong&gt;. Il &lt;strong&gt;répond aux critères&lt;/strong&gt; édictés plusieurs fois dans cet article. Et je me sens plus à l&amp;rsquo;aise de pouvoir modifier comme bon me semble cet environnement de développement/travail.&lt;/p&gt;
&lt;p&gt;Les outils utilisés me font penser à &lt;strong&gt;une boîte à outil&lt;/strong&gt; de base pour le &lt;strong&gt;travail sur Kubernetes&lt;/strong&gt;. Même sans utiliser le fichier Makefile je suis amené à pratiquer les outils comme kubeconform, kubectl, kube-linter et kustomize.&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est donc une très bonne chose d&amp;rsquo;avoir regroupé ces outils autour de Makefile et de les utiliser régulièrement sur mes projets Kubernetes.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Nous avons posé le contexte d&amp;rsquo;une &lt;strong&gt;recherche d&amp;rsquo;outil&lt;/strong&gt; simple, rapide et léger &lt;strong&gt;pour créer de nombreux environnements Kubernetes&lt;/strong&gt; afin de travailler sur ces environnements dans le cadre d&amp;rsquo;un &lt;strong&gt;développement de fichiers YAML&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Après quelques essais sur Minikube et k3s, mes recherches se sont portées sur l&amp;rsquo;&lt;strong&gt;utilisation de kind&lt;/strong&gt;. Puis j&amp;rsquo;ai utilisé make pour le manipuler et regrouper aussi les différents outils utiles.&lt;/p&gt;
&lt;p&gt;La &lt;strong&gt;boîte à outil&lt;/strong&gt; se compose de :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;kind&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;skaffold&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;kubectl&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;kubeconform&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;kube-linter&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;et &lt;strong&gt;make&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;J&amp;rsquo;aborde désormais de &lt;strong&gt;manière plus sereine&lt;/strong&gt; le développement d&amp;rsquo;une application qui sera hébergée par un Kubernetes. J&amp;rsquo;ai un template à ma disposition pour ces fichiers. Template que je peux faire évoluer au gré des obstacles rencontrés. Il utilise tous les outils que j&amp;rsquo;ai appréciés. J&amp;rsquo;en suis &lt;strong&gt;pleinement satisfait&lt;/strong&gt; &amp;#x1f60e; .&lt;/p&gt;
&lt;p&gt;Et vous, &lt;strong&gt;quel environnement Kubernetes utilisez-vous&lt;/strong&gt; pour vos développements de fichiers YAML ?&lt;/p&gt;
&lt;h1 id=&#34;liens-utiles&#34;&gt;Liens utiles&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/fr/&#34;&gt;Kubernetes (k8s) officiel&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://microk8s.io/&#34;&gt;MicroK8S&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://minikube.sigs.k8s.io/docs/&#34;&gt;Minikube&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://k0sproject.io/&#34;&gt;k0s&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://k3s.io/&#34;&gt;k3s&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kind.sigs.k8s.io/&#34;&gt;kind&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/stackrox/kube-linter&#34;&gt;kube-linter&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/yannh/kubeconform&#34;&gt;kubeconform&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ahmetb/kubectx&#34;&gt;kubectx&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://fr.wikipedia.org/wiki/Make&#34;&gt;make&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://skaffold.dev/&#34;&gt;skaffold&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/odtre/templates/k8s-dev-example/&#34;&gt;dépôt Gitlab du template proposé dans cet article pour développer sur un environnement Kubernetes « propre »&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <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>La Gachette qui publie mon blog</title>
      <link>https://olivier.dossmann.net/2023/01/la-gachette-qui-publie-mon-blog/</link>
      <pubDate>Fri, 20 Jan 2023 17:46:32 +0200</pubDate>
      
      <guid>https://olivier.dossmann.net/2023/01/la-gachette-qui-publie-mon-blog/</guid>
      <description>&lt;h1 id=&#34;introduction&#34;&gt;Introduction&lt;/h1&gt;
&lt;p&gt;Peut-être serez-vous surpris d&amp;rsquo;apprendre que la publication d&amp;rsquo;un article sur ce blog revient simplement à écrire du texte dans un fichier et &lt;a href=&#34;https://fr.wikipedia.org/wiki/Commit&#34;&gt;envoyer un commit&lt;/a&gt; sur un dépôt Git. &lt;strong&gt;Ni plus, ni moins&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est là que commence toute une &lt;strong&gt;chaîne de publication&lt;/strong&gt; afin de mettre à disposition le fameux article sur le Web ! Pour cela j&amp;rsquo;ai utilisé très peu d&amp;rsquo;outils et un peu d&amp;rsquo;imagination.&lt;/p&gt;
&lt;p&gt;Le but du présent article est de &lt;strong&gt;vous présenter l&amp;rsquo;outil de la chaîne que j&amp;rsquo;ai dû développer pour mener à bien ce projet : &lt;a href=&#34;https://github.com/blankoworld/gachette&#34;&gt;Gachette&lt;/a&gt;&lt;/strong&gt;. Puis de vous décrire comment le mettre en place.&lt;/p&gt;
&lt;p&gt;Mais avant tout commençons à planter le décor !&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/nature/goutte.jpg&#34; alt=&#34;Phénomène de goutte qui remonte après être tombé dans 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/nikkvalentine/&#34;&gt;profil de Nikk sur Flickr&lt;/a&gt;&lt;/em&gt; sous licence CC BY 2.0.&lt;/p&gt;
&lt;h1 id=&#34;plantons-le-décor-avec-lhistoire-logicielle-de-ce-blog&#34;&gt;Plantons le décor avec l&amp;rsquo;Histoire logicielle de ce blog&lt;/h1&gt;
&lt;p&gt;(je comprendrais que ce chapitre ne soit pas très enthousiasmant pour vous, si c&amp;rsquo;est le cas, passez au suivant &amp;#x1f609;)&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://olivier.dossmann.net/2016/03/hugo_le_moteur_de_blog_statique_rapide_et_moderne/&#34;&gt;En 2016 je vous parlais d&amp;rsquo;Hugo, le moteur de blog statique&lt;/a&gt; que j&amp;rsquo;utilise pour « confectionner » ce blog. Outil très intéressant qui &lt;strong&gt;utilise de simples fichiers pour générer un site web entier&lt;/strong&gt;, statique ; c&amp;rsquo;est à dire en pur HTML et ne demandant aucune autre ressource finale qu&amp;rsquo;un serveur Web tel qu&amp;rsquo;Apache2, nginx, lighttpd, Caddy Server et j&amp;rsquo;en passe… Dans ma situation, le serveur Web en question est Nginx depuis 2013 environ - mais qu&amp;rsquo;importe.&lt;/p&gt;
&lt;p&gt;Afin de garder en mémoire les travaux effectués, &lt;a href=&#34;https://olivier.dossmann.net/2017/04/gitea-service-git-sans-prise-de-t%C3%AAte-issu-de-gogs/&#34;&gt;je vous partageais en 2017 l&amp;rsquo;outil Gitea, service Git sans prise de tête issu de Gogs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;À cette époque (entre 2016 et 2019/2020), pour publier mon blog il me faut :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(manuel) écrire l&amp;rsquo;article dans &lt;strong&gt;un fichier texte&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;(manuel) (facultatif) l&amp;rsquo;enregistrer sous Git avec &lt;strong&gt;un commit&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;(manuel) (facultatif) &lt;strong&gt;envoyer&lt;/strong&gt; l&amp;rsquo;article &lt;strong&gt;sur Gitea&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;(manuel) &lt;strong&gt;compiler le site&lt;/strong&gt; à l&amp;rsquo;aide de la commande &lt;code&gt;hugo&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;(manuel) &lt;strong&gt;synchroniser les fichiers résultants&lt;/strong&gt; sur mon serveur doté de Nginx, par exemple avec une commande &lt;code&gt;rsync&lt;/code&gt; simple&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;À force de &lt;a href=&#34;https://olivier.dossmann.net/2016/02/fosdem-2016/&#34;&gt;traîner à FOSDEM en 2016&lt;/a&gt; et &lt;a href=&#34;https://olivier.dossmann.net/2017/02/fosdem-2017-rencontre-avec-des-aliens/&#34;&gt;en 2017&lt;/a&gt;, j&amp;rsquo;ai non seulement appris que l&amp;rsquo;informatique sert à automatiser des tâches mais qu&amp;rsquo;il est aussi possible de le faire de manière « simple ».&lt;/p&gt;
&lt;p&gt;Je me renseigne et j&amp;rsquo;apprends que sous Gitlab, Github et Gitea (plateformes que j&amp;rsquo;utilise à l&amp;rsquo;époque), il existe un &lt;a href=&#34;https://blog.hubspot.fr/website/webhook&#34;&gt;système de webhooks&lt;/a&gt;. Qu&amp;rsquo;est-ce à dire ? Grossomodo je peux configurer ces plateformes pour qu&amp;rsquo;à &lt;strong&gt;chaque envoi de mon travail peut résulter un appel à une adresse Web&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Il suffit ensuite, à l&amp;rsquo;adresse appelée, de &lt;strong&gt;pouvoir étudier la requête envoyée et d&amp;rsquo;agir en conséquence&lt;/strong&gt; (par exemple déployer un site).&lt;/p&gt;
&lt;p&gt;Sur le papier ça a l&amp;rsquo;air fun :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(manuel) j&amp;rsquo;écris mon article dans &lt;strong&gt;un fichier texte&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;(manuel) je &lt;strong&gt;commite et pousse sur Gitea/Github/Gitlab&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;(automatique) la plateforme de réception &lt;strong&gt;envoie un appel&lt;/strong&gt; à un de mes serveurs&lt;/li&gt;
&lt;li&gt;(automatique) un de mes serveurs reçevant l&amp;rsquo;appel &lt;strong&gt;lance un script&lt;/strong&gt; ou une action &lt;strong&gt;pour publier&lt;/strong&gt; les dernières nouveautés&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Parfait on se lance là dedans !&lt;/p&gt;
&lt;h1 id=&#34;la-naissance-de-gachette&#34;&gt;La naissance de Gachette&lt;/h1&gt;
&lt;p&gt;En 2019 où j&amp;rsquo;étudiais la question, je ne trouvais pas de serveur simple et léger qui puisse supporter les appels envoyés par Github, Gitlab et Gitea. &lt;strong&gt;Hors de question d&amp;rsquo;avoir 3 serveurs de webhooks différents sur mes machines&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Comme j&amp;rsquo;ai cru comprendre être ingénieur logiciel au travail &amp;#x1f923;, je me suis dit pouvoir l&amp;rsquo;être aussi à la maison sur mon temps personnel. À l&amp;rsquo;époque je m&amp;rsquo;amusais un peu avec le &lt;a href=&#34;https://crystal-lang.org/&#34;&gt;langage Crystal&lt;/a&gt; avec des amis, c&amp;rsquo;était l&amp;rsquo;occasion.&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est ainsi qu&amp;rsquo;est né &lt;a href=&#34;https://github.com/blankoworld/gachette&#34;&gt;Gachette&lt;/a&gt;, un serveur de webhooks sous Licence MIT en &lt;a href=&#34;https://crystal-lang.org/&#34;&gt;Crystal&lt;/a&gt; (une syntaxe comme Ruby, mais compilé) qui supporte les plateformes Github, Gitlab et Gitea.&lt;/p&gt;
&lt;p&gt;Sous ce langage, il existe quelques &lt;a href=&#34;https://fr.wikipedia.org/wiki/Framework&#34;&gt;frameworks&lt;/a&gt;, dont &lt;a href=&#34;https://kemalcr.com/&#34;&gt;Kemal, un framework web minimaliste&lt;/a&gt; qui permet d&amp;rsquo;ouvrir quelques routes très facilement. C&amp;rsquo;est ce que j&amp;rsquo;ai utilisé pour créer &lt;a href=&#34;https://github.com/blankoworld/gachette/releases/tag/0.1&#34;&gt;la première version 0.1 de Gachette en 2019&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;À tout casser on doit être à 100 lignes de code. Bref. À aujourd&amp;rsquo;hui, plutôt 200+ lignes de code Crystal.&lt;/p&gt;
&lt;p&gt;Voyons les particularités de mise en place de Gachette.&lt;/p&gt;
&lt;h1 id=&#34;mise-en-place-de-gachette-sur-un-serveur&#34;&gt;Mise en place de Gachette sur un serveur&lt;/h1&gt;
&lt;p&gt;Je ne vais pas reproduire &lt;a href=&#34;https://github.com/blankoworld/gachette/blob/master/README.md#installation&#34;&gt;ce que le fichier README de Gachette énonce si bien pour l&amp;rsquo;installation&lt;/a&gt;, cependant je peux vous faire un résumé rapide de l&amp;rsquo;installation/configuration :&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;# On récupère le projet&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git clone https://github.com/blankoworld/gachette.git
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#007020&#34;&gt;cd&lt;/span&gt; gachette
&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;# Pré-requis : Crystal, Shards et make doivent être installés&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;shards install
&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;# On compile le logiciel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;make
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;À l&amp;rsquo;issue de ces commandes devrait apparaître un fichier &lt;strong&gt;bin/gachette&lt;/strong&gt; qui est un exécutable utilisable tel quel.&lt;/p&gt;
&lt;p&gt;On le place où on veut, par exemple dans &lt;strong&gt;/srv/www/gachette/gachette&lt;/strong&gt; puis on édite le fichier &lt;strong&gt;/etc/systemd/system/gachette.service&lt;/strong&gt; dont le contenu est le 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-service&#34; data-lang=&#34;service&#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;Gachette webhooks 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;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/gachette&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;/srv/www/gachette/gachette -c /etc/gachette.ini -b 0.0.0.0 -p 3000&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;KEMAL_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;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;À noter qu&amp;rsquo;il faut adapter &lt;strong&gt;User=http&lt;/strong&gt; par l&amp;rsquo;utilisateur de votre système d&amp;rsquo;exploitation, par exemple sous Debian c&amp;rsquo;est &lt;em&gt;User=www-data&lt;/em&gt;. Mais également le port utilisé, ici c&amp;rsquo;est le port &lt;strong&gt;3000&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Ensuite créez le fichier &lt;strong&gt;/etc/gachette.ini&lt;/strong&gt; avec un contenu qui va décrire les dépôts/projets qui vont contacter le serveur webhooks et déclencher une action. Imaginons que le projet Gachette, sur Github, à l&amp;rsquo;adresse &lt;a href=&#34;https://github.com/blankoworld/gachette&#34;&gt;https://github.com/blankoworld/gachette&lt;/a&gt; veuille qu&amp;rsquo;à chaque commit nous exécutions le contenu du script &lt;em&gt;/srv/www/gachette/deploiement.sh&lt;/em&gt;, nous allons écrire :&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;# contenu du fichier /etc/gachette.ini&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:#666&#34;&gt;[&lt;/span&gt;Un_nom_au_hasard&lt;span style=&#34;color:#666&#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:#bb60d5&#34;&gt;service&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; github
&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;namespace&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; blankoworld/gachette
&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;key&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; monMot2Passe
&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;scriptfile&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; /srv/www/gachette/deploiement.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Une fois la configuration faite, le service installé, vous pouvez faire en tant qu&amp;rsquo;utilisateur root :&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;# pour lancer le service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl start gachette.service
&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;# pour voir l&amp;#39;état du service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl status gachette.service
&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;# pour lancer le service à chaque redémarrage : &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl &lt;span style=&#34;color:#007020&#34;&gt;enable&lt;/span&gt; gachette.service
&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;# pour suivre ce qu&amp;#39;il se passe dans Gachette : &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;journalctl -xe -f -u gachette.service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Tout résidera ensuite dans &lt;strong&gt;votre capacité à créer des scripts qui feront le travail de déploiement&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Dans ma situation, pour le présent blog, j&amp;rsquo;ai un script qui :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;récupère la dernière version du dépôt Git du blog&lt;/li&gt;
&lt;li&gt;compile le site pour générer les fichiers statiques&lt;/li&gt;
&lt;li&gt;synchronise le résultat - si réussi - vers un dossier particulier&lt;/li&gt;
&lt;li&gt;relance le serveur Web avec les nouveaux fichiers&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Suite à &lt;a href=&#34;https://olivier.dossmann.net/2022/12/utilisation-de-tr%C3%A6fik-pour-publier-ses-conteneurs-docker/&#34;&gt;mon dernier article sur Træfik pour publier ses conteneurs Docker&lt;/a&gt;, je me suis même essayé à l&amp;rsquo;utilisation de conteneurs Docker pour isoler les environnements, voire même à avoir des images Docker communes pour l&amp;rsquo;ensemble des sites Web statiques : très pratique !&lt;/p&gt;
&lt;p&gt;On s&amp;rsquo;amuse bien par ici en somme &amp;#x1f609;.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Bien que certains jugerons ma chaîne de publication assez alambiquée, utilisant des outils peu communs, voire pas du tout utilisés (Gachette notamment), ce système a déjà fait ses preuves et tourne bien : moins d&amp;rsquo;une minute après avoir enregistré un article, il est publié sur le web sans action humaine.&lt;/p&gt;
&lt;p&gt;Il n&amp;rsquo;y a pour cela que 3 outils simples :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gitea comme dépôt Git ; qui déclenche une demande auprès d&amp;rsquo;un serveur distant (ici Gachette)&lt;/li&gt;
&lt;li&gt;Gachette qui reçoit la demande et lance un script de compilation/déploiement/traitement (bref, une action est menée)&lt;/li&gt;
&lt;li&gt;Nginx comme serveur Web pour diffuser les pages statiques ainsi générées&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;utilisation de Docker en sus améliore le côté réutilisable des outils : pour plusieurs sites statiques j&amp;rsquo;utilise la même image qui va compiler les fichiers puis les mettre à disposition sur le net.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;La difficulté réside cependant à notre capacité à créer des scripts&lt;/strong&gt; pour lancer les différentes actions sur le serveur. La ligne de commande et Bash sont de fidèles alliés !&lt;/p&gt;
&lt;h1 id=&#34;liens-utiles&#34;&gt;Liens utiles&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.github.com/fr/webhooks-and-events/webhooks/creating-webhooks&#34;&gt;Configurer un Webhook sur Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.gitlab.com/ee/user/project/integrations/webhooks.html#configure-a-webhook-in-gitlab&#34;&gt;Configure a webhook in Gitlab&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.gitea.io/en-us/usage/webhooks/&#34;&gt;Gitea Webhooks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
	    <title>Utilisation de træfik pour publier ses conteneurs Docker</title>
      <link>https://olivier.dossmann.net/2022/12/utilisation-de-tr%C3%A6fik-pour-publier-ses-conteneurs-docker/</link>
      <pubDate>Wed, 07 Dec 2022 07:16:11 +0100</pubDate>
      
      <guid>https://olivier.dossmann.net/2022/12/utilisation-de-tr%C3%A6fik-pour-publier-ses-conteneurs-docker/</guid>
      <description>&lt;h1 id=&#34;introduction&#34;&gt;Introduction&lt;/h1&gt;
&lt;p&gt;Il y a 8 ans &lt;a href=&#34;https://olivier.dossmann.net/2014/04/voici-docker-plus-l%C3%A9ger-et-plus-simple-quune-machine-virtuelle/&#34;&gt;je vous faisais découvrir Docker&lt;/a&gt;. À l&amp;rsquo;époque je ne savais pas encore à quel point cet outil très controversé serait utilisé !&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.docker.com/&#34;&gt;Docker&lt;/a&gt; est quasiment devenu un standard. Qu&amp;rsquo;on le veuille ou non il arrive souvent qu&amp;rsquo;on ait un conteneur Docker à lancer. On finit toujours par devoir lire la &lt;a href=&#34;https://docs.docker.com/get-started/&#34;&gt;documentation de Docker&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Avant de continuer sur la problématique du présent article, je tiens à vous signaler qu&amp;rsquo;il est important de savoir un minimum jouer avec les fichiers &lt;strong&gt;docker-compose.yml&lt;/strong&gt;. Cas échéant je crains que cet article ne vous soit d&amp;rsquo;aucune autre utilité que nourrir votre curiosité.&lt;/p&gt;
&lt;p&gt;Ainsi, un problème qui survient fréquemment quand on a crée nos images, nos conteneurs puis que nous lançons ces derniers : comment publier nos conteneurs afin qu&amp;rsquo;ils soient disponibles sur Internet ? En général la solution est d&amp;rsquo;utiliser un proxy (par exemple &lt;a href=&#34;https://nginx.org/en/docs/&#34;&gt;Nginx&lt;/a&gt;) qui va étudier les requêtes HTTP demandées sur le serveur puis rediriger vers le port choisi d&amp;rsquo;un conteneur Docker qu&amp;rsquo;on a lancé.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/logos/traefik.png&#34; alt=&#34;Image du logo de Traefik&#34;&gt;&lt;/p&gt;
&lt;p&gt;Dans cet article je vais rapidement expliquer pourquoi le choix de &lt;a href=&#34;https://traefik.io/&#34;&gt;Træfik&lt;/a&gt; plutôt que Nginx que j&amp;rsquo;utilisais avant ça. Ensuite j&amp;rsquo;expliquerai les configurations utilisées pour mettre à disposition nos conteneurs. Nous aborderons rapidement quelques points pour aller plus loin et finirons par une conclusion.&lt;/p&gt;
&lt;h1 id=&#34;choix-du-proxy&#34;&gt;Choix du proxy&lt;/h1&gt;
&lt;p&gt;Habituellement, pour mettre en place l&amp;rsquo;accès à des sites web que j&amp;rsquo;héberge, j&amp;rsquo;utilisais &lt;a href=&#34;https://httpd.apache.org/&#34;&gt;Apache&lt;/a&gt;, &lt;a href=&#34;https://www.nginx.com/&#34;&gt;Nginx&lt;/a&gt; ou encore &lt;a href=&#34;https://caddyserver.com/&#34;&gt;Caddy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Cependant il y avait pas mal de contraintes :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;chaque nouveau domaine demandait une configuration spécifique avec un fichier spécifique, des dossiers spécifiques,&lt;/li&gt;
&lt;li&gt;pour avoir un certificat SSL par &lt;a href=&#34;https://letsencrypt.org/&#34;&gt;Let&amp;rsquo;s Encrypt&lt;/a&gt;, il fallait parfois user d&amp;rsquo;intelligence, même une fois qu&amp;rsquo;on utilise &lt;a href=&#34;https://certbot.eff.org/&#34;&gt;Certbot&lt;/a&gt;, notamment pour redémarrer le serveur Web une fois les certificats renouvelés,&lt;/li&gt;
&lt;li&gt;quand on lançait un conteneur Docker, il valait mieux choisir un port spécifique, par exemple 8081, puis recopier ce nombre &lt;strong&gt;en dur&lt;/strong&gt; dans la configuration du serveur Web (Nginx dans mon cas) et je ne suis pas le plus imaginatif pour les numéros de ports qui se cumulaient…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ce qui est assez pénible. Très consommateur de temps.&lt;/p&gt;
&lt;p&gt;Étant donné que nous utilisons déjà les possibilités de Docker et Docker Compose, autant continuer en utilisant un outil ayant un backend avec Docker, non ?&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est là que Træfik entre en jeu :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;il permet &lt;strong&gt;avec quelques lignes dans vos fichiers docker-compose.yml&lt;/strong&gt; de &lt;strong&gt;définir le domaine à utiliser&lt;/strong&gt; pour tel ou tel conteneur Docker&lt;/li&gt;
&lt;li&gt;il s&amp;rsquo;occupe de &lt;strong&gt;faire la demande de certificat Let&amp;rsquo;s Encrypt et le renouvellement&lt;/strong&gt; de ces derniers&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;le lancement d&amp;rsquo;un conteneur Docker ne demande pas de relancer Træfik&lt;/strong&gt;, il y a une détection automatique des configurations&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;on laisse les ports choisis par Docker pour nos conteneurs&lt;/strong&gt;, ce qui nous évite d&amp;rsquo;en faire une gestion&lt;/li&gt;
&lt;li&gt;étant codé en Go (tout comme Docker et Docker Compose), Træfik fait partie du même monde, il est donc aussi rapide et compatible avec les outils utilisés&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pas besoin d&amp;rsquo;installer Træfik&lt;/strong&gt; : il sera un conteneur Docker comme le reste des services de la machine &amp;#x1f603;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Au final ce sont les contraintes des serveurs Web dont j&amp;rsquo;ai eu l&amp;rsquo;usage qui m&amp;rsquo;ont convaincu d&amp;rsquo;essayer Træfik. Voyons donc à quoi cela ressemble !&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ATTENTION&lt;/strong&gt; : Træfik ne résoud pas tous les problèmes du monde. Il va falloir expérimenter, recommencer plusieurs fois, plier son cerveau pour saisir de quoi il retourne. Parfois demander de l&amp;rsquo;aide. C&amp;rsquo;est un processus d&amp;rsquo;apprentissage qui en vaut la peine cependant !&lt;/p&gt;
&lt;h1 id=&#34;configuration-de-træfik&#34;&gt;Configuration de træfik&lt;/h1&gt;
&lt;p&gt;Pour mettre en place Træfik nous allons procéder comme la &lt;a href=&#34;https://doc.traefik.io/traefik/&#34;&gt;documentation de Træfik Proxy&lt;/a&gt; le propose :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;faire un &lt;strong&gt;docker-compose.yml&lt;/strong&gt; pour décrire notre service Træfik&lt;/li&gt;
&lt;li&gt;utiliser un fichier de configuration externe pour configurer le service : le fichier &lt;strong&gt;traefik.yml&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;demander à exposer les ports 80 et 443&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pour cela, voici le fichier &lt;strong&gt;docker-compose.yml&lt;/strong&gt; pour lancer le service Træfik :&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-docker-compose&#34; data-lang=&#34;docker-compose&#34;&gt;version: &amp;#39;3&amp;#39;

services:
    proxy:
      image: traefik:v2.8
      restart: always
      ports:
      	- 80:80
        - 443:443
      volumes:
        # pour que Træfik écoute les événements Docker : à adapter chez vous
        - /var/run/docker.sock:/var/run/docker.sock
        # Utilisation d&amp;#39;un fichier de configuration
        - ${PWD}/traefik.yml:/etc/traefik/traefik.yml
        # Mémorisation des certificats TLS (par Let&amp;#39;s Encrypt)
        - ${PWD}/acme.json:/acme.json
      labels:
        # Activation du tls
        - &amp;#34;traefik.http.routers.api.tls&amp;#34;
        # nawak, pour que les logs la boucle sur service error: port is missing
        - &amp;#34;traefik.http.services.nawak.loadbalancer.server.port=8484&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ce qui va monter le fichier local &lt;strong&gt;/var/run/docker.sock&lt;/strong&gt; pour discuter avec Docker : adaptez-le au fichier Socket de votre service Docker.&lt;/p&gt;
&lt;p&gt;Cela va utiliser le fichier &lt;strong&gt;traefik.yml&lt;/strong&gt; local qui contient notre configuration pour notre service Træfik.&lt;/p&gt;
&lt;p&gt;On stocke les données des certificats dans le fichier local &lt;strong&gt;acme.json&lt;/strong&gt; : pensez à faire &lt;code&gt;touch acme.json&lt;/code&gt; pour créer le fichier avant de lancer.&lt;/p&gt;
&lt;p&gt;Et voici le contenu de notre fichier &lt;strong&gt;traefik.yml&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-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;api&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;dashboard&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;true&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;# pour activer un tableau de bord&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;providers&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&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;network&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;traefik&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#60a0b0;font-style:italic&#34;&gt;# réseau de discussion entre les conteneurs et traefik&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;exposedByDefault&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;false&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;# n&amp;#39;active pas les conteneurs par défaut sur le web&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;entryPoints&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;web&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;address&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;: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;http&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;redirections&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;entryPoint&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;to&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;websecure&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#60a0b0;font-style:italic&#34;&gt;# pointe sur websecure plus bas (port 443 en somme)&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;scheme&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;https&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;websecure&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;address&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;:443&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;http&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;tls&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;# configuration par défaut&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;certResolver&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;letsencrypt&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#60a0b0;font-style:italic&#34;&gt;# pointe sur la config. letsencrypt plus bas&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:#bbb&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#062873;font-weight:bold&#34;&gt;traefik&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;# adresse pour le dashboard ;-)&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;address&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;:8080&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;certificatesResolvers&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;letsencrypt&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;acme&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;email&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;mon-courriel@domaine.tld&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;storage&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;/acme.json&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;httpChallenge&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;# le type utilisé pour valider les certificats Let&amp;#39;s Encrypt&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;entryPoint&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;web&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;Je me suis permis de commenter un peu partout pour savoir de quoi il retourne.&lt;/p&gt;
&lt;p&gt;Sachez qu&amp;rsquo;il existe aussi une méthode pour créer un fichier sur lequel Traefik va lire régulièrement pour mettre à jour sa configuration. Peut-être ferais-je un autre article sur ce sujet un jour. Petite piste : c&amp;rsquo;est le &lt;a href=&#34;https://doc.traefik.io/traefik/providers/file/&#34;&gt;&lt;em&gt;Provider&lt;/em&gt; nommé &lt;strong&gt;file&lt;/strong&gt;&lt;/a&gt; qui permet de faire ça.&lt;/p&gt;
&lt;p&gt;Une fois configuré, les autres conteneurs Docker que nous lançons n&amp;rsquo;ont plus besoin que des lignes suivantes dans &lt;strong&gt;leur fichier docker-compose.yml&lt;/strong&gt; :&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-docker-compose&#34; data-lang=&#34;docker-compose&#34;&gt;labels:
  - &amp;#34;traefik.enable=true&amp;#34;
  - &amp;#34;traefik.http.routers.un-nom-de-service.rule=Host(`mon.domaine.com`)&amp;#34;
  - &amp;#34;traefik.http.routers.un-nom-de-service.entrypoints=websecure&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Au lancement de vos conteneurs via un fichier docker-compose.yml, Træfik lira les informations contenues dans &lt;strong&gt;labels&lt;/strong&gt; et tentera de les analyser puis utiliser à bon essien.&lt;/p&gt;
&lt;p&gt;Dans l&amp;rsquo;exemple donné ci-avant, on comprend que :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;trafik.enable : le service doit être publié par Traefik (car dans la configuration nous avions mis &lt;code&gt;exposedByDefault: false&lt;/code&gt;, donc pas de publication par défaut)&lt;/li&gt;
&lt;li&gt;traefik.http.routers.un-nom-de-service.rule=Host(`mon.domaine.com`) : pour votre service remplacez un-nom-de-service par ce que vous voulez. Et &lt;strong&gt;mon.domaine.com&lt;/strong&gt; par le domaine que vous détenez&lt;/li&gt;
&lt;li&gt;la dernière ligne ne sert qu&amp;rsquo;à indiquer quel entrée par défaut accepter/utiliser. En l&amp;rsquo;occurence celle nommée &lt;em&gt;websecure&lt;/em&gt; qui, dans notre configuration du fichier traefik.yml est configurée pour être disponible sur le port 443 avec un résolveur de certificat Let&amp;rsquo;s Encrypt&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Exemple de docker-compose.yml pour lancer un service :&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-docker-compose&#34; data-lang=&#34;docker-compose&#34;&gt;version: &amp;#39;3&amp;#39;

services:
    whoami:
      image: traefik/whoami
      labels:
        - &amp;#34;traefik.enable=true&amp;#34;
        - &amp;#34;traefik.http.routers.whoami.rule=Host(`whoami.domaine.com`)&amp;#34;
        - &amp;#34;traefik.http.routers.whoami.entrypoints=websecure&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Y aurait-il encore d&amp;rsquo;autres fonctionnalités sympas ?&lt;/p&gt;
&lt;h1 id=&#34;pour-aller-plus-loin&#34;&gt;Pour aller plus loin&lt;/h1&gt;
&lt;p&gt;Dans ce que j&amp;rsquo;ai pratiqué, voici quelques points à étudier pour aller plus loin :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;utilisation de &lt;a href=&#34;https://doc.traefik.io/traefik/https/acme/#dnschallenge&#34;&gt;Let&amp;rsquo;s Encrypt par challenge DNS&lt;/a&gt; qui permet de gérer les DNS de son fournisseur de domaine en direct. Par exemple pour Gandi il suffit de fournir la variable d&amp;rsquo;environnement GANDIV5_API_KEY&lt;/li&gt;
&lt;li&gt;utilisation d&amp;rsquo;un fichier externe avec &lt;code&gt;watch: true&lt;/code&gt; pour appliquer les changements dès modification du fichier&lt;/li&gt;
&lt;li&gt;utilisation de middleware pour une authentification basique&lt;/li&gt;
&lt;li&gt;activer un port, par exemple 8080 pour l&amp;rsquo;accès au tableau de bord&lt;/li&gt;
&lt;li&gt;dans certains cas où les services ne sont pas forcément dans des Docker, il peut être intéressant de fournir une IP et un port spécifique par un loadBalancer, Cf. &lt;a href=&#34;https://doc.traefik.io/traefik/routing/services/#servers&#34;&gt;https://doc.traefik.io/traefik/routing/services/#servers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Il y a beaucoup plus à découvrir avec Træfik. Je vous invite à &lt;a href=&#34;https://doc.traefik.io/traefik/&#34;&gt;lire la documentation&lt;/a&gt; qui est très riche et bien expliquée.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Utiliser Træfik a permis de réduire considérablement le temps de maintenance de mes services, que ce soit en terme de mises à jour, de renouvellement de certificats et d&amp;rsquo;organisation des dossiers/fichiers.&lt;/p&gt;
&lt;p&gt;Cependant qu&amp;rsquo;on se le dise, ce n&amp;rsquo;est pas exempt de quelques difficultés :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;il n&amp;rsquo;y a pas toujours des images Docker de vos services, il faut donc parfois fabriquer soi-même les conteneurs,&lt;/li&gt;
&lt;li&gt;la courbe d&amp;rsquo;apprentissage de Træfik est assez difficile,&lt;/li&gt;
&lt;li&gt;on se casse les méninges jusqu&amp;rsquo;à comprendre comment fournir un service sur Træfik&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si on fait l&amp;rsquo;effort d&amp;rsquo;apprendre Træfik et d&amp;rsquo;investir du temps, c&amp;rsquo;est surtout pour assurer la possibilité de connecter tout cela à un &lt;a href=&#34;https://doc.traefik.io/traefik/observability/metrics/overview/&#34;&gt;système de métriques&lt;/a&gt;, pouvoir faire de la journalisation, vérifier l&amp;rsquo;état de santé des serveurs, etc.&lt;/p&gt;
&lt;p&gt;Il y a de quoi faire !&lt;/p&gt;
</description>
    </item>
    
    <item>
	    <title>Cron sous Docker avec Alpine</title>
      <link>https://olivier.dossmann.net/2022/10/cron-sous-docker-avec-alpine/</link>
      <pubDate>Wed, 12 Oct 2022 21:41:39 +0200</pubDate>
      
      <guid>https://olivier.dossmann.net/2022/10/cron-sous-docker-avec-alpine/</guid>
      <description>&lt;h1 id=&#34;introduction&#34;&gt;Introduction&lt;/h1&gt;
&lt;p&gt;Chose promie, chose due ! J&amp;rsquo;écris un article sur mes pérégrinations en informatique.&lt;/p&gt;
&lt;p&gt;Cette fois, je fais suite à &lt;a href=&#34;https://olivier.dossmann.net/2022/09/%C3%A9tat-des-lieux-2022/&#34;&gt;l&amp;rsquo;état des lieux 2022 de mon espace numérique&lt;/a&gt;. Certains de mes services/sites nécessitent régulièrement d&amp;rsquo;être mis à jour. Pour cela je souhaite utiliser &lt;strong&gt;Cron, un service sous GNU/Linux qui permet de planifier le lancement de script(s) à des fréquences définies&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Comme je souhaite utiliser Docker, je me suis demandé s&amp;rsquo;il était possible de créer un service dédié avec Cron, Docker et Alpine.&lt;/p&gt;
&lt;p&gt;Cet article explique quelques règles que j&amp;rsquo;ai dû suivre pour y parvenir. Il vous faudra a minima connaître Docker, voire Docker Compose pour comprendre quelque chose. À la rigueur vous connaissez déjà Cron et souhaitez l&amp;rsquo;utiliser sous Docker.&lt;/p&gt;
&lt;p&gt;Nous allons d&amp;rsquo;abord réflechir sur le sujet. Puis nous utiliserons l&amp;rsquo;exemple d&amp;rsquo;un site pour expliquer la solution choisie avant de conclure sur cette histoire.&lt;/p&gt;
&lt;p&gt;Pour les pressés, j&amp;rsquo;ai fais un chapitre « En bref » à la fin de cet article.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/objets/montre.jpg&#34; alt=&#34;Montre de poignet avec un stylo&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Photo trouvée sur le &lt;a href=&#34;https://flickr.com/photos/ducly/&#34;&gt;profil de Duc Ly sur Flickr&lt;/a&gt;&lt;/em&gt; sous licence CC BY-SA 2.0.&lt;/p&gt;
&lt;h1 id=&#34;réflexion-sur-le-sujet&#34;&gt;Réflexion sur le sujet&lt;/h1&gt;
&lt;p&gt;Ce que nous souhaitons faire, c&amp;rsquo;est lancer un service, par exemple &lt;strong&gt;almanax&lt;/strong&gt;, et le mettre à jour régulièrement avec une tâche dans le service &lt;strong&gt;cron&lt;/strong&gt;. Je vais expliquer un peu ma réflexion, si vous voulez entrer plus rapidement dans le vif du sujet, rendez-vous au chapitre suivant.&lt;/p&gt;
&lt;p&gt;Tout d&amp;rsquo;abord il faut savoir que &lt;strong&gt;l&amp;rsquo;environnement choisi est Docker&lt;/strong&gt;. Un système qui permet, &lt;strong&gt;à partir d&amp;rsquo;une image&lt;/strong&gt; de &lt;strong&gt;générer plusieurs conteneurs&lt;/strong&gt; ayant des points de montage différents pour changer les données qui s&amp;rsquo;y trouvent.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://docs.docker.com/develop/dev-best-practices/&#34;&gt;Docker propose plusieurs bonnes pratiques&lt;/a&gt;, parmi lesquelles :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ne lancer qu&amp;rsquo;un seul processus/service dans chaque conteneur&lt;/li&gt;
&lt;li&gt;réutiliser les images ou les parties d&amp;rsquo;images au maximum pour réduire à la fois la maintenance des images/conteneurs, le travail effectué et la place système utilisée pour les images de base&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sachant que nous ne lançons qu&amp;rsquo;un seul processus par conteneur Docker, et que je souhaite utiliser Cron, je vais devoir lancer cron dans un autre service. Concrètement, Docker propose Docker Compose qui est un outil permettant de lancer plusieurs services à la fois, avec des dépendances entre eux (si besoin), une description des points de montage, des commandes à lancer sur chaque service, les ports ouverts, etc.&lt;/p&gt;
&lt;p&gt;On peut également choisir l&amp;rsquo;image qu&amp;rsquo;on souhaite utiliser pour chaque service.&lt;/p&gt;
&lt;p&gt;Certes nous allons lancer Cron dans un service à part, pour lancer les scripts que notre autre service a besoin pour mettre à jour ce dernier - je pense notamment à un script qui recompile et reconstitue mes pages webs statiques -, mais nous allons devoir avoir accès à notre service &lt;strong&gt;almanax&lt;/strong&gt; qui contient la logique principale du site.&lt;/p&gt;
&lt;p&gt;Pour cela, l&amp;rsquo;idée est de modifier l&amp;rsquo;image de &lt;strong&gt;almanax&lt;/strong&gt; pour qu&amp;rsquo;elle contienne elle aussi &lt;strong&gt;cron&lt;/strong&gt;. Ainsi on pourra lancer la même image sous Docker Compose, avec une commande de lancement différente.&lt;/p&gt;
&lt;p&gt;On utilise des services Docker. Chacun ayant déjà leur propre image sous Alpine. Ainsi, chaque image possède déjà Cron inclut dans Alpine.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;allais dire qu&amp;rsquo;une image vaut mieux que 1 000 mots, mais là nous allons donner un exemple avec Docker Compose pour comprendre de quoi il s&amp;rsquo;agit.&lt;/p&gt;
&lt;h1 id=&#34;mise-en-place-exemple-avec-lalmanax&#34;&gt;Mise en place, exemple avec l&amp;rsquo;Almanax&lt;/h1&gt;
&lt;p&gt;Peut-être le savez-vous déjà : j&amp;rsquo;ai crée une page statique qui liste une quinzaine de quêtes de l&amp;rsquo;Almanax dans un jeu nommé Dofus.&lt;/p&gt;
&lt;p&gt;Cet outil est un de mes services fourni aux utilisateurs, mais également &lt;a href=&#34;https://github.com/blankoworld/dofus-almanax&#34;&gt;un projet Open Source, dofus-almanax que je fournis via Github&lt;/a&gt;. C&amp;rsquo;est dans ce dépôt Github que vous trouverez la plupart des fichiers nécessaires au bon lancement d&amp;rsquo;un service Cron que nous allons décrire.&lt;/p&gt;
&lt;p&gt;On va étudier le fichier docker-compose.yml 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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;version: &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;3&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;services:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  generator:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    build: .
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    image: dofus-almanax:0.2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    volumes:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - almanax_public:/opt/almanax/public:rw
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - almanax_data:/opt/almanax/dl:rw
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  web:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    image: caddy:2-alpine
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    restart: always
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    depends_on:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - generator
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    volumes:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - almanax_public:/usr/share/caddy:ro
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#70a0d0&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#bb60d5&#34;&gt;PWD&lt;/span&gt;&lt;span style=&#34;color:#70a0d0&#34;&gt;}&lt;/span&gt;/Caddyfile:/etc/caddy/Caddyfile
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ports:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - 8888:80
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  cron:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    image: dofus-almanax:0.2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    restart: always
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    entrypoint: /usr/sbin/crond
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    command: &lt;span style=&#34;color:#666&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;-f&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;-l&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;2&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;-L&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;/dev/stdout&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    volumes:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - almanax_public:/opt/almanax/public:rw
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - almanax_data:/opt/almanax/dl:rw
&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;volumes:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  almanax_public:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  almanax_data:
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Nous avons 3 services :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;generator : qui génère le site web au lancement, suite à quoi il s&amp;rsquo;éteint,&lt;/li&gt;
&lt;li&gt;web : un service pour mettre à disposition les fichiers statiques générés par &lt;strong&gt;generator&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;cron : un service pour mettre à jour régulièrement les fichiers statiques.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La particularité de la solution :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;generator&lt;/strong&gt; et &lt;strong&gt;cron&lt;/strong&gt; utilisent la même image : dofus-almanax:0.2&lt;/li&gt;
&lt;li&gt;ces deux services n&amp;rsquo;ont cependant pas la même commande au lancement : l&amp;rsquo;un prend la commande par défaut de l&amp;rsquo;image dofus-almanax:0.2, l&amp;rsquo;autre lance spécifiquement cron&lt;/li&gt;
&lt;li&gt;pour le service &lt;strong&gt;cron&lt;/strong&gt;, il spécifie avec le mot clé &lt;strong&gt;entrypoint&lt;/strong&gt; d&amp;rsquo;utiliser &lt;strong&gt;/usr/sbin/crond&lt;/strong&gt; (chemin absolu du binaire sous Alpine) et donne les paramètres &lt;code&gt;-f -l 2 -L /dev/stdout&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Que font les paramètres ?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-f&lt;/code&gt; définit de lancer le service en &lt;code&gt;foreground&lt;/code&gt;, nécessaire sous Docker, sinon cela ne fonctionne pas&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-l 2&lt;/code&gt; définit un niveau de journalisation, habituellement c&amp;rsquo;est 8 (Cf. &lt;a href=&#34;https://unix.stackexchange.com/a/496741&#34;&gt;une explication des niveaux crond sous Stackoverflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-L /dev/stdout&lt;/code&gt; permet d&amp;rsquo;avoir une sortie à l&amp;rsquo;écran dans Docker Compose&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ça, c&amp;rsquo;est les éléments de base. Cependant comment fonctionne la mise à jour, la configuration de cette dernière, etc.?&lt;/p&gt;
&lt;h1 id=&#34;fonctionnement-de-cron-dans-limage-dofus-almanax02&#34;&gt;Fonctionnement de Cron dans l&amp;rsquo;image dofus-almanax:0.2&lt;/h1&gt;
&lt;p&gt;Nous l&amp;rsquo;avions dit, l&amp;rsquo;idée est de tout mettre dans l&amp;rsquo;image &lt;strong&gt;dofus-almanax:0.2&lt;/strong&gt; (à la fois nos scripts, nos fichiers &lt;strong&gt;et&lt;/strong&gt; crond). Mais comment configurer le service Cron pour lui indiquer la fréquence à laquelle mettre à jour et comment mettre à jour nos fichiers ?&lt;/p&gt;
&lt;p&gt;Regardons l&amp;rsquo;image Docker, écrite sous le fichier Dockerfile 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-Dockerfile&#34; data-lang=&#34;Dockerfile&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;FROM&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;alpine:3.16&lt;/span&gt;&lt;span style=&#34;&#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;&#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;RUN&lt;/span&gt; apk update &lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#4070a0;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    apk add --no-cache &lt;span style=&#34;color:#4070a0;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        py3-lxml &lt;span style=&#34;color:#4070a0;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	py3-mechanize &lt;span style=&#34;color:#4070a0;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	tzdata &lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#4070a0;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    rm -rf /var/cache/apk/*&lt;span style=&#34;&#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;&#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;ENV&lt;/span&gt; &lt;span style=&#34;color:#bb60d5&#34;&gt;TZ&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;Europe/Paris&lt;span style=&#34;&#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;&#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;WORKDIR&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;/opt/almanax&lt;/span&gt;&lt;span style=&#34;&#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;&#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;VOLUME&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;/opt/almanax/public&lt;/span&gt;&lt;span style=&#34;&#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;VOLUME&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;/opt/almanax/dl&lt;/span&gt;&lt;span style=&#34;&#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;&#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;ENTRYPOINT&lt;/span&gt; [&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;python3&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;almanax_next_week.py&amp;#34;&lt;/span&gt;]&lt;span style=&#34;&#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;CMD&lt;/span&gt; [&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;/opt/almanax/public/index.html&amp;#34;&lt;/span&gt;]&lt;span style=&#34;&#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;&#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;COPY&lt;/span&gt; ./src /opt/almanax&lt;span style=&#34;&#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;COPY&lt;/span&gt; ./crontabs /etc/crontabs/root&lt;span style=&#34;&#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;&#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;RUN&lt;/span&gt; chown root:root /etc/crontabs/root &lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#4070a0;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    chmod &lt;span style=&#34;color:#40a070&#34;&gt;600&lt;/span&gt; /etc/crontabs/root&lt;span style=&#34;&#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;&#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;COPY&lt;/span&gt; ./cron_scripts/generate.sh /opt/generate&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Étudions ce fichier dans les grandes lignes concernant le service Cron notamment.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Nous partons d&amp;rsquo;une &lt;strong&gt;image Alpine 3.16 qui contient déjà crond&lt;/strong&gt; (le service Cron)&lt;/li&gt;
&lt;li&gt;Nous installons &lt;strong&gt;tzdata&lt;/strong&gt; qui nous permettra de choisir correctement un fuseau horaire&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ENV TZ=Europe/Paris&lt;/code&gt; définit notre fuseau horaire, histoire de lancer le script au moment où nous nous y attendons&lt;/li&gt;
&lt;li&gt;Le fichier le plus important, &lt;strong&gt;cronbtabs&lt;/strong&gt; est copié vers &lt;strong&gt;/etc/crontabs/root&lt;/strong&gt;, la ligne &lt;code&gt;COPY ./crontabs /etc/crontabs/root&lt;/code&gt; est déterminante pour remplacer le fichier du service crond d&amp;rsquo;Alpine Linux&lt;/li&gt;
&lt;li&gt;On copie aussi un script &lt;strong&gt;generate.sh&lt;/strong&gt; dont nous parlerons après&lt;/li&gt;
&lt;li&gt;Ce même fichier nécessite des permissions spécifiques, notifiée vers la fin du fichier Dockerfile :&lt;/li&gt;
&lt;/ol&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-Dockerfile&#34; data-lang=&#34;Dockerfile&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;RUN&lt;/span&gt; chown root:root /etc/crontabs/root &lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#4070a0;font-weight:bold&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    chmod &lt;span style=&#34;color:#40a070&#34;&gt;600&lt;/span&gt; /etc/crontabs/root&lt;span style=&#34;&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Que contient le fichier crontabs et generate.sh ?&lt;/p&gt;
&lt;h1 id=&#34;la-configuration-du-service-crond&#34;&gt;La configuration du service crond&lt;/h1&gt;
&lt;p&gt;Sous Alpine, le fichier  utilisé pour configurer les éléments à lancer par crond est &lt;strong&gt;/etc/crontabs/root&lt;/strong&gt;. Dans le chapitre précédent nous parlions de comment le remplacer, voici désormais son contenu :&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:#40a070&#34;&gt;5&lt;/span&gt;       &lt;span style=&#34;color:#40a070&#34;&gt;0&lt;/span&gt;       *       *       *       /bin/sh /opt/generate
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;Nous voyons que nous utilisons effectivement le script &lt;strong&gt;generate.sh&lt;/strong&gt; - qui a d&amp;rsquo;ailleurs été renommé &lt;strong&gt;generate&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Nous utilisons &lt;code&gt;/bin/sh&lt;/code&gt; devant notre script :
&lt;ul&gt;
&lt;li&gt;c&amp;rsquo;est un chemin absolu vers le binaire sh&lt;/li&gt;
&lt;li&gt;et nous utilisons sh, pas bash (car bash n&amp;rsquo;est, à défaut, pas délivré sous Alpine Linux)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Nous utilisons des caractères spécifique, formatés spécifiquement pour dire que nous lançons le service à 00h05 du matin&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Pour générer un fichier compatible avec crond, je vous suggère &lt;a href=&#34;https://crontab-generator.org/&#34;&gt;Crontab Generator&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Il va falloir appliquer quelques règles pour être sûr que tout cela fonctionne évidemment.&lt;/p&gt;
&lt;h1 id=&#34;en-bref-les-règles-à-appliquer-pour-crond&#34;&gt;En bref, les règles à appliquer pour crond&lt;/h1&gt;
&lt;p&gt;Voici les règles à retenir pour rédiger le fichier que le service crond va étudier :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;7 espaces entre chaque élément défini dans le crontab (le fichier se nomme ainsi)&lt;/li&gt;
&lt;li&gt;utiliser /bin/sh sous Alpine pour lancer un script, puis le nom de votre script&lt;/li&gt;
&lt;li&gt;ne pas mettre de point dans le script qu&amp;rsquo;on lance (mettre par exemple &lt;code&gt;generate&lt;/code&gt; au lieu de &lt;code&gt;generate.sh&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;le fichier &lt;code&gt;/etc/crontabs/root&lt;/code&gt; doit appartenir à root (&lt;code&gt;root:root&lt;/code&gt;) et avoir les permissions 600 (&lt;code&gt;chmod 600&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;utilisez &lt;code&gt;-L /dev/stdout&lt;/code&gt; sous votre Docker Compose pour avoir une sortie lisible et &lt;code&gt;-l 2&lt;/code&gt; pour plus de logs, mais &lt;code&gt;-l 8&lt;/code&gt; suffit&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ce qui fait déjà pas mal de choses à savoir !&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Bien que la réflexion ait été longue (et croyez moi j&amp;rsquo;ai pris plusieurs jours pour tester au fur et à mesure ce que je souhaitais), nous avons réuni les seules règles à appliquer pour que cela fonctionne, tout en trouvant une solution sympathique qui a plusieurs avantages :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;le service Cron accède à tous les fichiers communs de notre service initial&lt;/li&gt;
&lt;li&gt;le service Cron accède également à tous les scripts utiles de notre service initial&lt;/li&gt;
&lt;li&gt;il suffit de changer le script d&amp;rsquo;entrée de l&amp;rsquo;image initiale pour lancer Cron&lt;/li&gt;
&lt;li&gt;on a peu de changement à faire pour utiliser Cron finalement !&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;inconvénient reste cependant qu&amp;rsquo;il faut pouvoir modifier l&amp;rsquo;image initiale. Si nous n&amp;rsquo;avions pas la possibilité de faire ça, j&amp;rsquo;imagine qu&amp;rsquo;on devrait créer un point de montage commun entre le service initial et le service cron pour accéder à la fois aux fichiers mais aussi aux binaires… ce qui est bien plus complexe/casse-tête !&lt;/p&gt;
&lt;h1 id=&#34;liens-utiles&#34;&gt;Liens utiles&lt;/h1&gt;
&lt;p&gt;Je me suis grandement inspiré, pour mes pérégrinations sur Cron dans Alpine sous Docker par :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://devopsheaven.com/cron/docker/alpine/linux/2017/10/30/run-cron-docker-alpine.html&#34;&gt;https://devopsheaven.com/cron/docker/alpine/linux/2017/10/30/run-cron-docker-alpine.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://mixu.wtf/cron-in-docker-alpine-image/&#34;&gt;https://mixu.wtf/cron-in-docker-alpine-image/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://crontab-generator.org/&#34;&gt;Crontab Generator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
	    <title>Installation de PixelFed, une alternative à Instagram</title>
      <link>https://olivier.dossmann.net/2018/09/installation-de-pixelfed-une-alternative-%C3%A0-instagram/</link>
      <pubDate>Fri, 14 Sep 2018 23:34:55 +0200</pubDate>
      
      <guid>https://olivier.dossmann.net/2018/09/installation-de-pixelfed-une-alternative-%C3%A0-instagram/</guid>
      <description>&lt;h3 id=&#34;introduction&#34;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Peut-être le saviez-vous, ma curiosité m&amp;rsquo;a amenée à parcourir les réseaux sociaux. Ainsi &lt;a href=&#34;https://herds.eu/bl4n&#34; title=&#34;Découvrir mon profil&#34;&gt;je réside sur GNU Social&lt;/a&gt;, un réseau alternatif. Àla Twitter. Mais &lt;a href=&#34;https://fr.wikipedia.org/wiki/Red%C3%A9centralisation_d%27Internet&#34; title=&#34;En savoir plus sur la décentralisation d&#39;Internet&#34;&gt;décentralisé&lt;/a&gt;. Depuis début 2018, ce réseau évolue rapidement. De nouvelles applications basées sur celui-ci fleurissent :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://joinmastodon.org/&#34; title=&#34;Découvrir Mastodon et rejoindre une instance&#34;&gt;Mastodon&lt;/a&gt; : encore meilleur que Twitter !&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://joinpeertube.org/fr/home/&#34; title=&#34;En apprendre plus sur PeerTube et rejoindre une instance&#34;&gt;PeerTube&lt;/a&gt; : YouTube sans la censure&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://join.funkwhale.audio/&#34; title=&#34;En savoir plus sur Funkwhale et rejoindre une instance&#34;&gt;Funkwhale&lt;/a&gt; : Groovshark chez soi, à partager en famille&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pixelfed.social/&#34; title=&#34;Page officielle du projet&#34;&gt;PixelFed&lt;/a&gt; : alternative à Instagram&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nous allons nous intéresser au dernier de la liste : &lt;strong&gt;PixelFed&lt;/strong&gt;, un outil pour publier et partager des photos. Un tutoriel plus accessible sur son installation manque cruellement sur le web, alors pourquoi ne pas se lancer ici ?&lt;/p&gt;
&lt;p&gt;Je vous expliquerai en plusieurs étapes ma procédure d&amp;rsquo;installation. Le logiciel n&amp;rsquo;est pas encore stable, je préfère donc en parler ici plutôt que sur &lt;a href=&#34;https://olivier.dossmann.net/wiki/&#34; title=&#34;Se rendre sur mon recueil d&#39;astuces&#34;&gt;mon recueil d&amp;rsquo;astuces&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/logos/pixelfed.gif&#34; alt=&#34;Logo de PixelFed : sorte de fleur à plusieurs pétales des couleurs de l&amp;rsquo;arc en ciel dont le centre forme un P blanc&#34; title=&#34;Logo de PixelFed qui passe d&#39;une version pixelisé à une version nette&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;avant-propos&#34;&gt;Avant-propos&lt;/h3&gt;
&lt;p&gt;Ce « tutoriel » est très probablement &lt;strong&gt;réservé à des personnes ayant un minimum d&amp;rsquo;assurance avec la ligne de commande&lt;/strong&gt; ; les serveurs et probablement d&amp;rsquo;autres compétences dont je ne me rends pas compte. La lecture sera probablement longue, prenez votre temps et achevez les tâches progressivement.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PixelFed est un outil récent&lt;/strong&gt; qui n&amp;rsquo;a pas été testé ni longtemps ni sur énormément d&amp;rsquo;instances. Je crois qu&amp;rsquo;il est sage de dire qu&amp;rsquo;il est &lt;strong&gt;réservé aux têtes brûlées&lt;/strong&gt;. Ces personnes qui souhaitent être à la fois « hype » mais se casser les dents sur des soucis. Cela m&amp;rsquo;est arrivé : j&amp;rsquo;ai mis plusieurs heures à trouver ce qui n&amp;rsquo;allait pas.&lt;/p&gt;
&lt;p&gt;Je ne serais en aucun cas tenu pour responsable de toute perte de données, de problèmes ou de catastrophe résultant de l&amp;rsquo;application des commandes de ce tutoriel. Vous êtes assez intelligents pour vous renseigner si le besoin s&amp;rsquo;en fait sentir. D&amp;rsquo;ailleurs un &lt;a href=&#34;https://webchat.freenode.net/?randomnick=1&amp;amp;channels=%23pixelfed&amp;amp;uio=d4&#34; title=&#34;Se connecter au canal IRC de PixelFed&#34;&gt;canal IRC pour PixelFed&lt;/a&gt; existe pour vous aider. Vous n&amp;rsquo;êtes pas seul, l&amp;rsquo;univers que nous connaissons est rempli d&amp;rsquo;aliens comme vous et moi :)&lt;/p&gt;
&lt;h3 id=&#34;prérequis&#34;&gt;Prérequis&lt;/h3&gt;
&lt;p&gt;Sur &lt;a href=&#34;https://github.com/pixelfed/pixelfed&#34; title=&#34;Se rendre sur le dépôt officiel de PixelFed&#34;&gt;la page du dépôt du projet&lt;/a&gt; on lit que &lt;strong&gt;l&amp;rsquo;application requièrt PHP supérieur ou égal à 7.1&lt;/strong&gt;. Pour &lt;a href=&#34;https://packages.debian.org/stretch/php&#34; title=&#34;Voir le paquet PHP pour Debian Stretch&#34;&gt;Debian c&amp;rsquo;est mort&lt;/a&gt;, à moins que vous soyez &lt;a href=&#34;https://olivier.dossmann.net/wiki/systeme/pinning_debian/&#34; title=&#34;Découvrir mes astuces pour le Pinning sous Debian/Ubuntu&#34;&gt;le roi du pinning&lt;/a&gt;. Pour Ubuntu, c&amp;rsquo;est déjà mieux : PHP 7.1 (sous bionic).&lt;/p&gt;
&lt;p&gt;Dans le présent tutoriel j&amp;rsquo;ai travaillé sur une &lt;strong&gt;machine possédant ArchLinux&lt;/strong&gt; et PHP 7.2. J&amp;rsquo;ai donc utilisé les éléments suivants :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;php, Cf. &lt;a href=&#34;https://wiki.archlinux.org/index.php/PHP&#34;&gt;https://wiki.archlinux.org/index.php/PHP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;php-fpm, Cf. &lt;a href=&#34;https://wiki.archlinux.org/index.php/nginx#PHP_implementation&#34;&gt;https://wiki.archlinux.org/index.php/nginx#PHP_implementation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;postgreSQL, Cf. &lt;a href=&#34;https://olivier.dossmann.net/wiki/services/postgres/&#34;&gt;https://olivier.dossmann.net/wiki/services/postgres/&lt;/a&gt; et &lt;a href=&#34;https://wiki.archlinux.org/index.php/PostgreSQL&#34;&gt;https://wiki.archlinux.org/index.php/PostgreSQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;redis, &lt;a href=&#34;https://wiki.archlinux.org/index.php/redis&#34;&gt;https://wiki.archlinux.org/index.php/redis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;git&lt;/li&gt;
&lt;li&gt;nginx, Cf. &lt;a href=&#34;https://wiki.archlinux.org/index.php/nginx&#34;&gt;https://wiki.archlinux.org/index.php/nginx&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;J&amp;rsquo;ai installé les paquets suivants :&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sudo pacman -S php php-fpm php-gd php-pgsql git postgresql redis
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Puis à la lecture du &lt;a href=&#34;https://github.com/pixelfed/pixelfed/blob/dev/README.md&#34; title=&#34;Lire le fichier README de PixelFed&#34;&gt;fichier README sur le dépôt git officiel de PixelFed&lt;/a&gt;, j&amp;rsquo;ai du installer plusieurs autres logiciels, y compris sur &lt;a href=&#34;https://wiki.archlinux.org/index.php/Arch_User_Repository&#34; title=&#34;Apprendre à utiliser les dépôts AUR d&#39;ArchLinux&#34;&gt;les dépôts AUR d&amp;rsquo;ArchLinux&lt;/a&gt; en utilisant l&amp;rsquo;outil &lt;a href=&#34;https://github.com/trizen/trizen&#34; title=&#34;Savoir comment installer l&#39;outil trizen&#34;&gt;trizen&lt;/a&gt; - que je recommande.&lt;/p&gt;
&lt;p&gt;Voici les logiciels supplémentaires :&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;trizen -S optipng jpegoptim pngquant gifsicle svgo composer
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Éditez également le fichier &lt;strong&gt;/etc/php/php.ini&lt;/strong&gt; et décommentez (enlever le &amp;ldquo;;&amp;rdquo;) devant les lignes suivantes :&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;extension=bcmath.so
extension=gd.so
extension=iconv.so
extension=pdo_pgsql.so
extension=pgsql.so
extension=zip.so
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Nous lancerons les différents services plus tard, passons déjà à l&amp;rsquo;installation de PixelFed.&lt;/p&gt;
&lt;h3 id=&#34;installation&#34;&gt;Installation&lt;/h3&gt;
&lt;p&gt;Nous vérifions que le dossier &lt;strong&gt;/srv/http/&lt;/strong&gt; existe :&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;sudo mkdir -p /srv/http
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;puis nous créeons le dossier &lt;em&gt;pixelfed&lt;/em&gt; et lançons l&amp;rsquo;installation des dépendances :&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:#007020&#34;&gt;cd&lt;/span&gt; /srv/http
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo git clone https://github.com/dansup/pixelfed.git
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#007020&#34;&gt;cd&lt;/span&gt; pixelfed
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;composer install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Le plus gros de l&amp;rsquo;installation est faite ! Faisons de la configuration avant le grand lancement !&lt;/p&gt;
&lt;h3 id=&#34;configuration&#34;&gt;Configuration&lt;/h3&gt;
&lt;p&gt;La configuration va se passer en quelques étapes :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;configuration d&amp;rsquo;un fichier pour &lt;em&gt;php-fpm&lt;/em&gt;, spécifique à PixelFed&lt;/li&gt;
&lt;li&gt;configuration du fichier &lt;strong&gt;.env&lt;/strong&gt; de PixelFed&lt;/li&gt;
&lt;li&gt;lancement de postgreSQL&lt;/li&gt;
&lt;li&gt;configuration d&amp;rsquo;une base de données pour postgreSQL&lt;/li&gt;
&lt;li&gt;ajout d&amp;rsquo;un fichier de service pour systemd afin de lancer &lt;em&gt;horizon&lt;/em&gt; pour PixelFed&lt;/li&gt;
&lt;li&gt;configuration de Nginx&lt;/li&gt;
&lt;li&gt;création d&amp;rsquo;une clé pour PixelFed&lt;/li&gt;
&lt;li&gt;création du lien sur les &lt;em&gt;storage&lt;/em&gt; de PixelFed&lt;/li&gt;
&lt;li&gt;modification des permissions du dossier &lt;strong&gt;/srv/http/pixelfed&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On crée le fichier &lt;strong&gt;/etc/php/php-fpm.d/pixelfed.conf&lt;/strong&gt; 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-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;[pixelfed]&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;group&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;listen&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;/run/php-fpm/php-fpm-pixelfed.sock&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;listen.owner&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;listen.group&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;pm&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;dynamic&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;pm.max_children&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;5&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;pm.start_servers&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;2&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;pm.min_spare_servers&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;1&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;pm.max_spare_servers&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Au cas où, on crée nous même le fichier &lt;strong&gt;/run/php-fpm/php-fpm-pixelfed.sock&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;sudo mkdir -p /run/php-fpm
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo touch /run/php-fpm/php-fpm-pixelfed.sock &lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo chown http:http /run/php-fpm/php-fpm-pixelfed.sock
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Rendons-nous dans le dossier PixelFed pour créer le fichier de configuration et l&amp;rsquo;éditer :&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:#007020&#34;&gt;cd&lt;/span&gt; /srv/http/pixelfed
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo cp .env.example .env
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;avec le contenu suivant :&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;APP_NAME=&amp;#34;Le plus terrible des noms d&amp;#39;instance que tu peux trouver&amp;#34;
APP_ENV=production
APP_DEBUG=false
APP_URL=http://tondomaine.tld

# Language configuration
#APP_LOCALE=fr
#APP_FALLBACK_LOCALE=fr

ADMIN_DOMAIN=&amp;#34;tondomaine.tld&amp;#34;
APP_DOMAIN=&amp;#34;tondomaine.tld&amp;#34;

LOG_CHANNEL=stack

DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=&amp;#34;pixelfed&amp;#34;
DB_USERNAME=&amp;#34;roidumonde&amp;#34;
DB_PASSWORD=&amp;#34;ilestdesnôootres,ilabusonverrecommeuxlesôÔtres&amp;#34;

BROADCAST_DRIVER=log
CACHE_DRIVER=redis
SESSION_DRIVER=redis
SESSION_LIFETIME=120
QUEUE_DRIVER=redis

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=smtp.tondomaine.tld
MAIL_PORT=587
MAIL_USERNAME=tonpseudo@tondomaine.tld
MAIL_PASSWORD=mot2passe
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=&amp;#34;contact@tondomaine.tld&amp;#34;
MAIL_FROM_NAME=&amp;#34;Le nom d&amp;#39;expéditeur que tu veux que les personnes voient&amp;#34;

SESSION_DOMAIN=&amp;#34;.tondomaine.tld&amp;#34;
SESSION_SECURE_COOKIE=true
API_BASE=&amp;#34;/api/1/&amp;#34;
API_SEARCH=&amp;#34;/api/search&amp;#34;

OPEN_REGISTRATION=true
RECAPTCHA_ENABLED=false
ENFORCE_EMAIL_VERIFICATION=false

MAX_PHOTO_SIZE=15000
MAX_CAPTION_LENGTH=150
MAX_ALBUM_LENGTH=4

MIX_PUSHER_APP_KEY=&amp;#34;${PUSHER_APP_KEY}&amp;#34;
MIX_PUSHER_APP_CLUSTER=&amp;#34;${PUSHER_APP_CLUSTER}&amp;#34;
MIX_APP_URL=&amp;#34;${APP_URL}&amp;#34;
MIX_API_BASE=&amp;#34;${API_BASE}&amp;#34;
MIX_API_SEARCH=&amp;#34;${API_SEARCH}&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Pour certaines variables vous trouverez des informations dans &lt;a href=&#34;https://laravel.com/docs/&#34; title=&#34;Se rendre sur la documentation de Laravel&#34;&gt;la documentation de Laravel&lt;/a&gt;, outil utilisé pour crée PixelFed.&lt;/p&gt;
&lt;p&gt;Puis on lance postgreSQL et on crée une base de données suivant les informations ajoutées dans le fichier de configuration précédent :&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;sudo systemctl start postgresql.service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo systemctl &lt;span style=&#34;color:#007020&#34;&gt;enable&lt;/span&gt; postgresql.service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo su - postgres
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;createuser roidumonde
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;createdb -O roidumonde -E UTF-8 pixelfed
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;psql pixelfed
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ALTER USER roidumonde WITH PASSWORD &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;ilestdesnôootres,ilabusonverrecommeuxlesôÔtres&amp;#39;&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-weight:bold&#34;&gt;\q&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&#34;&gt;exit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Maintenant on va créer le fichier de service systemd pour lancer &lt;strong&gt;horizon&lt;/strong&gt;. Éditez &lt;strong&gt;/etc/systemd/system/horizon.service&lt;/strong&gt; et mettez y ceci :&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;Service horizon pour PixelFed&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/http/pixelfed&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;php artisan horizon&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;on-failure&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;suivi de :&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;sudo systemctl daemon-reload
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Edit&lt;/strong&gt; : À la lecture d&amp;rsquo;&lt;a href=&#34;https://github.com/pixelfed/pixelfed/issues/1220&#34;&gt;un ticket sur Github qui m&amp;rsquo;a été signalé par raphgilles&lt;/a&gt;, le fichier &lt;strong&gt;/etc/systemd/system/horizon.service&lt;/strong&gt; peut ressembler à ceci :&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;Service horizon pour PixelFed&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;ExecStart&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;/usr/bin/php7.2 /srv/http/pixelfed/artisan horizon&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;on-failure&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;De là on édite le fichier &lt;strong&gt;/etc/nginx/nginx.conf&lt;/strong&gt; et on rajoute la section suivante sous la ligne :&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# HTTPS Server
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;avec :&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;tondomaine.tld&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;root&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;/srv/http/pixelfed/public&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.php&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;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;try_files&lt;/span&gt; &lt;span style=&#34;color:#bb60d5&#34;&gt;$uri&lt;/span&gt; &lt;span style=&#34;color:#bb60d5&#34;&gt;$uri/&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#bb60d5&#34;&gt;$is_args$args&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;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:#235388&#34;&gt;\.php$&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;try_files&lt;/span&gt; &lt;span style=&#34;color:#bb60d5&#34;&gt;$uri&lt;/span&gt; =&lt;span style=&#34;color:#40a070&#34;&gt;404&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;fastcgi_split_path_info&lt;/span&gt;  &lt;span style=&#34;color:#4070a0&#34;&gt;^(.+\.php)(.*)&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;fastcgi_pass&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;unix:/run/php-fpm/php-fpm-pixelfed.sock&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;fastcgi_index&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;index.php&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;include&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;fastcgi.conf&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;fastcgi_param&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;SCRIPT_FILENAME&lt;/span&gt; &lt;span style=&#34;color:#bb60d5&#34;&gt;$document_root$fastcgi_script_name&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;fastcgi_param&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;PATH_INFO&lt;/span&gt; &lt;span style=&#34;color:#bb60d5&#34;&gt;$fastcgi_path_info&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;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;Il n&amp;rsquo;y a plus qu&amp;rsquo;à lancer redis, générer une clé pour PixelFed, générer le lien vers le dossier &lt;em&gt;storage&lt;/em&gt;, migrer la base de données et changer les permissions du dossier :&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;sudo systemctl start redis.service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo systemctl &lt;span style=&#34;color:#007020&#34;&gt;enable&lt;/span&gt; redis.service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#007020&#34;&gt;cd&lt;/span&gt; /srv/http/pixelfed
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;php artisan key:generate
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;php artisan storage:link
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;php artisan migrate
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#007020&#34;&gt;cd&lt;/span&gt; /srv/http
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo chown http:http pixelfed -R
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Chaud bouillant pour tester si tout va bien ? C&amp;rsquo;est parti !&lt;/p&gt;
&lt;h3 id=&#34;ça-passe-ou-ça-casse-&#34;&gt;Ça passe ou ça casse !&lt;/h3&gt;
&lt;p&gt;Tout est prêt, il ne reste plus qu&amp;rsquo;à :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;lancer horizon&lt;/li&gt;
&lt;li&gt;lancer php-fpm&lt;/li&gt;
&lt;li&gt;lancer Nginx&lt;/li&gt;
&lt;li&gt;tout casser &amp;#x1f62d;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Faites :&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;sudo systemctl start horizon.service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo systemctl &lt;span style=&#34;color:#007020&#34;&gt;enable&lt;/span&gt; horizon.service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo systemctl start php-fpm.service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo systemctl &lt;span style=&#34;color:#007020&#34;&gt;enable&lt;/span&gt; php-fpm.service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo systemctl start nginx.service
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo systemctl &lt;span style=&#34;color:#007020&#34;&gt;enable&lt;/span&gt; nginx.service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Alors, si vous allez sur tondomaine.tld, tout fonctionne ?&lt;/p&gt;
&lt;h3 id=&#34;accéder-au-dashboard-admin&#34;&gt;Accéder au Dashboard admin&lt;/h3&gt;
&lt;p&gt;Au moment où j&amp;rsquo;ai écris ce tutoriel, le &lt;a href=&#34;https://github.com/pixelfed/pixelfed/issues/327&#34; title=&#34;Découvrir les détails du bug 327&#34;&gt;bug 327&lt;/a&gt; avait encore cours. Pour pallier à ce problème, j&amp;rsquo;ai lancé la commande 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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo mkdir -p /srv/http/pixelfed/storage/app/public/m &lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo chown http:http /srv/http/pixelfed/storage/app/public/m
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Et pour devenir administrateur, sachant que nous sommes le premier utilisateur (id : 1) à s&amp;rsquo;être enregistré :&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;sudo su - postgres
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;psql pixelfed
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;UPDATE users SET &lt;span style=&#34;color:#bb60d5&#34;&gt;is_admin&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;t&amp;#39;&lt;/span&gt; WHERE &lt;span style=&#34;color:#bb60d5&#34;&gt;id&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; 1;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#4070a0;font-weight:bold&#34;&gt;\q&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&#34;&gt;exit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Et vous voilà administrateur !&lt;/p&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Je dois avouer que l&amp;rsquo;installation est non seulement longue, mais compliquée. Le nombre de problèmes à régler est plus important que pour l&amp;rsquo;installation d&amp;rsquo;une autre application PHP que j&amp;rsquo;ai eu l&amp;rsquo;occasion d&amp;rsquo;utiliser.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai par exemple encore quelques soucis pour comprendre comment personnaliser les pages d&amp;rsquo;à propos, de licence, la page d&amp;rsquo;accueil, etc. sans casser mon installation et ses mises à jours. J&amp;rsquo;aimerais également savoir si le lien entre PixelFed et Redis fonctionne réellement, parce que d&amp;rsquo;après le Dashboard admin, Redis est inactif…&lt;/p&gt;
&lt;p&gt;Je suis pressé d&amp;rsquo;être à l&amp;rsquo;année prochaine pour voir ce que ce projet donnera ! Et peut-être aurons-nous une application mobile pour faciliter l&amp;rsquo;envoi de données ? Voire la possibilité d&amp;rsquo;utiliser AndStatus, Twidere ou Tusky pour envoyer nos belles images et nos têtes curieuses &amp;#x1f47d; .&lt;/p&gt;
</description>
    </item>
    
    <item>
	    <title>Les Rencontres Mondiales du Logiciel Libre à Strasbourg en 2018</title>
      <link>https://olivier.dossmann.net/2018/07/les_rencontres_mondiales_du_logiciel_libre_a_strasbourg_en_2018/</link>
      <pubDate>Wed, 18 Jul 2018 19:29:42 +0200</pubDate>
      
      <guid>https://olivier.dossmann.net/2018/07/les_rencontres_mondiales_du_logiciel_libre_a_strasbourg_en_2018/</guid>
      <description>&lt;h3 id=&#34;introduction&#34;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Peut-être vous souvenez-vous de mes récits et péripéties aux &lt;strong&gt;&lt;a href=&#34;https://fr.wikipedia.org/wiki/Rencontres_mondiales_du_logiciel_libre&#34; title=&#34;En savoir plus sur Wikipédia&#34;&gt;Rencontres Mondiales du Logiciels Libre&lt;/a&gt;&lt;/strong&gt; (ou &lt;strong&gt;RMLL&lt;/strong&gt;) ? Ou peut-être n&amp;rsquo;avez vous jamais entendu parler des RMLL ?&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est un évènement crée en 2000 et dont le lieu change chaque année : il passe de ville en ville. Le sujet principal est comme son nom l&amp;rsquo;indique : &lt;a href=&#34;https://fr.wikipedia.org/wiki/Logiciel_libre&#34; title=&#34;En savoir plus sur Wikipédia&#34;&gt;le Libre&lt;/a&gt;, c&amp;rsquo;est à dire les musiques libres, les logiciels libres, les vidéos libres, l&amp;rsquo;art libre, les prix libres, les plans libres pour confectionner des appareils, etc.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai pu me rendre aux RMLL de l&amp;rsquo;année &lt;a href=&#34;https://olivier.dossmann.net/2006/07/les_rmll_2006_a_vandoeuvre_les_nancy/&#34; title=&#34;Lire l&#39;article de mon retour d&#39;expérience aux RMLL 2006&#34;&gt;2006 (Nancy)&lt;/a&gt;, &lt;a href=&#34;https://olivier.dossmann.net/2009/07/les_rmll_2009_a_nantes/&#34; title=&#34;Lire l&#39;article de mon passage aux RMLL 2009 à Nantes&#34;&gt;2009 (Nantes)&lt;/a&gt;, 2010 (Bordeaux), &lt;a href=&#34;https://olivier.dossmann.net/2011/07/retour_de_conference_aux_rmll_2011_a_strasbourg/&#34; title=&#34;En savoir plus sur ma conférence présentée aux RMLL 2011 sur Nanoblogger&#34;&gt;2011 (Strasbourg)&lt;/a&gt;, 2012 (Genève), 2013 (Bruxelles) et 2018 (Strasbourg) ! Je vous propose de dire quelques mots sur les éléments que j&amp;rsquo;ai repérés, &lt;strong&gt;les différentes activités&lt;/strong&gt; dont j&amp;rsquo;ai entendu parler et celles &lt;strong&gt;auxquelles j&amp;rsquo;ai participées&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;[&lt;img src=&#34;https://olivier.dossmann.net/images/evenement/rmll/2018_goodies_mini.jpg&#34; alt=&#34;Ensemble des goodies obtenus à l&amp;rsquo;événement, que ça soit bière, gobelets, autocollants, T-shirt et tickets d&amp;rsquo;échange contre boissons&#34;&gt;](/images/evenement/rmll/2018_goodies.jpg&amp;quot; &amp;gt;}})&lt;/p&gt;
&lt;h3 id=&#34;bilan&#34;&gt;Bilan&lt;/h3&gt;
&lt;p&gt;Ça commence souvent comme ça : on lit &lt;a href=&#34;https://linuxfr.org/news/les-rmll-2018-strasbourg-arrivent-a-grand-pas&#34; title=&#34;Lire l&#39;annonce des RMLL 2018 sur LinuxFR&#34;&gt;une news sur LinuxFR&lt;/a&gt;, on tombe sur &lt;a href=&#34;https://2018.rmll.info/&#34; title=&#34;Visiter le site officiel des RMLL 2018&#34;&gt;le site très disruptif des RMLL 2018&lt;/a&gt; et on se rend compte qu&amp;rsquo;effectivement c&amp;rsquo;est dans notre ville. Et ils ont besoin d&amp;rsquo;aide !&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai donc - encore - participé à cet événement en tant que bénévole, visiteur, mais aussi coordinateur de la captation. Je tiens d&amp;rsquo;ailleurs à profiter de ce paragraphe pour &lt;strong&gt;remercier l&amp;rsquo;ensemble des personnes qui ont participé de prêt ou de loin à la réalisation de la captation durant les RMLL 2018&lt;/strong&gt;. Vous qui lisez ces lignes vous reconnaîtrez sûrement !&lt;/p&gt;
&lt;p&gt;Ce qui est particulièrement appréciable cette année :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;la &lt;strong&gt;proximité&lt;/strong&gt;. Nous en profitons bien plus quand c&amp;rsquo;est proche de chez soi !&lt;/li&gt;
&lt;li&gt;la bière était bonne. Cette année c&amp;rsquo;était &lt;strong&gt;&lt;a href=&#34;http://www.la-merciere.fr/&#34; title=&#34;Se rendre sur le site officiel de la bière La Mercière&#34;&gt;La Mercière&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;les &lt;strong&gt;T-shirt bénévoles - violets -&lt;/strong&gt; ont été si bien accueillis et appréciés que le staff a hésité à les vendre&lt;/li&gt;
&lt;li&gt;le &lt;strong&gt;site&lt;/strong&gt; a été tellement &lt;strong&gt;disruptif et décalé&lt;/strong&gt; par rapport à l&amp;rsquo;habitude des gens qu&amp;rsquo;il a souvent été critiqué. À mon sens il restera dans les esprits et c&amp;rsquo;est l&amp;rsquo;essentiel ! À noter qu&amp;rsquo;importe que le site plaise ou non, &lt;strong&gt;l&amp;rsquo;ensemble de la communication, des graphismes, des flyers, des affiches, des T-shirts, des marquages au sol, des pancartes ont été dans le même thème visuel&lt;/strong&gt;. C&amp;rsquo;est appréciable !&lt;/li&gt;
&lt;li&gt;il y a eu une &lt;strong&gt;réunion &lt;a href=&#34;http://chatons.org/&#34; title=&#34;En apprendre plus sur le projet des CHATONS&#34;&gt;CHATONS&lt;/a&gt;&lt;/strong&gt;, ce qui m&amp;rsquo;a permis de rencontrer des personnes que je ne connaissais que sur la liste de discussion&lt;/li&gt;
&lt;li&gt;il y a eu un &lt;strong&gt;concert de musique Libre&lt;/strong&gt; - que j&amp;rsquo;ai loupé&lt;/li&gt;
&lt;li&gt;la &lt;strong&gt;soirée jeux vidéos&lt;/strong&gt; au &lt;a href=&#34;https://www.shadok.strasbourg.eu/&#34; title=&#34;Visiter le site officiel de la Fabrique du Numérique strasbourgeoise&#34;&gt;Shadok, la Fabrique Numérique de Strasbourg&lt;/a&gt; a été sympathique et accessible aux plus jeunes (testée et approuvée par un enfant de 5 ans). Il y a même eu un &lt;strong&gt;bal&lt;/strong&gt; avec des &lt;strong&gt;danses&lt;/strong&gt; et un joueur de &lt;strong&gt;flûte&lt;/strong&gt; devant le bâtiment&lt;/li&gt;
&lt;li&gt;la &lt;strong&gt;lecture par la méthode de l&amp;rsquo;arpentage&lt;/strong&gt; a fait des émules : il s&amp;rsquo;agit de découper un livre en plusieurs sections et de faire lire à chacun du groupe une partie. Une fois la lecture terminée, chacun raconte ce qu&amp;rsquo;il a compris de sa lecture. On parcourt donc un livre assez rapidement.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/evenement/rmll/2018_chatons_stephanois.jpg&#34; alt=&#34;Autocollant du CHATONS stéphanois&#34;&gt;&lt;/p&gt;
&lt;p&gt;Là où &lt;strong&gt;les RMLL nous surprennent&lt;/strong&gt; souvent, c&amp;rsquo;est &lt;strong&gt;avec les enfants&lt;/strong&gt; : ils sont tout fou de venir regarder les huluberlus que nous sommes. Notamment au &lt;strong&gt;« village du Libre »&lt;/strong&gt; qui est un ensemble de stands avec des associations, des projets ou des groupes de personnes voulant présenter ce qu&amp;rsquo;ils font. C&amp;rsquo;est riche en conversations, en goodies et en autocollants. Ceux que vous voyez sur l&amp;rsquo;image d&amp;rsquo;illustration de cet article ont été récupérés durant l&amp;rsquo;évènement par mon enfant ! Sacrée bestiole ! Merci aux personnes des stands d&amp;rsquo;avoir été aussi généreux !&lt;/p&gt;
&lt;p&gt;Et pour le plaisir des enfants, on a même eu droit à des &lt;strong&gt;démonstrations de trajets de locomotives - alimentées par batterie USB -&lt;/strong&gt; sur des rails officiels, mais sans utiliser le protocole électrique propriétaire des rails (car oui apparemment si on envoie du courant dans les rails, ça ne donne rien). Sans l&amp;rsquo;appareil propriétaire aucun résultat. On arrête pas le progrès…&lt;/p&gt;
&lt;p&gt;Je crois avoir fait le tour des moments clés des RMLL 2018.&lt;/p&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Cette année a eu un &lt;a href=&#34;https://2018.rmll.info/fr/program/calendar/table&#34; title=&#34;Visionner le programme chargé des RMLL 2018&#34;&gt;programme très chargé&lt;/a&gt;, une période assez courte de préparation, des personnes investies et des dons curieux d&amp;rsquo;associations qui ne se sont jamais présentées à l&amp;rsquo;événement, comme &lt;a href=&#34;https://renewablefreedom.org/&#34; title=&#34;Visiter le site en anglais de Renewable Freedom Foundation&#34;&gt;Renewable Freedom Foundation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Côté captation, j&amp;rsquo;ai apprécié travailler aux côtés de &lt;a href=&#34;https://reflexlibre.net/&#34; title=&#34;Découvrir les services proposés par ljf au sujet de YunoHost&#34;&gt;ljf (de YunoHost)&lt;/a&gt;. Nous étions coordinateurs de la captation. C&amp;rsquo;est une expérience enrichissante qui continue puisqu&amp;rsquo;une fois les enregistrements effectués, il va falloir les passer en revue !&lt;/p&gt;
&lt;p&gt;Tout ceci a été formidable grâce :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;à la ville de Strasbourg&lt;/li&gt;
&lt;li&gt;aux personnes qui ont organisé les RMLL 2018 à Strasbourg&lt;/li&gt;
&lt;li&gt;aux bénévoles quels qu&amp;rsquo;ils soient&lt;/li&gt;
&lt;li&gt;à &lt;a href=&#34;https://passageenseine.fr/&#34; title=&#34;Visiter le site de l&#39;événement Pas Sages En Seine&#34;&gt;PSES&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;aux CHATONS&lt;/li&gt;
&lt;li&gt;aux visiteurs&lt;/li&gt;
&lt;li&gt;aux personnes que j&amp;rsquo;ai oubliées et qui mériteraient toute mon attention&lt;/li&gt;
&lt;li&gt;à mon enfant d&amp;rsquo;avoir judicieusement récupéré et partagé de nombreuses étiquettes et goodies, mais aussi d&amp;rsquo;avoir pu montrer que les bénévoles de 5 ans existent. J&amp;rsquo;ai aussi sourit en le voyant &lt;strong&gt;faire de la publicité pour sa Debian chérie alors même que son papa n&amp;rsquo;utilise pas ce système d&amp;rsquo;exploitation&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/evenement/rmll/2018_casquette_debian.jpg&#34; alt=&#34;Casquette bleue avec un logo Debian GNU/Linux noir&#34;&gt;&lt;/p&gt;
&lt;p&gt;Quoiqu&amp;rsquo;en disent les mauvaises langues, il y a de bons côtés aux événements. &lt;strong&gt;J&amp;rsquo;invite chaque personne qui lit cet article à s&amp;rsquo;intéresser aux événements du Libre qui se déroulent autour de chez elle&lt;/strong&gt; afin d&amp;rsquo;y participer. Il y a une véritable expérience humaine à faire. &lt;strong&gt;Soyez souriants et partagez !&lt;/strong&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
	    <title>Wekan, mon alternative à MyTinyTodo</title>
      <link>https://olivier.dossmann.net/2018/02/wekan-mon-alternative-%C3%A0-mytinytodo/</link>
      <pubDate>Wed, 21 Feb 2018 19:07:46 +0100</pubDate>
      
      <guid>https://olivier.dossmann.net/2018/02/wekan-mon-alternative-%C3%A0-mytinytodo/</guid>
      <description>&lt;h3 id=&#34;introduction&#34;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Pour encore beaucoup de personnes, s&amp;rsquo;organiser n&amp;rsquo;est pas une tâche facile. On commence par faire des pense-bête sur de petits papiers. Puis les notes s&amp;rsquo;accumulent et le bureau se retrouve complètement recouvert !&lt;/p&gt;
&lt;p&gt;Pour pallier à ce genre de problèmes, j&amp;rsquo;utilise &lt;a href=&#34;http://www.mytinytodo.net/&#34;&gt;MyTinyTodo&lt;/a&gt;. Cependant c&amp;rsquo;est un outil mono-utilisateur et la dernière version date de 2014.&lt;/p&gt;
&lt;p&gt;Je commence donc à tester plusieurs alternatives. Aujourd&amp;rsquo;hui je vais vous parler de l&amp;rsquo;une d&amp;rsquo;entre elles : &lt;a href=&#34;https://wekan.github.io/&#34;&gt;Wekan&lt;/a&gt;, un kanban Libre façon &amp;ldquo;Trello&amp;rdquo; (service de pense-bête en ligne).&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/lieux/PenseBete.jpg&#34; alt=&#34;Un bureau complètement recouvert par des pense-bêtes de couleur&#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/arrighi/&#34;&gt;profil de Michael Arrighi sur Flickr&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;présentation-de-wekan&#34;&gt;Présentation de Wekan&lt;/h3&gt;
&lt;p&gt;Wekan se base sur &lt;a href=&#34;https://fr.wikipedia.org/wiki/Kanban_(d%C3%A9veloppement)&#34;&gt;les kanban&lt;/a&gt;, un &lt;strong&gt;système de colonne et de lignes (appelées couloirs)&lt;/strong&gt; pour trier ses tâches.&lt;/p&gt;
&lt;p&gt;Par exemple on pourrait imaginer des colonnes &amp;ldquo;À faire&amp;rdquo;, &amp;ldquo;En cours&amp;rdquo;, &amp;ldquo;En attente&amp;rdquo; et &amp;ldquo;Terminées&amp;rdquo; pour trier ses tâches suivant leur état d&amp;rsquo;avancement. C&amp;rsquo;est vous qui choisissez !&lt;/p&gt;
&lt;p&gt;Ce logiciel utilise des technologies Web assez modernes, ce qui permet une &lt;strong&gt;utilisation agréable de l&amp;rsquo;interface. C&amp;rsquo;est assez intuitif&lt;/strong&gt; de manière générale, bien plus que MyTinyTodo ne l&amp;rsquo;est !&lt;/p&gt;
&lt;p&gt;Je pense d&amp;rsquo;ailleurs que ça vaut le coup de comparer un peu MyTinyTodo et Wekan pour comprendre ce que Wekan peut apporter.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/screenshots/wekan.png&#34; alt=&#34;Un aperçu écran de l&amp;rsquo;interface de Wekan sur un tableau d&amp;rsquo;exemple crée pour l&amp;rsquo;occasion&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;comparaison-succinte-des-deux-outils&#34;&gt;Comparaison succinte des deux outils&lt;/h3&gt;
&lt;p&gt;MyTinyTodo utilise &lt;a href=&#34;https://fr.wikipedia.org/wiki/Getting_Things_Done&#34;&gt;GTD&lt;/a&gt;, une technique qui « trie » les tâches par un degré d&amp;rsquo;importance (4 niveaux). Pour agir sur l&amp;rsquo;interface et changer rapidement quelques tâches de degré d&amp;rsquo;importance, c&amp;rsquo;est une torture parce qu&amp;rsquo;il faut les sélectionner une à une. Là où Wekan propose simplement de déplacer la tâche dans la colonne appropriée.&lt;/p&gt;
&lt;p&gt;En revanche, la &lt;strong&gt;méthode de Kanban&lt;/strong&gt; énnoncée auparavant sous Wekan &lt;strong&gt;implique que vous sachiez comment organiser vos tickets&lt;/strong&gt;. Alors que MyTinyTodo propose plutôt des catégories de tâches. Mais dont le déplacement n&amp;rsquo;est pas aussi simple qu&amp;rsquo;un glisser/déposer.&lt;/p&gt;
&lt;p&gt;MyTinyTodo est mono-utilisateur. Wekan multi-utilisateur, avec un partage des tâches/tableaux et des sections privées/publiques.&lt;/p&gt;
&lt;p&gt;MyTinyTodo consomme peu : 20Mo de mémoire vive à tout péter, avec une base SQLITE3 facile à sauvegarder. Tandis que Wekan utilise 120Mo de mémoire vive, utilise MongoDB qui utilise 20 Mo de mémoire vive et est embêtant à sauvegarder car il faut un script pour lancer la sauvegarde de la base (si on l&amp;rsquo;utilise dans un Docker c&amp;rsquo;est légèrement plus complexe).&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;était, dans les grandes lignes, ce qui diffère des deux outils. J&amp;rsquo;ai tout de même mon opinion sur l&amp;rsquo;outil Wekan, dont nous allons tout de suite parler.&lt;/p&gt;
&lt;h3 id=&#34;mon-expérience-de-wekan&#34;&gt;Mon expérience de Wekan&lt;/h3&gt;
&lt;p&gt;Wekan, est une brise fraîche pour la gestion des tâches car le glisser/déposer d&amp;rsquo;une colonne ou d&amp;rsquo;une ligne (ils appellent ça des couloirs) à l&amp;rsquo;autre est aisé. Ce qui implique moins de temps à trier et plus de temps pour réellement faire les tâches. C&amp;rsquo;est agréable.&lt;/p&gt;
&lt;p&gt;Seulement &lt;strong&gt;cet outil est de la folie furieuse&lt;/strong&gt; pour tout le reste :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;il consomme pas mal en mémoire vive (120Mo) et en processeur (CPU)&lt;/li&gt;
&lt;li&gt;supprimer une tâche n&amp;rsquo;est pas intuitif : il faut aller dans &amp;ldquo;plus&amp;rdquo; puis trouver un petit lien souligné nommé « Supprimer »&lt;/li&gt;
&lt;li&gt;supprimer un tableau ? Pas possible ! On peut l&amp;rsquo;archiver oui. Et plus tard, si vous êtes un guerrier, vous pouvez utiliser &lt;a href=&#34;https://github.com/wekan/wekan-cleanup&#34;&gt;wekan-cleanup&lt;/a&gt; (un script) pour nettoyer votre base MongoDB&lt;/li&gt;
&lt;li&gt;l&amp;rsquo;outil n&amp;rsquo;est pas disponible sur ARM en 32 bits. Notamment à cause de meteorJS qui est le framework utilisé pour développer l&amp;rsquo;outil&lt;/li&gt;
&lt;li&gt;pas encore de possibilité d&amp;rsquo;utiliser autre chose que la base de données MongoDB&lt;/li&gt;
&lt;li&gt;il utilise NodeJS. Sérieux, c&amp;rsquo;est assez galère de faire une installation propre sans exploser son propre système qui contient lui aussi du Javascript en pagaille&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Le produit final est certes agréable pour l&amp;rsquo;utilisateur, mais côté serveur il faut pallier aux problèmes cités.&lt;/p&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Vous l&amp;rsquo;aurez compris, &lt;strong&gt;je suis mitigé sur Wekan&lt;/strong&gt;. Je souhaite trouver un outil plus léger, disponible sur ARM, avec une interface web et une méthode simple et « raffinée » pour déplacer rapidement les tâches d&amp;rsquo;une priorité ou d&amp;rsquo;une catégorie à une autre. Peut-être que je cherche le mouton à 5 pattes, mais mon petit doigt me dit que je trouverai une solution pour « créer » un outil capable de saisir et organiser rapidement mes tâches et les accomplir plutôt qu&amp;rsquo;à perdre du temps à les gérer !&lt;/p&gt;
</description>
    </item>
    
    <item>
	    <title>Suivre la progression de ses jeux vidéos</title>
      <link>https://olivier.dossmann.net/2017/08/suivre_la_progression_de_ses_jeux_videos/</link>
      <pubDate>Sat, 12 Aug 2017 19:32:37 +0100</pubDate>
      
      <guid>https://olivier.dossmann.net/2017/08/suivre_la_progression_de_ses_jeux_videos/</guid>
      <description>&lt;h3 id=&#34;introduction&#34;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Précédemment &lt;a href=&#34;https://olivier.dossmann.net/2017/06/project-zero/#application-de-la-m%C3%A9thode-par-l-exemple&#34;&gt;je parlais de mon application de la méthode de Project Zero&lt;/a&gt; sur ma liste de jeux vidéos. Je réduis en effet ma liste de jeux en cours à 3 maximum par console. Ce qui me permet d&amp;rsquo;achever plus rapidement les jeux vidéos l&amp;rsquo;un après l&amp;rsquo;autre sans me disperser.&lt;/p&gt;
&lt;p&gt;Seulement voilà, la collection s&amp;rsquo;aggrandissant, il a fallu trouver un outil pour suivre facilement l&amp;rsquo;ensemble de mes jeux vidéos, triés par console, savoir lequel a été terminé, ceux qu&amp;rsquo;il me reste à finir, les jeux en cours, etc.&lt;/p&gt;
&lt;p&gt;Je vais donc vous faire part de mon expérience sur 2 outils qui permettent de gérer sa collection de jeux vidéos :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Backloggery (site web)&lt;/li&gt;
&lt;li&gt;My Game Collection (Android)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/humains/downloading_eye.jpg&#34; alt=&#34;Œil pris de très près avec une barre de chargement qui fait le tour de la pupille&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;backloggerycom&#34;&gt;Backloggery.com&lt;/h3&gt;
&lt;p&gt;Après quelques recherches sur le Web je suis tombé sur un site intéressant : &lt;a href=&#34;http://backloggery.com/&#34;&gt;Backloggery.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Il permet à un utilisateur de créer une liste de titres (jeux vidéos). Pour chacun d&amp;rsquo;eux, vous pouvez renseigner (liste non exhaustive) :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;le titre du jeu&lt;/li&gt;
&lt;li&gt;la console/système sur lequel il tourne&lt;/li&gt;
&lt;li&gt;votre progression parmi :
&lt;ul&gt;
&lt;li&gt;unfinished : jeu non terminé&lt;/li&gt;
&lt;li&gt;unplayed : pas encore joué&lt;/li&gt;
&lt;li&gt;beaten : jeu terminé&lt;/li&gt;
&lt;li&gt;completed : jeu terminé totalement&lt;/li&gt;
&lt;li&gt;mastered : jeu terminé avec un défi personnel fixé&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;votre avis de 1 à 5 (ou pas d&amp;rsquo;avis)&lt;/li&gt;
&lt;li&gt;si vous jouez actuellement à ce jeu ou non&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ce site permet également de créer sa liste de jeux vidéos souhaités. Il propose de noter le jeu comme détenu, à la maison, souscris par abonnement, des commentaires, des notes de progression, le nombre de succès accomplis, etc.&lt;/p&gt;
&lt;p&gt;Puis, une fois le détail de vos jeux enregistrés, le site fait une page de statistiques de vos jeux, comme &lt;a href=&#34;http://backloggery.com/MetalMan1230&#34;&gt;par exemple le profil de MetalMan1230 sur Backloggery&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ce que j&amp;rsquo;aime :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;un thème un peu rétro qui tient la route&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://backloggery.com/rules.php&#34;&gt;ses règles d&amp;rsquo;utilisation&lt;/a&gt; qui stipulent qu&amp;rsquo;aucune donnée à caractère personnel ne sera collectée. Au pire anonymisée.&lt;/li&gt;
&lt;li&gt;le côté simple pour la saisie des jeux, pas de chi-chi, tu entres le titre, la console et ton pourcentage d&amp;rsquo;accomplissement du jeu&lt;/li&gt;
&lt;li&gt;la page de statistiques est une très bonne idée car elle permet de visuellement comprendre notre état d&amp;rsquo;avancement&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ce que j&amp;rsquo;aime moins :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;le site n&amp;rsquo;est pas du tout mobile-friendly, c&amp;rsquo;est à dire qu&amp;rsquo;il ne s&amp;rsquo;adapte pas bien aux petits écran, c&amp;rsquo;est une galère.&lt;/li&gt;
&lt;li&gt;il n&amp;rsquo;y a pas d&amp;rsquo;API pour récupérer des infos de son compte (pour éventuellement créer une page web statique récapitulative)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Il n&amp;rsquo;en reste pas moins que c&amp;rsquo;est un site que je conseille vivement !&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/screenshots/backloggery_metalman1230_profile.png&#34; alt=&#34;Partie du profil de MetalMan1230 sur Backloggery&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;my-game-collection&#34;&gt;My Game Collection&lt;/h3&gt;
&lt;p&gt;Sur Android, il en est tout autrement : le Play Store propose tout un tas d&amp;rsquo;application, mais une d&amp;rsquo;entre elle semble se démarquer par sa richesse de fonctionnalités : &lt;a href=&#34;https://play.google.com/store/apps/details?id=com.tuyware.mygamecollection&#34;&gt;my-game-collection&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;idée de l&amp;rsquo;application : récupérer sa liste de jeux sur un nombre important de services comme Steam, Backloggery, HowLongToBeat, Collectorz, Desura, Itch.io, vgcollect, etc. afin d&amp;rsquo;en créer une liste à suivre.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;outil propose ensuite d&amp;rsquo;ajouter des tags à vos jeux pour les filtrer par la suite. Il gère aussi la collection d&amp;rsquo;amiibo, de Skylanders, de personnages Disney Infinity, etc.&lt;/p&gt;
&lt;p&gt;Voici les éléments que j&amp;rsquo;apprécie particulièrement :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;import de jeux parmi une liste bien fournie de site web&lt;/li&gt;
&lt;li&gt;pendant la synchronisation de notre liste avec une plateforme distante, on peut choisir au cas par cas de modifier les données du jeu vidéo tel qu&amp;rsquo;il apparaît dans notre liste (image de présentation, titre du jeu, tags utilisés pour l&amp;rsquo;œuvre, etc.). Si vous avez la flemme, il y a la synchronisation automatique&lt;/li&gt;
&lt;li&gt;avoir pensé aux figurines des jeux vidéos, comme pour Lego Dimensions&lt;/li&gt;
&lt;li&gt;gère aussi sa liste de consoles et d&amp;rsquo;accessoires&lt;/li&gt;
&lt;li&gt;le côté mobile est intéressant car on peut saisir à côté de sa collection sans déplacer le PC&lt;/li&gt;
&lt;li&gt;affichage - en utilisant le site HowLongToBeat - du nombre d&amp;rsquo;heure pour accomplir le jeu en totalité&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En revanche, je peux lister bon nombre de soucis :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;l&amp;rsquo;interface n&amp;rsquo;est pas simple à utiliser. C&amp;rsquo;est trop fourni donc on se retrouve avec de petits boutons, voire même avec des choses qui se chevauchent sans qu&amp;rsquo;on puisse appuyer sur le bouton situé derrière&lt;/li&gt;
&lt;li&gt;l&amp;rsquo;outil propose un compte premium afin de pouvoir bénéficier de toutes les possibilités, c&amp;rsquo;est compréhensible mais assez dommage&lt;/li&gt;
&lt;li&gt;la synchronisation des données ne fonctionne que dans un sens (on récupère, on envoie pas). Du coup ça reste moyen pour gérer ses jeux Backloggery…&lt;/li&gt;
&lt;li&gt;quand la base de données igdb.com n&amp;rsquo;est pas suffisante pour les informations d&amp;rsquo;un jeu, il faut utiliser GiantBomb.com, mais ça demande une clé API. Quand on y connaît pas grand chose, c&amp;rsquo;est juste impossible&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Je dois l&amp;rsquo;avouer, ce dernier outil ne correspond pas du tout à mes attentes, bien qu&amp;rsquo;il contienne la liste des Skylanders (qui me serait utile) mais aussi une récupération sur HowLongToBeat du temps approximatif pour terminer le jeu.&lt;/p&gt;
&lt;p&gt;Si vous avez la flemme d&amp;rsquo;utiliser un ordinateur pour gérer votre collection, utilisez cet outil, sinon ravisez-vous et continuez sur d&amp;rsquo;autres services prévus à cet effet.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/screenshots/mygamecollection.png&#34; alt=&#34;Écran de la liste des jeux vidéos détenus sous My Game Collection sous Android&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Après avoir eu du mal à trouver une application qui permette de suivre la progression pour chaque jeu vidéo détenu, je m&amp;rsquo;attendais à trouver quelque chose de plus basique que les outils présentés. Je reste donc étonné de ces derniers. Mais quelque peu déçu du manque de finition de ces applications.&lt;/p&gt;
&lt;p&gt;Dans l&amp;rsquo;idéal, et comme souvent, il faudrait que je crée mon propre outil pour correspondre à mes attentes. Mais qui a du temps pour ça ?&lt;/p&gt;
&lt;p&gt;Je vais donc rester sur une approche temporaire et double : utiliser Backloggery, exporter chaque fois vers My Game Collection pendant que je développerai un outil similaire ralliant le meilleur des deux dans un seul outil :)&lt;/p&gt;
</description>
    </item>
    
    <item>
	    <title>S&#39;organiser avec Lessy</title>
      <link>https://olivier.dossmann.net/2017/06/sorganiser-avec-lessy/</link>
      <pubDate>Fri, 30 Jun 2017 20:05:16 +0100</pubDate>
      
      <guid>https://olivier.dossmann.net/2017/06/sorganiser-avec-lessy/</guid>
      <description>&lt;h3 id=&#34;introduction&#34;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Ce n&amp;rsquo;est pas un secret, &lt;a href=&#34;https://olivier.dossmann.net/2013/07/pourquoi-suis-je-electroniquement-disperse/&#34;&gt;j&amp;rsquo;ai toujours été électroniquement dispersé&lt;/a&gt;. Toujours plein d&amp;rsquo;idées, peu de temps pour les accomplir et 1000 manières de résoudre des problèmes.&lt;/p&gt;
&lt;p&gt;Est-ce bon ou mal ? Ce billet ne permettra pas de répondre à cette question. En revanche j&amp;rsquo;ai peut-être trouvé une méthode pour avancer dans ses projets personnels sans perdre de vue l&amp;rsquo;ensemble des projets.&lt;/p&gt;
&lt;p&gt;Après une petite histoire sur la découverte - piquante - d&amp;rsquo;un outil, je vous présenterai ce dernier.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/nature/hyps_bullock.jpg&#34; alt=&#34;Capture de deux bullots sous l&amp;rsquo;eau, l&amp;rsquo;un de couleur rose claire, l&amp;rsquo;autre de couleur rose foncé&#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/steve_childs/&#34;&gt;profil de Steve Childs sur Flickr&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;la-découverte&#34;&gt;La découverte&lt;/h3&gt;
&lt;p&gt;Tout commence par &lt;a href=&#34;https://id-libre.org/blogigor/article123/veille-premiere-partie-de-juin-2017&#34;&gt;l&amp;rsquo;idée saugrenue d&amp;rsquo;iGor de partager partiellement ses découvertes&lt;/a&gt;. Et je ne l&amp;rsquo;en remercierai jamais assez ! Je découvre un lien vers un projet, une méthode, un outil pour gérer les idées saugrenues qui nous trottent dans la tête. Comme quoi partager, même en vrac, participe à l&amp;rsquo;évolution possible de son entourage &amp;#x1f624;.&lt;/p&gt;
&lt;p&gt;Je suis donc arrivé sur &lt;a href=&#34;https://marienfressinaud.fr/category/lessy.html&#34;&gt;un ensemble de billets présentant une méthode&lt;/a&gt;. Billets que vous n&amp;rsquo;avez pas besoin de lire puisque je tenterais de faire un résumé dans le paragraphe suivant. Mais rien ne vous empêche d&amp;rsquo;y faire un - grand - tour &amp;#x1f60f;.&lt;/p&gt;
&lt;p&gt;Ce qui m&amp;rsquo;a paru curieux sur le coup : &lt;a href=&#34;https://olivier.dossmann.net/2017/05/hesitation_sur_la_nintendo_switch/&#34;&gt;suite à l&amp;rsquo;acquisition récente de la Nintendo Switch™&lt;/a&gt; - notamment - je procédais à une méthode similaire pour ma gestion des jeux en cours.&lt;/p&gt;
&lt;p&gt;Je vous en parlerais après, place à la description de Lessy !&lt;/p&gt;
&lt;h3 id=&#34;découverte-de-la-méthode-lessy&#34;&gt;Découverte de la méthode Lessy&lt;/h3&gt;
&lt;p&gt;Je tiens avant tout à préciser que je vous partage ma compréhension de la méthode Lessy. Elle doit sûrement différer quelque peu de celle dont &lt;a href=&#34;https://marienfressinaud.fr/&#34;&gt;Marien Fressinaud&lt;/a&gt; décrit.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;outil développé par Marien est disponible sur Github : &lt;a href=&#34;https://github.com/marienfressinaud/lessy&#34;&gt;https://github.com/marienfressinaud/lessy&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Et disponible en ligne : &lt;a href=&#34;https://lessy.io/&#34;&gt;https://lessy.io/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Mais alors, Lessy, qu&amp;rsquo;est-ce ? Je dirais un &lt;strong&gt;ensemble de règles&lt;/strong&gt; :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;chaque fois qu&amp;rsquo;on a une &lt;strong&gt;idée de projet&lt;/strong&gt;, on la note sur un &lt;strong&gt;bout de papier&lt;/strong&gt; (ou en numérique) et on le dépose &lt;strong&gt;dans une boîte&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;si on veut travailler sur un projet on le sort de la boîte&lt;/li&gt;
&lt;li&gt;on ne travaille jamais à plus de 3 projets à la fois&lt;/li&gt;
&lt;li&gt;quand on sort un projet de la boîte, on se fixe une date maximum avant de remettre le projet dans la boîte. Ceci pour permettre à des projets qui n&amp;rsquo;avancent pas de retourner dans la boîte au profit d&amp;rsquo;autres projets&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ces règles impliquent qu&amp;rsquo;on peut travailler sur moins de 3 projets. Et que ne nous sommes pas obligés de finir le projet avant de le remettre dans la boîte.&lt;/p&gt;
&lt;p&gt;Ce que j&amp;rsquo;ai trouvé bluffant, c&amp;rsquo;est que j&amp;rsquo;utilisais une méthode similaire depuis quelques temps avec mes… jeux vidéos.&lt;/p&gt;
&lt;h3 id=&#34;application-de-la-méthode-par-lexemple&#34;&gt;Application de la méthode par l&amp;rsquo;exemple&lt;/h3&gt;
&lt;p&gt;Je vous le disais, suite à l&amp;rsquo;acquisition d&amp;rsquo;une console dernièrement, je n&amp;rsquo;arrivais plus à gérer le nombre de jeux en cours. Alors j&amp;rsquo;ai mis en place les quelques règles citées précédemment de la manière suivante :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;les jeux représentent les projets&lt;/li&gt;
&lt;li&gt;je mets donc tous les jeux dans une boîte (carton)&lt;/li&gt;
&lt;li&gt;je ne sors que 3 jeux maximum à la fois&lt;/li&gt;
&lt;li&gt;quand j&amp;rsquo;ai terminé d&amp;rsquo;avancer sur un jeu : je le remets dans le carton&lt;/li&gt;
&lt;li&gt;tout jeu terminé va sur une étagère&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Et petite différence avec la méthode :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pour chaque console je fais un carton&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Je gère ainsi &lt;strong&gt;3 jeux par console&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Quand je veux jouer, généralement je réfléchis en terme de console du moment plutôt que jeu du moment. Et je choisirai parmi les 3 jeux sortis celui que je préfère au moment où je veux jouer.&lt;/p&gt;
&lt;p&gt;Cela m&amp;rsquo;a déjà permis de mieux avancer sur les jeux vidéos, voire d&amp;rsquo;en terminer quelques uns. Ce qui ne m&amp;rsquo;était pas arrivé depuis des années !&lt;/p&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Bien que mon application de la méthode soit assez atypique, je dois dire que je suis très heureux d&amp;rsquo;avoir découvert Lessy.&lt;/p&gt;
&lt;p&gt;Je pensais qu&amp;rsquo;une RFC serait de bonne augure, qu&amp;rsquo;une bibliothèque pouvait être construire pour gérer ce type de gestion de &amp;ldquo;papiers dans une boîte&amp;rdquo;, mais finalement c&amp;rsquo;est tout aussi bien d&amp;rsquo;adapter selon ses besoins.&lt;/p&gt;
&lt;p&gt;Lessy va-t-il révolutionner votre gestion des priorités et la finalisation de vos projets ?&lt;/p&gt;
</description>
    </item>
    
    <item>
	    <title>Migrer son wiki de Dokuwiki à Hugo</title>
      <link>https://olivier.dossmann.net/2017/06/migrer-son-wiki-de-dokuwiki-%C3%A0-hugo/</link>
      <pubDate>Sun, 25 Jun 2017 11:08:23 +0100</pubDate>
      
      <guid>https://olivier.dossmann.net/2017/06/migrer-son-wiki-de-dokuwiki-%C3%A0-hugo/</guid>
      <description>&lt;h3 id=&#34;introduction&#34;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Il y a quelques mois &lt;a href=&#34;https://olivier.dossmann.net/2016/03/hugo_le_moteur_de_blog_statique_rapide_et_moderne/&#34; title=&#34;En apprendre plus sur ma migration vers Hugo&#34;&gt;je vous parlais de ma découverte d&amp;rsquo;Hugo, le moteur de site statique&lt;/a&gt;. J&amp;rsquo;en profitais pour faire la transition de mon blog vers Hugo. Mais aussi d&amp;rsquo;outils spécifiques comme &lt;a href=&#34;https://github.com/blankoworld/hugo-portal&#34;&gt;hugo-portal, un portail web&lt;/a&gt; de ma fabrication.&lt;/p&gt;
&lt;p&gt;Vous l&amp;rsquo;aurez compris, dans la continuité de ma démarche, je me devais de passer également mon wiki à ce formidable outil qu&amp;rsquo;est &lt;a href=&#34;http://gohugo.io/&#34;&gt;Hugo&lt;/a&gt;. Ceci pour simplifier ma chaîne de publication Web et n&amp;rsquo;avoir qu&amp;rsquo;un outil à maintenir.&lt;/p&gt;
&lt;p&gt;Nous verrons ici les étapes successives par lesquelles je suis passé pour obtenir un premier résultat :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;la recherche d&amp;rsquo;un outil de migration de Dokuwiki vers Hugo&lt;/li&gt;
&lt;li&gt;la recherche d&amp;rsquo;un thème Hugo spécialisé wiki&lt;/li&gt;
&lt;li&gt;mes impressions sur cette migration&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/objets/ombrelle_tournoyante.jpg&#34; alt=&#34;Ombrelle figée vue du dessus dont les contours et tout le reste du décor tournent sans fin en laissant une trace éphémère&#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/silkeremmery/&#34;&gt;profil de silkeremmery sur flickr&lt;/a&gt; sous licence cc by 2.0.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;outil-de-migration-de-dokuwiki--hugo&#34;&gt;Outil de migration de Dokuwiki → Hugo&lt;/h3&gt;
&lt;p&gt;Généralement, la première chose à faire quand on veut migrer depuis un outil vers un autre, c&amp;rsquo;est de regarder dans la documentation de ce dernier s&amp;rsquo;il existe un script de migration. Et Ô bonheur : &lt;a href=&#34;https://gohugo.io/tools/migrations/&#34;&gt;Hugo propose une page complète sur les outils de migration&lt;/a&gt;. Et plus encore : &lt;a href=&#34;https://github.com/wgroeneveld/dokuwiki-to-hugo&#34;&gt;un script pour Dokuwiki existe&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;En revanche, j&amp;rsquo;ai tenté de l&amp;rsquo;utiliser, et &lt;a href=&#34;https://github.com/blankoworld/dokuwiki-to-hugo&#34;&gt;j&amp;rsquo;ai dû modifier le script dokuwiki-to-hugo&lt;/a&gt;. Dans les grandes lignes j&amp;rsquo;ai :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ajouté le script main.py à la racine du projet (sinon ça ne fonctionnait pas comme la documentation le signalait) sans cela je n&amp;rsquo;obtenais aucun résultat&lt;/li&gt;
&lt;li&gt;ajouté la prise en compte du mot clé &amp;ldquo;this&amp;rdquo; qui semble apparaître à plusieurs endroit de mon Dokuwki. Mot clé utilisé pour la création de liens&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Avec ce script, on simplifie grandement la tâche de migration, car il suffit :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;de récupérer son dossier Dokuwiki contenant les pages, par exemple &lt;strong&gt;wiki/data/pages&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;de le copier quelque part sur notre disque local. Par exemple : &lt;strong&gt;/home/olivier/wiki&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;de lancer notre script dokuwiki-to-hugo (situé dans le répertoire /home/olivier/dokuwiki-to-hugo/) de la manière 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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python3 main.py -d /home/olivier/wiki/data/pages
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Vous obtenez un dossier &lt;strong&gt;/home/olivier/dokuwiki-to-hugo/output/home/od/projets/wiki/data/pages&lt;/strong&gt; qui contient des fichiers Markdown compatibles avec Hugo. La grande classe !&lt;/p&gt;
&lt;p&gt;Il ne reste plus qu&amp;rsquo;à ajouter un beau thème pour obtenir un wiki tout neuf !&lt;/p&gt;
&lt;h3 id=&#34;un-thème-wiki-pour-hugo&#34;&gt;Un thème wiki pour Hugo&lt;/h3&gt;
&lt;p&gt;Dans le même ordre d&amp;rsquo;idée que le paragraphe précédent, quand on cherche quelque chose de particulier sur un outil, on regarde dans la documentation et/ou sur le site web. Ça tombe bien, &lt;a href=&#34;https://themes.gohugo.io/&#34;&gt;Hugo propose une galerie de thèmes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Mon problème : Je ne vois rien qui soit dans l&amp;rsquo;esprit d&amp;rsquo;un wiki. Il n&amp;rsquo;y a &lt;strong&gt;même pas de tag wiki dans la liste des thèmes&lt;/strong&gt;. Évidemment il y a bien un &lt;a href=&#34;https://themes.gohugo.io/tags/documentation/&#34;&gt;tag documentation dans la liste de thèmes Hugo&lt;/a&gt;, mais ça ne ressemble pas vraiment à mon habitude de wiki.&lt;/p&gt;
&lt;p&gt;Je me suis donc improvisé créateur de thème Hugo avec les contraintes non-moins compliquées :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;de rendre le site responsive un maximum : qu&amp;rsquo;il soit utilisable sur mon mobile et sur mon desktop&lt;/li&gt;
&lt;li&gt;de rester le plus simple possible, dans l&amp;rsquo;esprit de Dokuwiki, voire assez proche&lt;/li&gt;
&lt;li&gt;de ne pas y passer énormément de temps&lt;/li&gt;
&lt;li&gt;de partager mon travail. Et qui sait, le proposer sur la galerie de thèmes Hugo ?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;J&amp;rsquo;ai donc créé &lt;a href=&#34;https://github.com/blankoworld/hugo_theme_adam_eve&#34;&gt;le thème Adam &amp;amp; Eve pour Hugo&lt;/a&gt;. Il peut se résumer à 2 types d&amp;rsquo;écran :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;la page d&amp;rsquo;accueil, qui affiche le titre de notre wiki et contient des liens vers du contenu qu&amp;rsquo;on veut partager&lt;/li&gt;
&lt;li&gt;une page spécifique, qui propose un retour vers l&amp;rsquo;accueil, un sommaire du contenu de notre page et le contenu de notre page&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Voici un aperçu d&amp;rsquo;une page spécifique sur laquelle on remarque notamment des encarts jaune et rouge que j&amp;rsquo;ai repris de certains modules Dokuwiki :&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://olivier.dossmann.net/images/screenshots/adam_eve_hugo_theme-00.png&#34;&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/screenshots/adam_eve_hugo_theme-00_mini.png&#34; alt=&#34;Page décrivant Minetest sur ma version en cours de migration&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;La page d&amp;rsquo;accueil ressemble plutôt à :&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://olivier.dossmann.net/images/screenshots/adam_eve_hugo_theme-01.png&#34;&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/screenshots/adam_eve_hugo_theme-01_mini.png&#34; alt=&#34;Page contenant des encarts jaunes et rouges que j&amp;rsquo;ai repris de certains modules Dokuwiki&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Et sous sa version mobile :&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/screenshots/adam_eve_hugo_theme-01_mobile.png&#34; alt=&#34;Page d&amp;rsquo;accueil du wiki apparaissant sur un téléphone mobile&#34;&gt;&lt;/p&gt;
&lt;p&gt;Ce thème ne ment pas, il reste dans &lt;strong&gt;son plus simple apparât&lt;/strong&gt; : celui d&amp;rsquo;Adam et Eve.&lt;/p&gt;
&lt;h3 id=&#34;mon-ressenti-sur-cette-migration&#34;&gt;Mon ressenti sur cette migration&lt;/h3&gt;
&lt;p&gt;Je ne vais pas le cacher, je reste mitigé sur la migration d&amp;rsquo;un Dockuwiki vers Hugo. Pour plusieurs raisons :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;suivant la taille de son wiki précédent, la migration prendra plus de temps. Je parle bien sûr de la relecture et le peaufinage. Dans mon cas : 375+ pages à vérifier. J&amp;rsquo;y suis encore à l&amp;rsquo;écriture de ces lignes…&lt;/li&gt;
&lt;li&gt;l&amp;rsquo;outil de migration n&amp;rsquo;est pas parfait, il ne gère pas les tableaux, certains morceaux de code qu&amp;rsquo;on a mis sur nos pages, la conversion des liens est loin d&amp;rsquo;être parfaite et parfois ça cafouille quand il y a plusieurs signes égal à la suite&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mais soyons positif : vous partez avec une épine de moins que moi, à savoir le thème wiki ! Soyez heureux de pouvoir &lt;strong&gt;enfin&lt;/strong&gt; profiter d&amp;rsquo;un si merveilleux thème wiki pour votre outil &amp;#x1f607;.&lt;/p&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;De nos jours, faut pas rêver, peu d&amp;rsquo;outils font les choses à votre place :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;j&amp;rsquo;ai dû compléter le script de migration Dokuwiki vers Hugo pour assurer les particularités de mon wiki&lt;/li&gt;
&lt;li&gt;j&amp;rsquo;ai dû créer mon propre thème wiki pour avoir quelque chose qui corresponde à mes attentes d&amp;rsquo;un wiki responsive simple&lt;/li&gt;
&lt;li&gt;j&amp;rsquo;ai passé - et passe encore - un temps fou à peaufiner et traiter mes anciennes pages pour avoir quelque chose de potable sur la nouvelle mouture&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C&amp;rsquo;est un bilan très mitigé. Mais &lt;strong&gt;j&amp;rsquo;ai migré mon Dokuwiki vers Hugo&lt;/strong&gt; &amp;#x1f604;. C&amp;rsquo;est le plus important. Maintenant que j&amp;rsquo;ai Hugo pour mon blog, et pour mon wiki, je vais pouvoir passer pas mal de temps sur le contenu. Au bienfait des visiteurs !&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;EDIT&lt;/strong&gt; : à la mi-août 2017 (mais en ayant passé peu de temps dessus), la migration n&amp;rsquo;est toujours pas complète : je remanie sans cesse la structure et le contenu de mes pages wiki. Il sera donc réellement en ligne tardivement cette année !&lt;/p&gt;
</description>
    </item>
    
    <item>
	    <title>Gitea, service git sans prise de tête issu de Gogs</title>
      <link>https://olivier.dossmann.net/2017/04/gitea-service-git-sans-prise-de-t%C3%AAte-issu-de-gogs/</link>
      <pubDate>Fri, 07 Apr 2017 17:33:55 +0200</pubDate>
      
      <guid>https://olivier.dossmann.net/2017/04/gitea-service-git-sans-prise-de-t%C3%AAte-issu-de-gogs/</guid>
      <description>&lt;h3 id=&#34;introduction&#34;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Que ce soit au travail comme à la maison, j&amp;rsquo;utilise &lt;a href=&#34;https://fr.wikipedia.org/wiki/Git&#34;&gt;Git, le logiciel de gestion de version décentralisé&lt;/a&gt;, au quotidien. J&amp;rsquo;ai plusieurs projets, parfois publics, parfois privés.&lt;/p&gt;
&lt;p&gt;Jusqu&amp;rsquo;à maintenant, pour gérer mes dépôts, j&amp;rsquo;utilisais un mix de :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/&#34;&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://bitbucket.org/&#34;&gt;Bitbucket&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;et le petit nouveau que j&amp;rsquo;utilise chez &lt;a href=&#34;https://framagit.org/&#34;&gt;Framasoft&lt;/a&gt; :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/&#34;&gt;Gitlab&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Chacun de ces outils apporte quelque chose, que ce soit l&amp;rsquo;outil de gestion des tickets, un wiki attaché, des dépôts (public/gratuit) publics, un environnement d&amp;rsquo;intégration continu, etc. Mais utiliser ces outils nous fait dépendre d&amp;rsquo;une entreprise, et à tout moment le service - gratuit jusque là - peut couper.&lt;/p&gt;
&lt;p&gt;Je me suis dit qu&amp;rsquo;il était temps d&amp;rsquo;héberger une interface à mes dépôts (avec copie de sauvegarde en prime).&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/the.jpg&#34; alt=&#34;Image d&amp;rsquo;une tasse de thé ayant 3 touches de claviers qui flottent et dont les caractères sont T, E et A&#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/chumsdock/&#34;&gt;profil de chumsdock sur Flickr&lt;/a&gt;&lt;/em&gt; sous licence CC BY-SA 2.0.&lt;/p&gt;
&lt;h3 id=&#34;comment-en-être-arrivé-au-choix-de-gitea-&#34;&gt;Comment en être arrivé au choix de Gitea ?&lt;/h3&gt;
&lt;p&gt;Dans mes possibles il y avait :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gitlab : récent, écrit à l&amp;rsquo;aide de &lt;em&gt;Ruby On Rails&lt;/em&gt; et &lt;strong&gt;complet&lt;/strong&gt; (propose l&amp;rsquo;intégration continue, les pages webs, la génération d&amp;rsquo;une version production, etc.)&lt;/li&gt;
&lt;li&gt;un agglomérat de &lt;em&gt;git daemon&lt;/em&gt;, &lt;em&gt;gitolite&lt;/em&gt; et &lt;em&gt;git web&lt;/em&gt; : pour bénéficier d&amp;rsquo;un accès en &lt;strong&gt;git://&lt;/strong&gt;, gérer les dépôts publics/privés et avoir une interface web pour naviguer dans le dépôt de code&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gogs.io/&#34;&gt;Gogs&lt;/a&gt; : un outil &lt;strong&gt;léger&lt;/strong&gt;, écrit en &lt;em&gt;Go&lt;/em&gt;, se voulant être une solution sans prise de tête&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mes problèmes avec ces outils :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gitlab : &lt;strong&gt;trop gourmand&lt;/strong&gt; en mémoire vive. J&amp;rsquo;aimerais la possibilité de migrer sur une machine plus légère en cas de besoin&lt;/li&gt;
&lt;li&gt;le mix daemon+gitolite+web : mes essais sur l&amp;rsquo;interface web des dépôts privés n&amp;rsquo;étaient pas concluant. La mise en relation des outils était embêtante. Et &lt;strong&gt;pas de gestion de tickets&lt;/strong&gt; sur chaque projet.&lt;/li&gt;
&lt;li&gt;Gogs : documentation d&amp;rsquo;installation peu détaillée&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Vu mes maigres solutions, j&amp;rsquo;ai tenté l&amp;rsquo;aventure avec Gogs. &lt;a href=&#34;https://github.com/gogits/gogs/issues/3877&#34;&gt;L&amp;rsquo;envoi de courriel sous Gogs ne semble pas fonctionner pour tout le monde&lt;/a&gt; et &lt;a href=&#34;https://github.com/gogits/gogs/issues/997&#34;&gt;l&amp;rsquo;alternative via sendmail n&amp;rsquo;est pas encore implémentée&lt;/a&gt;, du coup à la lecture de ce dernier lien j&amp;rsquo;ai visé Gitea. Et je ne suis pas déçu du voyage.&lt;/p&gt;
&lt;h3 id=&#34;gitea&#34;&gt;Gitea&lt;/h3&gt;
&lt;p&gt;Gitea est un fork de Gogs. Un outil pour gérer des dépôts Git via une interface web. Cela propose une gestion des tickets attachés au projet, des pages de Wiki, une gestion des utilisateurs et des groupes d&amp;rsquo;utilisateurs et des liens vers de l&amp;rsquo;intégration continue.&lt;/p&gt;
&lt;p&gt;Gitea, tout comme Gogs, se veut être multiplateforme, léger, en un binaire unique et Open Source !&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.gitea.io/2016/12/welcome-to-gitea/&#34;&gt;L&amp;rsquo;équipe de Gitea explique sur son blog pourquoi elle a forké le projet&lt;/a&gt;. Je résumerais la chose ainsi : Gogs ne possède qu&amp;rsquo;une et une seule porte d&amp;rsquo;entrée aux contributions, c&amp;rsquo;est à dire un seul développeur. Ce qui, à long terme, ne permet probablement pas d&amp;rsquo;en assurer la pérénité. Gitea résout le problème en proposant plusieurs personnes pour maintenir le projet. Personnes précédemment choisies par la communauté.&lt;/p&gt;
&lt;h3 id=&#34;quelles-différences-avec-gogs-&#34;&gt;Quelles différences avec Gogs ?&lt;/h3&gt;
&lt;p&gt;Outre la centaine de participations au projet et la quarantaine de bugs résolus par Gitea, l&amp;rsquo;outil propose quelques fonctionnalités supplémentaires comme :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;la prise en charge d&amp;rsquo;OpenID pour s&amp;rsquo;identifier&lt;/li&gt;
&lt;li&gt;l&amp;rsquo;option sendmail pour envoyer des courriels&lt;/li&gt;
&lt;li&gt;le support de git-lfs afin d&amp;rsquo;inclure le versionnement de fichiers de plus grosse volumétrie&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Par ailleurs la plupart des variables autrefois connues sous le nom &lt;strong&gt;GOGS_WORK_DIR&lt;/strong&gt; sont remaniées en &lt;strong&gt;GITEA_WORK_DIR&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;apparence visuelle est aussi légèrement modifiée aux couleurs de Gitea.&lt;/p&gt;
&lt;h3 id=&#34;ce-choix-est-tout-de-même-risqué&#34;&gt;Ce choix est tout de même risqué&lt;/h3&gt;
&lt;p&gt;Utiliser un projet forké a des risques, comme je l&amp;rsquo;ai vu pour &lt;a href=&#34;http://linuxfr.org/news/chiliproject-redmine-fork%C3%A9&#34;&gt;ChiliProject, fork de Redmine&lt;/a&gt; qui a donné lieu 4 ans plus tard à un essouflement des personnes et un &lt;a href=&#34;https://github.com/asinteg/chiliproject-to-redmine&#34;&gt;beau script de migration vers Redmine&lt;/a&gt;. Ce qui est tout de même atypique de pouvoir revenir au projet initial sans casse !&lt;/p&gt;
&lt;p&gt;Je risque :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;d&amp;rsquo;utiliser un projet sans mises-à-jour&lt;/li&gt;
&lt;li&gt;de ne plus pouvoir retourner à Gogs le jour J&lt;/li&gt;
&lt;li&gt;perdre mon temps&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Défi accepté, j&amp;rsquo;utilise Gitea &amp;#x1f603;.&lt;/p&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://forge.o9.re/&#34;&gt;À première vue&lt;/a&gt; l&amp;rsquo;outil semble fonctionner. Il est agréable à utiliser. Me fournit les dépôts publics et privés dont j&amp;rsquo;avais besoin. Un accès SSH aux dépôts. La possibilité d&amp;rsquo;ajouter plusieurs clés d&amp;rsquo;accès à ces dépôts suivant mes machines. La gestion du projet via tickets, wiki, etc. Et il reste léger, la page de statistiques affichant &lt;strong&gt;une utilisation de 20MB&lt;/strong&gt; sur le serveur.&lt;/p&gt;
&lt;p&gt;En outre j&amp;rsquo;ai profité de l&amp;rsquo;installation de cet outil pour rédiger une &lt;a href=&#34;https://docs.gitea.io/en-us/config-cheat-sheet/&#34;&gt;page recensant les variables d&amp;rsquo;environnement disponibles sur Gitea&lt;/a&gt;. Je souhaite à Gitea une longue vie afin de pouvoir maintenir mon service Git à flot ;).&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai d&amp;rsquo;ailleurs participé à la rédaction complète d&amp;rsquo;une page sur les variables d&amp;rsquo;environnement spécifiques à Gitea&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
