<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Docker sur Olivier DOSSMANN</title>
    <link>https://olivier.dossmann.net/tags/docker/</link>
    <description>Contenu récent dans Docker sur Olivier DOSSMANN</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>fr</language>
    <copyright>© 2005-2026 Olivier DOSSMANN</copyright>
    <lastBuildDate>Sun, 22 Mar 2026 11:42:00 +0100</lastBuildDate><atom:link href="https://olivier.dossmann.net/tags/docker/index.xml" rel="self" type="application/rss+xml" />
    <item>
	    <title>Encore un autre lecteur de flux RSS, Yarr</title>
      <link>https://olivier.dossmann.net/2026/03/encore-un-autre-lecteur-de-flux-rss-yarr/</link>
      <pubDate>Sun, 22 Mar 2026 11:42:00 +0100</pubDate>
      
      <guid>https://olivier.dossmann.net/2026/03/encore-un-autre-lecteur-de-flux-rss-yarr/</guid>
      <description>&lt;h1 id=&#34;introduction&#34;&gt;Introduction&lt;/h1&gt;
&lt;p&gt;Il y a fort fort longtemps (en 2009), je testais &lt;a href=&#34;https://tt-rss.org/&#34;&gt;&lt;strong&gt;TinyTinyRSS&lt;/strong&gt;, un lecteur de flux RSS&lt;/a&gt; avec une interface Web. J&amp;rsquo;en parlais d&amp;rsquo;ailleurs dans un &lt;a href=&#34;https://olivier.dossmann.net/2009/09/nouvelles-astuces-sur-rxvt-unicode-et-tinytinyrss/&#34; title=&#34;Découvrir mon article sur TinyTinyRSS et rxvt-unicode&#34;&gt;article pour signaler la venue de deux nouveaux tutoriels (dont TinyTinyRSS) dans mon Recueil d&amp;rsquo;astuces&lt;/a&gt;. Ce lecteur était &lt;strong&gt;agréable à l&amp;rsquo;usage, rapide&lt;/strong&gt; et utilisait une base de données &lt;strong&gt;postgreSQL&lt;/strong&gt;. Bref, tout ce que je voulais à l&amp;rsquo;époque. Le temps a passé ; je dépensais moins de temps sur les flux RSS. Puis j&amp;rsquo;ai arrêté - qu&amp;rsquo;importe les raisons. Ça fait &lt;strong&gt;bientôt 10 ans&lt;/strong&gt; que j&amp;rsquo;ai laissé cela derrière moi.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Bouh la honte Olivier !&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Certes.&lt;/p&gt;
&lt;p&gt;Récemment, &lt;strong&gt;une mouche m&amp;rsquo;a piquée&lt;/strong&gt; - ou une &lt;em&gt;lubie&lt;/em&gt; - et &lt;strong&gt;je me suis renseigné&lt;/strong&gt; sur les outils de lecture de &lt;strong&gt;flux RSS&lt;/strong&gt; façon &lt;strong&gt;auto-hébergés et minimalistes&lt;/strong&gt;. Je ne vais pas détailler la liste dans cet article puisque, vous l&amp;rsquo;aurez compris, on parle déjà dans le titre de &lt;a href=&#34;https://github.com/nkanaev/yarr&#34;&gt;&lt;strong&gt;Yarr&lt;/strong&gt;&lt;/a&gt; !&lt;/p&gt;
&lt;p&gt;Ainsi nous commencerons par présenter l&amp;rsquo;outil, pour ensuite décrire comment l&amp;rsquo;utiliser avec docker-compose pour finalement terminer par mon retour d&amp;rsquo;expérience après quelques jours d&amp;rsquo;utilisation (démarrage au 25 février 2026) et via un &lt;strong&gt;tour complet de l&amp;rsquo;outil&lt;/strong&gt; - ça va être long mais il y a des images &amp;#x1f609; .&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/objets/faisceaux_lumineux.jpg&#34; alt=&#34;Image de faisceaux lumineux multiples qui ont sûrement dérivé&#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/12836528@N00/&#34;&gt;profil de Kevin Dooley sur Flickr&lt;/a&gt;&lt;/em&gt; sous licence CC BY 2.0.&lt;/p&gt;
&lt;h1 id=&#34;découverte-de-yarr&#34;&gt;Découverte de Yarr&lt;/h1&gt;
&lt;p&gt;Avant de découvrir : &lt;strong&gt;on cherche&lt;/strong&gt; ! J&amp;rsquo;ai donc établi une petite liste de &lt;strong&gt;critères pour la recherche d&amp;rsquo;un lecteur de flux RSS&lt;/strong&gt; :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;simple, voire &lt;strong&gt;basique&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;avec une &lt;strong&gt;interface Web&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;auto-hébergeable&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Open Source&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;rapide&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;léger&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;sans forcément une base de données de type MySQL ou PostgreSQL. SQLite acceptable,&lt;/li&gt;
&lt;li&gt;écrit, éventuellement, &lt;strong&gt;en Go&lt;/strong&gt; (j&amp;rsquo;envisage d&amp;rsquo;apprendre prochainement le Go).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;J&amp;rsquo;ai donc cherché. J&amp;rsquo;ai trouvé quelques outils comme :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://miniflux.app/&#34;&gt;Miniflux&lt;/a&gt; (en Go),&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://freshrss.org/index.html&#34;&gt;FreshRSS&lt;/a&gt; (en PHP),&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/LeedRSS/Leed&#34;&gt;LeedRSS&lt;/a&gt; (en PHP),&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ncarlier/feedpushr&#34;&gt;feedpushr&lt;/a&gt; (en Go),&lt;/li&gt;
&lt;li&gt;et &lt;a href=&#34;https://github.com/nkanaev/yarr&#34;&gt;Yarr&lt;/a&gt; (en Go).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Je l&amp;rsquo;ai déjà annoncé : nous n&amp;rsquo;irons pas plus loin avec cette liste.&lt;/p&gt;
&lt;p&gt;Nul besoin de faire la promotion de &lt;a href=&#34;https://github.com/nkanaev/yarr&#34;&gt;Yarr&lt;/a&gt;, je pense qu&amp;rsquo;&lt;a href=&#34;https://lord.re/posts/246-yarr-web-rss-pour-remplacer-ttrss/&#34;&gt;Internet fait déjà de belles suggestions d&amp;rsquo;utilisation de Yarr comme remplaçant de TinyTinyRSS&lt;/a&gt;. Petite histoire marrante : le nom est l&amp;rsquo;&lt;strong&gt;acronyme de Yet Another Rss Reader&lt;/strong&gt;, littéralement « Encore un autre lecteur RSS » ou « L&amp;rsquo;énième lecteur de flux RSS ».&lt;/p&gt;
&lt;p&gt;Une fois cette lecture de blog effectuée, j&amp;rsquo;ai voulu tester &lt;a href=&#34;https://github.com/nkanaev/yarr&#34;&gt;Yarr&lt;/a&gt;. Je me suis donc lancé dans l&amp;rsquo;écriture d&amp;rsquo;un fichier &lt;strong&gt;docker-compose.yml&lt;/strong&gt;.&lt;/p&gt;
&lt;h1 id=&#34;mon-fichier-docker-composeyaml-pour-yarr&#34;&gt;Mon fichier docker-compose.yaml pour Yarr&lt;/h1&gt;
&lt;p&gt;Il aura fallu &lt;strong&gt;moins de 20 minutes&lt;/strong&gt; pour trouver l&amp;rsquo;image Docker de &lt;a href=&#34;https://github.com/nkanaev/yarr&#34;&gt;Yarr&lt;/a&gt; sur le &lt;a href=&#34;https://github.com/nkanaev/yarr&#34;&gt;dépôt officiel de Yarr sur Github&lt;/a&gt;. Cependant l&amp;rsquo;image étant sur Github Actions - que je connais peu - j&amp;rsquo;ai eu plus de mal à trouver le nom donné à l&amp;rsquo;image pour la récupérer depuis Docker. Je vous le donne de suite : &lt;strong&gt;ghcr.io/nkanaev/yarr:v2.5&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Une fois le nom de l&amp;rsquo;image obtenu, il reste à en connaître son usage. Heureusement j&amp;rsquo;ai trouvé un article sur la création d&amp;rsquo;un fichier docker-compose.yaml pour &lt;a href=&#34;https://github.com/nkanaev/yarr&#34;&gt;Yarr&lt;/a&gt; (Cf. &lt;a href=&#34;https://awesome-docker-compose.com/apps/rss/yarr&#34;&gt;https://awesome-docker-compose.com/apps/rss/yarr&lt;/a&gt;) dont je me suis, forcément, grandement inspiré. Et oui je le dis quand j&amp;rsquo;utilise quelque chose qui n&amp;rsquo;est pas de moi &amp;#x1f609; .&lt;/p&gt;
&lt;p&gt;Ainsi j&amp;rsquo;ai pu construire le fichier &lt;strong&gt;docker-compose.yaml&lt;/strong&gt; 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;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;yarr&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;ghcr.io/nkanaev/yarr:v2.5&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_name&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;yarr&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;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:#40a070&#34;&gt;7070&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;- ${DATA_DIR:-./data}:/data&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;&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;- --addr=0.0.0.0:7070&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;- --db=/data/yarr.db&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;- --auth=${Y_USER}:${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;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;- TZ=Europe/Paris&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;labels&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;traefik.enable=true&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:#4070a0&#34;&gt;&amp;#34;traefik.http.routers.${SERVICE}.rule=Host(`$DOMAIN_URL`)&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:#4070a0&#34;&gt;&amp;#34;traefik.http.routers.${SERVICE}.entrypoints=websecure&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;où :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DATA_DIR&lt;/strong&gt;, &lt;strong&gt;Y_USER&lt;/strong&gt;, &lt;strong&gt;PASSWORD&lt;/strong&gt;, &lt;strong&gt;SERVICE&lt;/strong&gt; et &lt;strong&gt;DOMAIN_URL&lt;/strong&gt; sont à renseigner dans un fichier &lt;em&gt;.env&lt;/em&gt; (avec une valeur),&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DATA_DIR&lt;/strong&gt; est le chemin vers le point de montage où seront stockées les données de &lt;a href=&#34;https://github.com/nkanaev/yarr&#34;&gt;Yarr&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Y_USER&lt;/strong&gt; est le nom d&amp;rsquo;utilisateur que vous souhaitez utiliser comme &lt;em&gt;login&lt;/em&gt; pour s&amp;rsquo;identifier sur votre &lt;a href=&#34;https://github.com/nkanaev/yarr&#34;&gt;Yarr&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PASSWORD&lt;/strong&gt;… bah le mot de passe pour s&amp;rsquo;identifier au service &lt;a href=&#34;https://github.com/nkanaev/yarr&#34;&gt;Yarr&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SERVICE&lt;/strong&gt; est un nom (en minuscule, sans espace et sans point) pour le routeur dans Træfik (si vous n&amp;rsquo;utilisez pas Træfik, supprimez la section &amp;ldquo;labels&amp;rdquo; de ce docker-compose.yaml),&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DOMAIN_URL&lt;/strong&gt; est l&amp;rsquo;adresse web pour accéder au service, mais seulement si vous utilisez Træfik en frontal. Sinon supprimez la section &amp;ldquo;labels&amp;rdquo; de ce fichier docker-compose.yaml.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Exemple de fichier &lt;em&gt;.env&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-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;SERVICE&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;monService&lt;/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;DOMAIN_URL&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;domain.tld&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;DATA_DIR&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;/srv/http/yarr_data&lt;/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;Y_USER&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;olivier&lt;/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;PASSWORD&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;mot2passe&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Vous noterez qu&amp;rsquo;on &lt;strong&gt;autorise&lt;/strong&gt; volontairement &lt;strong&gt;toutes les IP&lt;/strong&gt; pour accéder au service (0.0.0.0). Ce dernier s&amp;rsquo;ouvrira sur le &lt;strong&gt;port 7070&lt;/strong&gt; dans le conteneur, mais Docker choisira un port aléatoire sur ce service (pour éviter de demander un port déjà utilisé). Nous en parlerons ci-après avec la commande &lt;code&gt;docker compose port&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Une fois le fichier &lt;em&gt;.env&lt;/em&gt; configuré, on lance et accède rapidement au service (pour tester 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;&lt;span style=&#34;color:#60a0b0;font-style:italic&#34;&gt;# Lance le service en arrière plan - récupération de la main sur l&amp;#39;invite de commande&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker compose up -d
&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;# Affiche les conteneurs lancés&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker compose ps
&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;# Affiche l&amp;#39;adresse pour accéder au service en local&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker compose port yarr &lt;span style=&#34;color:#40a070&#34;&gt;7070&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On lance un navigateur, on tape l&amp;rsquo;adresse retournée par la dernière commande (chez moi &lt;strong&gt;0.0.0.0:32768&lt;/strong&gt;) et le lecteur de flux RSS apparaît. C&amp;rsquo;est parti pour une période d&amp;rsquo;essai de plusieurs jours (tests commencés à partir du 25 février 2026).&lt;/p&gt;
&lt;h1 id=&#34;mon-expérience-avec-yarr---on-fait-le-tour&#34;&gt;Mon expérience avec Yarr - on fait le tour !&lt;/h1&gt;
&lt;h2 id=&#34;lauthentification&#34;&gt;L&amp;rsquo;authentification&lt;/h2&gt;
&lt;p&gt;Dans le fichier docker-compose.yml précédent nous avons ajouté l&amp;rsquo;option &lt;code&gt;--auth&lt;/code&gt; afin d&amp;rsquo;activer l&amp;rsquo;authentification de &lt;a href=&#34;https://github.com/nkanaev/yarr&#34;&gt;Yarr&lt;/a&gt;. La &lt;strong&gt;première page&lt;/strong&gt; sur laquelle nous tombons est donc celle &lt;strong&gt;pour s&amp;rsquo;identifier&lt;/strong&gt; :&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/logiciels/yarr_accueil.png&#34; alt=&#34;Formulaire d&amp;rsquo;accueil pour s&amp;rsquo;identifier&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Simple&lt;/strong&gt;, efficace.&lt;/p&gt;
&lt;h2 id=&#34;linterface-générale&#34;&gt;L&amp;rsquo;interface générale&lt;/h2&gt;
&lt;p&gt;L&amp;rsquo;accueil est plutôt &lt;strong&gt;austère&lt;/strong&gt; - chouette c&amp;rsquo;est &lt;strong&gt;ce que je voulais&lt;/strong&gt; ! - et propose une &lt;strong&gt;disposition en 3 colonnes&lt;/strong&gt; :&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/logiciels/yarr_3_colonnes.png&#34; alt=&#34;Disposition en 3 colonnes sur la page d&amp;rsquo;accueil de Yarr&#34;&gt;&lt;/p&gt;
&lt;p&gt;Chaque colonne sert un objectif précis, de gauche à droite :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;la &lt;strong&gt;liste des flux&lt;/strong&gt; RSS,&lt;/li&gt;
&lt;li&gt;puis la &lt;strong&gt;liste des articles&lt;/strong&gt;/éléments d&amp;rsquo;un flux en particulier,&lt;/li&gt;
&lt;li&gt;puis &lt;strong&gt;l&amp;rsquo;article&lt;/strong&gt; choisi parmi la liste précédente.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Donc plus on se dirige à droite, plus la lecture se précise.&lt;/p&gt;
&lt;p&gt;Sur téléphone mobile il n&amp;rsquo;y aura plus qu&amp;rsquo;une seule colonne : celle tout à gauche. On choisira ainsi un flux, ce qui affichera la liste des articles et si on choisit un article, on verra son contenu. Toujours sur une colonne. &lt;strong&gt;Astucieux&lt;/strong&gt;, &lt;strong&gt;logique&lt;/strong&gt; et presque &lt;strong&gt;intuitif&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;avoue que sur ce dernier point, sur téléphone mobile, j&amp;rsquo;ai été totalement perdu : je ne savais pas où j&amp;rsquo;étais et ce que je faisais. Ce n&amp;rsquo;est qu&amp;rsquo;en comparant l&amp;rsquo;usage entre un grand écran et un petit écran que j&amp;rsquo;ai saisi ce qu&amp;rsquo;il en était. Sur ce coup-là, je suis le couteau le moins aiguisé du tiroir…&lt;/p&gt;
&lt;h2 id=&#34;la-configuration-de-linterface&#34;&gt;La configuration de l&amp;rsquo;interface&lt;/h2&gt;
&lt;p&gt;Je continue ma découverte avec l&amp;rsquo;&lt;strong&gt;icône représentant 3 petits points&lt;/strong&gt; en haut à droite de la première colonne (ou en haut à droite sur un petit écran ne présentant donc qu&amp;rsquo;une seule colonne). Les options de l&amp;rsquo;outil apparaissent :&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/logiciels/yarr_options.png&#34; alt=&#34;Image contenant le menu d&amp;rsquo;option de configuration de l&amp;rsquo;outil Yarr&#34;&gt;&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est ici que va se jouer les &lt;strong&gt;seules options disponibles dans &lt;a href=&#34;https://github.com/nkanaev/yarr&#34;&gt;Yarr&lt;/a&gt;&lt;/strong&gt; :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;New Feed&lt;/strong&gt; : Permet d&amp;rsquo;&lt;strong&gt;ajouter un nouveau flux&lt;/strong&gt;. Il faut 2 infos : l&amp;rsquo;adresse URL du flux, et le dossier dans lequel le ranger,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Refresh Feeds&lt;/strong&gt; : &lt;strong&gt;Actualisation&lt;/strong&gt; des flux,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Theme&lt;/strong&gt; : Pour changer l&amp;rsquo;&lt;strong&gt;apparence de &lt;a href=&#34;https://github.com/nkanaev/yarr&#34;&gt;Yarr&lt;/a&gt;&lt;/strong&gt;. Nous en parlerons tout à l&amp;rsquo;heure,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Auto Refresh&lt;/strong&gt; : Permet de choisir le &lt;strong&gt;laps de temps&lt;/strong&gt; entre plusieurs &lt;strong&gt;rafraîchissements automatiques&lt;/strong&gt;. Comprendre : on récupère les flux tous les X temps (de 0mn à 4h),&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Show first&lt;/strong&gt; : Permet de choisir si on préfère afficher les &lt;strong&gt;articles parus récemment&lt;/strong&gt; en premier (&lt;em&gt;New&lt;/em&gt;) &lt;strong&gt;ou ceux les plus anciens&lt;/strong&gt; en premier (&lt;em&gt;Old&lt;/em&gt;),&lt;/li&gt;
&lt;li&gt;Subscriptions :
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Import&lt;/strong&gt; : Donne la possibilité d&amp;rsquo;importer une liste de flux (au &lt;strong&gt;format OPML&lt;/strong&gt;),&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Export&lt;/strong&gt; : Permet d&amp;rsquo;exporter sa liste de flux (au &lt;strong&gt;format OPML&lt;/strong&gt;) pour la partager par exemple,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shortcuts&lt;/strong&gt; : Affiche un rappel des &lt;strong&gt;raccourcis claviers&lt;/strong&gt; possibles pour naviguer et lire les flux. Et ils sont &lt;strong&gt;très utiles&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Log out&lt;/strong&gt; : Apparaîtra seulement si l&amp;rsquo;option &lt;code&gt;--auth&lt;/code&gt; a été utilisée. C&amp;rsquo;est pour &lt;strong&gt;se déconnecter&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;J&amp;rsquo;avais peur de tomber sur un lecteur avec des milliers de configurations. Finalement &lt;strong&gt;&lt;a href=&#34;https://github.com/nkanaev/yarr&#34;&gt;Yarr&lt;/a&gt; va à l&amp;rsquo;essentiel&lt;/strong&gt;. Cela me plaît - encore une fois.&lt;/p&gt;
&lt;h2 id=&#34;choix-dun-thème&#34;&gt;Choix d&amp;rsquo;un thème&lt;/h2&gt;
&lt;p&gt;Vous aurez remarqué que &lt;strong&gt;mes impressions écrans&lt;/strong&gt; présentent les pages d&amp;rsquo;une &lt;strong&gt;couleur simili jaune&lt;/strong&gt; (qui fait penser à &lt;a href=&#34;https://ethanschoonover.com/solarized/&#34;&gt;Solarized Light d&amp;rsquo;Ethan Shoonover&lt;/a&gt;). C&amp;rsquo;est parce que j&amp;rsquo;ai choisi un thème. On peut &lt;strong&gt;choisir entre 3 thèmes&lt;/strong&gt; :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;blanc&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;jaune&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;noir&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Je suis content du thème jaune car ma vue pose problème avec les thèmes noirs (l&amp;rsquo;astigmathie a une forme d&amp;rsquo;opposition rebelle au &amp;ldquo;dark theme&amp;rdquo; et peut rendre les textes &amp;ldquo;flous&amp;rdquo;). Certes, la &lt;a href=&#34;https://www.nngroup.com/articles/dark-mode/&#34;&gt;performance de lecture est plus importante en mode &amp;ldquo;light&amp;rdquo;&lt;/a&gt;, mais ça reste trop lumineux pour moi. Je n&amp;rsquo;aime pas le jaune en tant que tel, mais pour mon efficacité de lecture c&amp;rsquo;est le &amp;ldquo;moins pire&amp;rdquo; &amp;#x1f923; . Évidemment les tendances s&amp;rsquo;inversent la nuit (mais pas pour moi), dans la pénombre et/ou dans un environnement peu lumineux. Mais nous ne sommes pas ici pour lancer le troll « Dark Mode vs. Light Mode », ou bien ? Combat !&lt;/p&gt;
&lt;h2 id=&#34;les-trois-icônes-principales&#34;&gt;Les trois icônes principales&lt;/h2&gt;
&lt;p&gt;Vous avez découvert l&amp;rsquo;usage en 3 colonnes, cette fois nous allons découvrir l&amp;rsquo;usage des 3 icônes tout en haut qui sont, en quelque sorte, le menu principal de &lt;a href=&#34;https://github.com/nkanaev/yarr&#34;&gt;Yarr&lt;/a&gt; :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;un rond rempli de noir,&lt;/li&gt;
&lt;li&gt;une étoile,&lt;/li&gt;
&lt;li&gt;3 traits horizontaux parallèles de longueurs différentes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La première (le &lt;strong&gt;rond noir&lt;/strong&gt;) permet d&amp;rsquo;&lt;strong&gt;afficher la liste des flux&lt;/strong&gt; sur lesquels nous avons encore des articles/éléments à lire.&lt;/p&gt;
&lt;p&gt;La seconde (&lt;strong&gt;étoile noire&lt;/strong&gt;) affiche une liste des flux sur lequels vous avez marqués des articles/éléments comme &lt;strong&gt;favoris&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Et la dernière (les &lt;strong&gt;3 traits horizontaux&lt;/strong&gt;) affiche la &lt;strong&gt;liste complète des flux&lt;/strong&gt;, qu&amp;rsquo;importe qu&amp;rsquo;il vous reste ou non des articles/éléments à lire.&lt;/p&gt;
&lt;p&gt;Exemple d&amp;rsquo;affichage en 3 colonnes sur le rond noir avec le choix d&amp;rsquo;un article et son affichage :&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/logiciels/yarr_exemple.png&#34; alt=&#34;Affichage en 3 colonnes de Yarr avec le choix du flux MiniMachines.net, d&amp;rsquo;un article précis et de son affichage dans la dernière colonne&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Simple, basique, sans fioritures&lt;/strong&gt;. Utilisable &lt;strong&gt;avec des raccourcis&lt;/strong&gt; clavier. &lt;strong&gt;Parfait&lt;/strong&gt; !&lt;/p&gt;
&lt;h2 id=&#34;les-derniers-petits-détails---et-après-jarrête-promis&#34;&gt;Les derniers petits détails - et après j&amp;rsquo;arrête promis !&lt;/h2&gt;
&lt;p&gt;Dernière liste d&amp;rsquo;icônes dans l&amp;rsquo;interface :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;deuxième colonne :
&lt;ul&gt;
&lt;li&gt;icône de &lt;strong&gt;loupe&lt;/strong&gt; : Fait une &lt;strong&gt;recherche dans la liste d&amp;rsquo;article&lt;/strong&gt; de &lt;strong&gt;CE&lt;/strong&gt; flux choisi,&lt;/li&gt;
&lt;li&gt;icône de &lt;strong&gt;validation&lt;/strong&gt; : &lt;strong&gt;Marque tous les articles&lt;/strong&gt; de ce flux &lt;strong&gt;comme lus&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;icône de &lt;strong&gt;3 petits points&lt;/strong&gt; l&amp;rsquo;un à côté de l&amp;rsquo;autre verticalement : c&amp;rsquo;est ici qu&amp;rsquo;on a les &lt;strong&gt;détails du flux&lt;/strong&gt;. On peut le renommer, le changer de place, le supprimer, aller sur le site Web, etc.,&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;troisième colonne :
&lt;ul&gt;
&lt;li&gt;icône d&amp;rsquo;&lt;strong&gt;étoile&lt;/strong&gt; (vide/remplie) : Marque l&amp;rsquo;article en &lt;strong&gt;favori&lt;/strong&gt; ou au contraire l&amp;rsquo;enlève des favoris,&lt;/li&gt;
&lt;li&gt;icône d&amp;rsquo;un &lt;strong&gt;rond&lt;/strong&gt; (vide/rempli) : Marque l&amp;rsquo;article comme &lt;strong&gt;lu ou non-lu&lt;/strong&gt; (suivant de quel état on commence),&lt;/li&gt;
&lt;li&gt;icône de &lt;strong&gt;traits verticaux entrecoupés comme de petits pistons&lt;/strong&gt; : Permet de &lt;strong&gt;changer la police&lt;/strong&gt; d&amp;rsquo;écriture (parmi sans-serif, serif et monospace) ainsi que &lt;strong&gt;la taille de police&lt;/strong&gt; (petit, ou grand, plus on appuie plus ça réduit/aggrandit),&lt;/li&gt;
&lt;li&gt;icône d&amp;rsquo;un &lt;strong&gt;livre ouvert&lt;/strong&gt; : Choisi de &lt;strong&gt;lire l&amp;rsquo;article dans &lt;a href=&#34;https://github.com/nkanaev/yarr&#34;&gt;Yarr&lt;/a&gt;&lt;/strong&gt; ou bien seulement les informations du flux RSS,&lt;/li&gt;
&lt;li&gt;icône d&amp;rsquo;un &lt;strong&gt;carré avec une flèche qui en sort&lt;/strong&gt;) : Va &lt;strong&gt;directement sur le site Web de l&amp;rsquo;article&lt;/strong&gt; en question.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/logiciels/yarr_flux_options.png&#34; alt=&#34;Détail des options disponible pour un flux donné dans la seconde colonne sur l&amp;rsquo;icône avec les 3 petits points&#34;&gt;&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;utilise souvent l&amp;rsquo;icône de validation de la seconde colonne pour marquer tous les articles comme lus une fois que j&amp;rsquo;ai parcouru la liste des titres et que rien ne m&amp;rsquo;intéressait.&lt;/p&gt;
&lt;p&gt;Les raccourcis claviers sont là pour faciliter le traitement des articles (lu, non-lu, favori, lire à l&amp;rsquo;extérieur, etc.). Parfois j&amp;rsquo;utilise le raccourci &amp;ldquo;o&amp;rdquo; pour lire l&amp;rsquo;article sur le site Web.&lt;/p&gt;
&lt;p&gt;Du reste, je n&amp;rsquo;utilise quasiment rien. Après tout je ne viens que pour lire des titres, trier et lire un article de temps en temps &amp;#x1f937; . Je ne suis pas là pour bosser.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Au début &lt;strong&gt;un peu perdu par l&amp;rsquo;interface&lt;/strong&gt; afin de &lt;strong&gt;comprendre à quoi sert chaque élément&lt;/strong&gt; - surtout entre interface petit écran et grand écran - j&amp;rsquo;ai finalement &lt;strong&gt;apprécié &lt;a href=&#34;https://github.com/nkanaev/yarr&#34;&gt;Yarr&lt;/a&gt; à l&amp;rsquo;usage&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est un outil &amp;ldquo;menu&amp;rdquo; (maigre, &lt;strong&gt;léger&lt;/strong&gt;), simple, &lt;strong&gt;basique, sans fioritures&lt;/strong&gt;. &lt;strong&gt;Configurable&lt;/strong&gt; un minimum. Utilisable avec des &lt;strong&gt;raccourcis clavier&lt;/strong&gt;. Très efficace d&amp;rsquo;ailleurs avec un clavier quand on s&amp;rsquo;y fait. C&amp;rsquo;est même redoutable de rapidité quand on a le coup de main !&lt;/p&gt;
&lt;p&gt;À vrai dire, je ne sais même pas de quoi j&amp;rsquo;aurais besoin en plus pour lire des flux. J&amp;rsquo;ajoute rapidement des flux, j&amp;rsquo;&lt;strong&gt;importe et exporte facilement&lt;/strong&gt; pour partager avec d&amp;rsquo;autres, je vois de nouveaux articles, je clique sur ce qui m&amp;rsquo;intéresse, je lis, je note le reste des articles comme lus pour ce flux et voilà.&lt;/p&gt;
&lt;p&gt;Ni plus. Ni moins. &lt;strong&gt;Parfait&lt;/strong&gt; &amp;#x1f604; .&lt;/p&gt;
&lt;h1 id=&#34;liens-utiles&#34;&gt;Liens utiles&lt;/h1&gt;
&lt;p&gt;Voici les liens de l&amp;rsquo;article par ordre d&amp;rsquo;apparition :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://tt-rss.org/&#34;&gt;TinyTinyRSS, un lecteur de flux RSS&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://olivier.dossmann.net/2009/09/nouvelles-astuces-sur-rxvt-unicode-et-tinytinyrss/&#34;&gt;Mon article pour signaler la venue de deux nouveaux tutoriels (dont TinyTinyRSS) dans mon Recueil d&amp;rsquo;astuces&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/nkanaev/yarr&#34;&gt;Yarr&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://miniflux.app/&#34;&gt;Miniflux&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://freshrss.org/index.html&#34;&gt;FreshRSS&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/LeedRSS/Leed&#34;&gt;LeedRSS&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ncarlier/feedpushr&#34;&gt;feedpushr&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://lord.re/posts/246-yarr-web-rss-pour-remplacer-ttrss/&#34;&gt;Bel article sur  l&amp;rsquo;utilisation de Yarr comme remplaçant de TinyTinyRSS&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://awesome-docker-compose.com/apps/rss/yarr&#34;&gt;Exemple de docker-compose pour Yarr&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://ethanschoonover.com/solarized/&#34;&gt;Solarized Light d&amp;rsquo;Ethan Shoonover&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.nngroup.com/articles/dark-mode/&#34;&gt;La performance de lecture suivant le thème light/dark et nos yeux&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&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>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>Voici Docker, plus léger et plus simple qu&#39;une machine virtuelle</title>
      <link>https://olivier.dossmann.net/2014/04/voici-docker-plus-l%C3%A9ger-et-plus-simple-quune-machine-virtuelle/</link>
      <pubDate>Thu, 03 Apr 2014 13:20:30 +0100</pubDate>
      
      <guid>https://olivier.dossmann.net/2014/04/voici-docker-plus-l%C3%A9ger-et-plus-simple-quune-machine-virtuelle/</guid>
      <description>&lt;h3 id=&#34;introduction&#34;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://olivier.dossmann.net/2014/03/serveur-de-machines-virtuelles-avec-virtualbox/&#34; title=&#34;Lire l&#39;article Serveur de machines virtuelles avec VirtualBox&#34;&gt;Nous parlions précédemment de VirtualBox pour créer des machines virtuelles&lt;/a&gt; sur sa machine. C&amp;rsquo;est une solution pratique qui permet de tester un environnement sans avoir à installer quoique ce soit de plus que VirtualBox sur sa machine et sans perdre de données. Un environnement fermé.&lt;/p&gt;
&lt;p&gt;Mais quand il s&amp;rsquo;agit de lancer plusieurs services sur une machine (un serveur web, un serveur de base de données, une application web, etc.) cela devient tout de suite lourd et consommateur de mémoire vive + espace disque.&lt;/p&gt;
&lt;p&gt;Des solutions alternatives existent, comme l&amp;rsquo;utilisation de LXC qui sont des conteneurs qui utilisent communément le noyau Linux mais fonctionnent à peu de choses prêts comme ce que nous appelons des &lt;strong&gt;chroots&lt;/strong&gt;. Cependant cette solution n&amp;rsquo;est pas si simple car il faut gérer les conteneurs, leur lancement, etc.&lt;/p&gt;
&lt;p&gt;Une solution plus simple, se basant sur les LXC existe : &lt;a href=&#34;http://docker.io&#34; title=&#34;Visiter la page officielle de Docker.&#34;&gt;Docker&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://olivier.dossmann.net/images/logos/docker.png&#34; alt=&#34;Logo de Docker&#34; title=&#34;Logo du projet Docker&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;présentation-de-docker&#34;&gt;Présentation de Docker&lt;/h3&gt;
&lt;p&gt;Pour &lt;a href=&#34;https://www.docker.io/learn_more/&#34; title=&#34;Leanr more about Docker&#34;&gt;en savoir plus sur Docker&lt;/a&gt;, il faut se rendre sur la &lt;a href=&#34;https://www.docker.io/learn_more/&#34; title=&#34;Learn more about Docker&#34;&gt;page prévue à cet effet sur le site officiel&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Mais pour vous résumer un peu ce que j&amp;rsquo;en ai compris :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Docker permet de créer des applications dans un conteneur&lt;/li&gt;
&lt;li&gt;Un conteneur est plus léger en terme de taille et en terme de consommation mémoire qu&amp;rsquo;une machine virtuelle entière&lt;/li&gt;
&lt;li&gt;Les conteneurs peuvent être construits à partir d&amp;rsquo;un simple fichier nommé le Dockerfile&lt;/li&gt;
&lt;li&gt;Les conteneurs peuvent être partagés via un dépôt public (&lt;a href=&#34;http://index.docker.io&#34; title=&#34;Trouver un docker particulier&#34;&gt;Index Docker&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;La création d&amp;rsquo;un conteneur peut se faire via l&amp;rsquo;utilisation de &lt;strong&gt;commit&lt;/strong&gt;, ce qui permet de versionner les conteneurs&lt;/li&gt;
&lt;li&gt;La création d&amp;rsquo;un conteneur peut se faire via l&amp;rsquo;héritage d&amp;rsquo;un autre conteneur&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ainsi :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;faire tourner plusieurs conteneurs est plus léger que créer plusieurs machines virtuelles&lt;/li&gt;
&lt;li&gt;le versionnement de ses conteneurs permet de redémarrer depuis un précédent commit, de rejouer certaines choses ou améliorer des conteneurs précédents&lt;/li&gt;
&lt;li&gt;le Dockerfile est un simple fichier, ce qui permet de partager/déplacer une application contenue dans un conteneur de manière très rapide&lt;/li&gt;
&lt;li&gt;plus de soucis avec les collègues au sujet d&amp;rsquo;un environnement différent d&amp;rsquo;un développeur à l&amp;rsquo;autre : tout le monde utilise la même version du conteneur&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Vous l&amp;rsquo;aurez compris, cela n&amp;rsquo;a que des avantages - quasiment.&lt;/p&gt;
&lt;h3 id=&#34;installation-et-utilisation&#34;&gt;Installation et utilisation&lt;/h3&gt;
&lt;p&gt;Le site de Docker nous apprend &lt;a href=&#34;https://www.docker.io/gettingstarted/&#34; title=&#34;Getting started on Docker&#34;&gt;comment installer et utiliser Docker en quelques points&lt;/a&gt;, mais aussi &lt;a href=&#34;https://olivier.dossmann.net/wiki/virtualisation/docker/&#34; title=&#34;Apprendre à installer et utiliser Docker sur Debian AMD64&#34;&gt;la page Docker de mon Recueil d&amp;rsquo;astuces&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ce que je pense qu&amp;rsquo;il faut au minimum retenir ce sont les commandes suivantes :&lt;/p&gt;
&lt;pre name=&#34;code&#34; class=&#34;bash&#34;&gt;
# Créer un nouveau conteneur basé sur Ubuntu
docker run -i -t ubuntu /bin/bash
# Voir les conteneurs lancés
docker ps
# Voir tout les conteneurs crées
docker ps -a
# Voir les images disponibles sur notre machine (à partir desquelles créer de nouveaux conteneurs)
docker images
# Supprimer un conteneur (ID est l&#39;identifiant donné par la commande docker ps -a)
docker rm ID
# Donner un nom à son conteneur (--name). Utile à la place d&#39;utiliser un ID
docker run -i -t --name SuperNom ubuntu /bin/bash
&lt;/pre&gt;
&lt;p&gt;Et évidemment, le plus intéressant est de regarder &lt;a href=&#34;http://index.docker.io&#34; title=&#34;Découvrir de nouveaux fichiers Docker&#34;&gt;l&amp;rsquo;index des fichiers Docker disponibles&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;quelques-regrets&#34;&gt;Quelques regrets&lt;/h3&gt;
&lt;p&gt;En faisant quelques conteneurs Docker, on peut regretter :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;le fait qu&amp;rsquo;il faille utiliser supervisord de manière systématique pour lancer plusieurs services dans un conteneurs.&lt;/li&gt;
&lt;li&gt;l&amp;rsquo;utilisation d&amp;rsquo;espace partagés ne nous prévient pas qu&amp;rsquo;on risque d&amp;rsquo;écraser nos propres données sur la machine hôte&lt;/li&gt;
&lt;li&gt;ne fonctionne que sur architecture am64&lt;/li&gt;
&lt;li&gt;ne fonctionne que pour Linux (puisque basé sur LXC), donc sous windows il faut utiliser une machine virtuelle avec Ubuntu&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si on se soustrait de ses inconvénients, cela reste un outil intéressant !&lt;/p&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Docker est un outil intéressant comparé à la gestion, la création et l&amp;rsquo;utilisation de conteneurs LXC, c&amp;rsquo;est une surcouche très attrayante.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;apprécie qu&amp;rsquo;on puisse générer un environnement commun à l&amp;rsquo;ensemble d&amp;rsquo;une équipe de développeurs afin qu&amp;rsquo;ils aient toujours les mêmes bibliothèques et outils. En revanche, pour de la production je ne trouve pas cela encore assez au point car réussir à lancer plusieurs services sur un conteneur est vite décourageant et demande pas mal de connaissances !&lt;/p&gt;
&lt;p&gt;Mon utilisation de Docker resterait donc du côté développement, afin d&amp;rsquo;utiliser un fichier simple qui génère un environnement complet de développement et de déploiement local d&amp;rsquo;un ou plusieurs services. Par exemple pour avoir un serveur OpenERP ou bien un serveur postgreSQL.&lt;/p&gt;
&lt;p&gt;Je pense que ça peut-être déployé sur un serveur distant (machine virtuelle ou non) avec plusieurs conteneurs, un par service afin de permettre de déployé/déplacer un service rapidement, sans effort et sans pertes.&lt;/p&gt;
&lt;p&gt;Je verrais cela à l&amp;rsquo;utilisation, et je vous invite à en faire autant !&lt;/p&gt;
&lt;h3 id=&#34;liens-utiles&#34;&gt;Liens utiles&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.docker.io/learn_more/&#34; title=&#34;Learn more about Docker&#34;&gt;En savoir plus sur Docker (en)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://index.docker.io/&#34; title=&#34;Se rendre sur le site officiel des images Docker&#34;&gt;Index des images Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://olivier.dossmann.net/wiki/virtualisation/docker/&#34; title=&#34;En savoir plus sur Docker&#34;&gt;Docker sur mon Recueil d&amp;rsquo;astuces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://linuxfr.org/news/logiciels-pour-survivre-avec-docker&#34; title=&#34;Découvrir des logiciels permettant de gérer ses conteneurs Docker selon LinuxFR&#34;&gt;Pistes pour gérer ses conteneurs Docker selon LinuxFR&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
  </channel>
</rss>
