<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Les carnets de Charly]]></title><description><![CDATA[Experiences en tout genre : sport, cuisine, informatique]]></description><link>https://charly-ginevra.fr/</link><image><url>https://charly-ginevra.fr/favicon.png</url><title>Les carnets de Charly</title><link>https://charly-ginevra.fr/</link></image><generator>Ghost 5.82</generator><lastBuildDate>Tue, 07 Apr 2026 14:26:07 GMT</lastBuildDate><atom:link href="https://charly-ginevra.fr/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[UV : Une nouvelle ère pour les développeurs Python]]></title><description><![CDATA[<p>Avec l&#x2019;arriv&#xE9;e de <em>UV</em>, l&#x2019;&#xE9;cosyst&#xE8;me Python entre dans une phase de transformation. Ultra-rapide, moderne et pens&#xE9; pour simplifier la vie des d&#xE9;veloppeurs, ce nouveau gestionnaire de packages est en train de red&#xE9;finir nos habitudes de travail</p>]]></description><link>https://charly-ginevra.fr/uv-une-nouvelle-ere-pour-les-developpeurs-python/</link><guid isPermaLink="false">68b9f0eb0db8cb0001435987</guid><category><![CDATA[Informatique]]></category><category><![CDATA[Python]]></category><dc:creator><![CDATA[Charly]]></dc:creator><pubDate>Fri, 05 Sep 2025 14:03:27 GMT</pubDate><media:content url="https://charly-ginevra.fr/content/images/2025/09/holy-uv.png" medium="image"/><content:encoded><![CDATA[<img src="https://charly-ginevra.fr/content/images/2025/09/holy-uv.png" alt="UV : Une nouvelle &#xE8;re pour les d&#xE9;veloppeurs Python"><p>Avec l&#x2019;arriv&#xE9;e de <em>UV</em>, l&#x2019;&#xE9;cosyst&#xE8;me Python entre dans une phase de transformation. Ultra-rapide, moderne et pens&#xE9; pour simplifier la vie des d&#xE9;veloppeurs, ce nouveau gestionnaire de packages est en train de red&#xE9;finir nos habitudes de travail et s&#x2019;imposer comme la r&#xE9;f&#xE9;rence incontournable.</p><p>Dans ce court article, je voulais revenir bri&#xE8;vement sur <em>UV</em>. La premi&#xE8;re fois que j&#x2019;ai entendu parler de cet outil, c&#x2019;&#xE9;tait sur la cha&#xEE;ne <a href="https://www.youtube.com/@ArjanCodes?ref=charly-ginevra.fr">ArjanCodes</a>, qui regorge de bonnes pratiques de programmation, de pr&#xE9;sentations de librairies et d&#x2019;outils.</p><p>Cr&#xE9;&#xE9; par la soci&#xE9;t&#xE9; <strong>Astral</strong>, <em>UV</em> est un gestionnaire de packages pour Python &#xE9;crit en Rust, inspir&#xE9; par la toolchain de ce dernier.</p><h1 id="des-environnements-virtuels-en-un-%C3%A9clair">Des environnements virtuels en un &#xE9;clair</h1><p>Je me souviens, il n&#x2019;y a pas si longtemps, on partageait encore les d&#xE9;pendances des projets dans de simples fichiers <code>requirements.txt</code>. Et quand ce fichier manquait&#x2026; on &#xE9;tait un peu coinc&#xE9;s.</p><p>Depuis, la <a href="https://peps.python.org/pep-0621/?utm_source=chatgpt.com">PEP 621</a> a chang&#xE9; la donne. Par d&#xE9;faut, lorsque vous initialisez un projet avec <code>uv init</code>, ce fichier est d&#xE9;sormais pr&#xE9;sent.</p><p>Comme tout bon projet Python, il faut ensuite mettre en place un environnement virtuel. Rien de plus simple avec <em>UV</em> : une simple commande <code>uv venv</code> suffit. Pas besoin d&#x2019;installer un module suppl&#xE9;mentaire, c&#x2019;est aussi direct que &#xE7;a.</p><p>Pour ajouter des d&#xE9;pendances, <code>uv add &lt;package&gt;</code> et pr&#xE9;parez-vous, c&#x2019;est tr&#xE8;s rapide. La premi&#xE8;re fois, je me suis m&#xEA;me demand&#xE9; s&#x2019;il n&#x2019;y avait pas eu un bug tant l&#x2019;installation a &#xE9;t&#xE9; instantan&#xE9;e.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://github.com/astral-sh/uv/assets/1309177/629e59c0-9c6e-4013-9ad4-adb2bcf5080d" class="kg-image" alt="UV : Une nouvelle &#xE8;re pour les d&#xE9;veloppeurs Python" loading="lazy" width="496" height="107"><figcaption><span style="white-space: pre-wrap;">Benchmark pr&#xE9;sent&#xE9; par Astral</span></figcaption></figure><p>Et pour charger toutes les d&#xE9;pendances, rien de plus simple : <code>uv sync</code>.</p><h1 id="un-code-toujours-impeccable">Un code toujours impeccable</h1><p>C&#xF4;t&#xE9; formatage et linting, vous connaissez sans doute <a href="https://github.com/psf/black?utm_source=chatgpt.com">Black</a> ou <a href="https://github.com/PyCQA/flake8?ref=charly-ginevra.fr">Flake8</a>. Mais Astral propose aussi sa propre solution : <a href="https://docs.astral.sh/ruff/?ref=charly-ginevra.fr">Ruff</a>.</p><p>Les performances sont impressionnantes, et surtout, vous n&#x2019;avez besoin que d&#x2019;un seul outil.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://user-images.githubusercontent.com/1309177/232603514-c95e9b0f-6b31-43de-9a80-9e844173fd6a.svg#only-dark" class="kg-image" alt="UV : Une nouvelle &#xE8;re pour les d&#xE9;veloppeurs Python" loading="lazy" width="585" height="167"><figcaption><span style="white-space: pre-wrap;">Performances de Ruff pr&#xE9;sent&#xE9;es par Astral</span></figcaption></figure><p>Vous disposez d&#x2019;une <a href="https://docs.astral.sh/ruff/rules/?ref=charly-ginevra.fr">multitude de r&#xE8;gles</a> pour adapter votre codebase &#xE0; vos besoins.</p><p>Cerise sur le g&#xE2;teau : Astral pense &#xE0; vous et donne plusieurs <a href="https://docs.astral.sh/ruff/editors/setup/?ref=charly-ginevra.fr">tutoriels</a> pour int&#xE9;grer Ruff &#xE0; votre &#xE9;diteur pr&#xE9;f&#xE9;rer.</p><h1 id="le-packaging-sans-prise-de-t%C3%AAte">Le packaging, sans prise de t&#xEA;te</h1><p>Pendant longtemps, cr&#xE9;er une librairie Python pouvait sembler complexe et un peu fastidieux.</p><p>Avec <em>UV</em>, ce temps est r&#xE9;volu : <code>uv build</code> et <code>uv publish</code> rendent le packaging et la publication simples et rapides.</p><p>Et pour aller encore plus loin, Astral fournit son propre <a href="https://docs.astral.sh/uv/concepts/build-backend/?ref=charly-ginevra.fr#namespace-packages">backend de packaging</a>, lui aussi <em>blazingly fast</em>.</p><h1 id="conclusion">Conclusion</h1><p>Bien que certaines critiques puissent &#xEA;tre formul&#xE9;es du fait de sa jeunesse, <em>uv</em> reste pour moi un incontournable pour mes futurs projets Python.</p><p>J&#x2019;ai &#xE9;galement con&#xE7;u un <strong>template</strong> pour mes <strong>futurs projets</strong> Python, disponible sur mon GitHub. Il inclut notamment :</p><ul><li><strong>Ruff</strong> pour assurer la qualit&#xE9; du code</li><li>Une <strong>structure de tests</strong> pr&#xEA;te &#xE0; l&#x2019;emploi</li><li><strong>Pre-commit</strong> pour garantir la qualit&#xE9; de chaque commit</li><li>Une <strong>int&#xE9;gration continue fonctionnelle</strong> avec GitHub Actions</li></ul><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://github.com/CharlyGin/say_hello/?ref=charly-ginevra.fr"><div class="kg-bookmark-content"><div class="kg-bookmark-title">GitHub - CharlyGin/say_hello: Template Python Package using UV</div><div class="kg-bookmark-description">Template Python Package using UV. Contribute to CharlyGin/say_hello development by creating an account on GitHub.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" alt="UV : Une nouvelle &#xE8;re pour les d&#xE9;veloppeurs Python"><span class="kg-bookmark-author">GitHub</span><span class="kg-bookmark-publisher">CharlyGin</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://opengraph.githubassets.com/156cc345e87898b3bbccedf129e2627b928dbe0b15dd733b6e853a9982c0c5f0/CharlyGin/say_hello" alt="UV : Une nouvelle &#xE8;re pour les d&#xE9;veloppeurs Python"></div></a></figure><h1 id="sources">Sources</h1><ul><li><a href="https://astral.sh/?ref=charly-ginevra.fr">Astral.sh</a></li><li><a href="https://docs.astral.sh/uv/?ref=charly-ginevra.fr" rel="noreferrer">uv - documentation</a></li><li><a href="https://docs.astral.sh/ruff/?ref=charly-ginevra.fr" rel="noreferrer">ruff - documentation</a></li><li><a href="https://www.youtube.com/@ArjanCodes?ref=charly-ginevra.fr">ArjanCodes</a></li></ul>]]></content:encoded></item><item><title><![CDATA[GitHub Actions : De l’enfer au paradis]]></title><description><![CDATA[<p>Si vous utilisez GitHub et que vous vous int&#xE9;ressez un peu au monde du DevOps, vous avez forc&#xE9;ment crois&#xE9; GitHub Actions. Et parfois&#x2026; on se dit qu&#x2019;on aurait pr&#xE9;f&#xE9;r&#xE9; que nos chemins ne se soient jamais rencontr&</p>]]></description><link>https://charly-ginevra.fr/github-actions-de-lenfer-au-paradis/</link><guid isPermaLink="false">688baea65c08a10001756f3e</guid><category><![CDATA[Informatique]]></category><category><![CDATA[Automatisation]]></category><category><![CDATA[GitHub Actions]]></category><category><![CDATA[CI/CD]]></category><dc:creator><![CDATA[Charly]]></dc:creator><pubDate>Thu, 04 Sep 2025 12:28:38 GMT</pubDate><media:content url="https://charly-ginevra.fr/content/images/2025/09/github-actions-enfer-paradis.png" medium="image"/><content:encoded><![CDATA[<img src="https://charly-ginevra.fr/content/images/2025/09/github-actions-enfer-paradis.png" alt="GitHub Actions : De l&#x2019;enfer au paradis"><p>Si vous utilisez GitHub et que vous vous int&#xE9;ressez un peu au monde du DevOps, vous avez forc&#xE9;ment crois&#xE9; GitHub Actions. Et parfois&#x2026; on se dit qu&#x2019;on aurait pr&#xE9;f&#xE9;r&#xE9; que nos chemins ne se soient jamais rencontr&#xE9;s.</p><p>Sur internet, les avis sont tr&#xE8;s partag&#xE9;s : certains adorent, d&#x2019;autres jurent que c&#x2019;est l&#x2019;enfer. La v&#xE9;rit&#xE9;, c&#x2019;est que beaucoup des critiques viennent surtout d&#x2019;une mauvaise utilisation de l&#x2019;outil.</p><p>Dans cet article, je vous raconte mon parcours avec GitHub Actions, pr&#xE9;sent&#xE9; sous la forme d&#x2019;une &#x201C;semaine fictive&#x201D; inspir&#xE9;e de la Gen&#xE8;se : mes d&#xE9;buts chaotiques, mes erreurs, mes d&#xE9;couvertes&#x2026; et comment j&#x2019;ai fini par passer de l&#x2019;enfer au paradis.</p><h1 id="jour-1-la-rencontre">Jour 1 : La rencontre</h1><p>Ma premi&#xE8;re rencontre avec le monde du CI/CD s&#x2019;est faite avec GitHub Actions. Et, de mani&#xE8;re totalement illogique, ma premi&#xE8;re id&#xE9;e a &#xE9;t&#xE9; de lancer&#x2026; des tests automatis&#xE9;s. Sauf qu&#x2019;&#xE0; l&#x2019;&#xE9;poque, je n&#x2019;&#xE9;crivais quasiment pas de tests. Allez comprendre.</p><p>Apr&#xE8;s une lecture en diagonale de la documentation et quelques essais maladroits, j&#x2019;ai r&#xE9;ussi &#xE0; obtenir un workflow fonctionnel :</p><pre><code class="language-yaml">name: CI

on:
  push:
    branches: [ &quot;master&quot;, &quot;dev&quot; ]
  pull_request:
    branches: [ &quot;master&quot;, &quot;dev&quot; ]

# ...

jobs:
  build:

    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [16.x, 18.x]

    steps:
    - uses: actions/checkout@v3
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}
        cache: &apos;npm&apos;
    - run: npm ci
    - run: npx prisma migrate dev --name init
    - run: npm run build --if-present
    - run: npm test</code></pre><p>Tous les voyants &#xE9;taient au vert. J&#x2019;&#xE9;tais fier de moi, au sommet de la fameuse <a href="https://www.kinesiologie-marseille.com/dunning-kruger-effet-de-surconfiance-des-incompetents/?ref=charly-ginevra.fr" rel="noreferrer">&#x201C;montagne de la stupidit&#xE9;&#x201D;</a>. J&#x2019;&#xE9;tais donc encore bien loin d&#x2019;imaginer la suite.</p><p>Avec le recul, je vois bien les probl&#xE8;mes :</p><ul><li><strong>Un seul job fourre-tout</strong> : tout &#xE9;tait dans &#x201C;build&#x201D;, alors que &#xE7;a faisait plein d&#x2019;autres choses. Pas tr&#xE8;s clair.</li><li><strong>Des &#xE9;tapes sans vraie logique</strong> : pourquoi lancer une migration Prisma dans un job de CI ?</li><li><strong>Nom trompeur</strong> : &#x201C;build&#x201D; laissait penser qu&#x2019;on faisait uniquement de la compilation, alors que c&#x2019;&#xE9;tait un joyeux m&#xE9;lange de build, tests et scripts divers.</li></ul><p>Bref, un workflow petit mais d&#xE9;j&#xE0; bancal. Et comme souvent, quand on commence mal, &#xE7;a finit rarement bien&#x2026;</p><h1 id="jour-2-les-choses-s%C3%A9rieuses">Jour 2 : Les choses s&#xE9;rieuses</h1><p>Dans <em>GitHub Actions</em>, il y a le mot <em>&#x201C;action&#x201D;</em>. Et &#xE7;a peut vouloir dire deux choses :</p><ol><li><strong>L&#x2019;action au sens &#xE9;v&#xE9;nement &#x2192; r&#xE9;action</strong> : un push, un pull request, et hop, &#xE7;a d&#xE9;clenche un workflow.</li><li><strong>L&#x2019;action au sens GitHub</strong> : comme le dit la doc, <a href="https://docs.github.com/fr/actions/get-started/understand-github-actions?ref=charly-ginevra.fr#composants-de-github-actions" rel="noreferrer">&#x201C;une extension r&#xE9;utilisable qui peut simplifier votre workflow&#x201D;</a>.</li></ol><p>L&#x2019;id&#xE9;e est simple : des &#xE9;diteurs (ou la communaut&#xE9;) cr&#xE9;ent et testent ces actions, et nous, d&#xE9;veloppeurs, on peut les int&#xE9;grer directement dans nos workflows sans r&#xE9;inventer la roue. Tout est disponible sur la <a href="https://github.com/marketplace?ref=charly-ginevra.fr" rel="noreferrer">Marketplace GitHub</a>.</p><p>La philosophie est s&#xE9;duisante : un assemblage de &#x201C;bo&#xEE;tes noires&#x201D;, chacune sp&#xE9;cialis&#xE9;e dans une t&#xE2;che bien pr&#xE9;cise.</p><h2 id="mon-cas-concret-docker">Mon cas concret : Docker</h2><p>Pour l&#x2019;un de mes projets, je voulais automatiser la construction et le d&#xE9;ploiement d&#x2019;images Docker. Objectif : faire &#xE7;a dans les r&#xE8;gles de l&#x2019;art. Apr&#xE8;s une petite exploration de la marketplace&#x2026; bingo ! Docker fournit ses propres actions officielles. R&#xE9;sultat, j&#x2019;ai rapidement obtenu ce workflow :</p><pre><code class="language-yaml">name: Build docker image &amp; deploy

# ...

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: # ...
          password: # ...
      - name: Build and push
        uses: docker/build-push-action@v6
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          tags: # ...</code></pre><p>Sur le papier, c&#x2019;est nickel. Mais dans les faits&#x2026; comment je teste que ce workflow fonctionne ?</p><h2 id="le-vrai-probl%C3%A8me-tester">Le vrai probl&#xE8;me : tester</h2><p>&#xC0; ce stade, il n&#x2019;y a qu&#x2019;une seule solution : <strong>commit et push sur le d&#xE9;p&#xF4;t</strong>. Et si &#xE7;a ne marche pas ? On lit les logs, on change et on recommence.</p><p>Imaginez : on vous demande de d&#xE9;velopper une feature et la seule fa&#xE7;on de la tester, c&#x2019;est de la d&#xE9;ployer en production &#xE0; chaque essai. Vous voyez le souci ?</p><p>Alors oui, ce n&#x2019;est pas dramatique pour un projet perso on s&apos;en fiche sinon avec un peu de strat&#xE9;gie de branches, &#xE7;a limite la casse. Mais &#xE7;a reste franchement frustrant.</p><p>Et le pire, c&#x2019;est qu&#x2019;il n&#x2019;existe pas de solution native pour tester ses workflows en local (on parlera d&#x2019;<code>act</code> un peu plus tard &#x1F440;). R&#xE9;sultat : des commits en s&#xE9;rie, des allers-retours chronophages&#x2026; et quelques heures de cris et de larmes dans le processus.</p><h1 id="jour-3-un-peu-de-clart%C3%A9">Jour 3 : Un peu de clart&#xE9;</h1><p>Comme je l&#x2019;ai mentionn&#xE9; plus t&#xF4;t, l&#x2019;une des erreurs les plus courantes avec GitHub Actions, c&#x2019;est de vouloir tout entasser dans un seul job d&#x2019;un seul workflow.</p><p>R&#xE9;sultat ? On se prive d&#x2019;une vision claire de ce qui se passe, et le debug devient vite un enfer.</p><h2 id="le-probl%C3%A8me-du-%E2%80%9Cfourre-tout%E2%80%9D">Le probl&#xE8;me du &#x201C;fourre-tout&#x201D;</h2><p>Reprenons mon premier exemple : si le job s&#x2019;appelle <code>build</code> et qu&#x2019;il &#xE9;choue, que s&#x2019;est-il pass&#xE9; exactement ?</p><ul><li>Est-ce une d&#xE9;pendance qui a cass&#xE9; ?</li><li>Un probl&#xE8;me r&#xE9;seau ?</li><li>Une erreur dans la compilation ?</li><li>Ou bien un test qui a plant&#xE9; ?</li></ul><p>Impossible de le savoir sans plonger dans les logs. Et plus votre workflow grossit, plus &#xE7;a devient p&#xE9;nible.</p><h2 id="la-bonne-pratique-d%C3%A9couper">La bonne pratique : d&#xE9;couper</h2><p>La solution est simple : <strong>d&#xE9;couper le workflow en plusieurs jobs clairs et ind&#xE9;pendants</strong>.</p><p>Un sch&#xE9;ma g&#xE9;n&#xE9;rique :</p><ul><li><code>test</code> &#x2192; ex&#xE9;cuter la suite de tests</li><li><code>build</code> &#x2192; compiler / packager l&#x2019;application</li><li><code>deploy</code> &#x2192; livrer le produit</li></ul><h3 id="%E2%9A%A0%EF%B8%8F-attention-aux-parall%C3%A8les">&#x26A0;&#xFE0F; Attention aux parall&#xE8;les</h3><p>Par d&#xE9;faut, GitHub Actions ex&#xE9;cute les jobs <strong>en parall&#xE8;le</strong>. Ce qui est souvent tr&#xE8;s bien pour gagner du temps&#x2026; sauf quand on veut imposer un ordre logique (ex. : d&#xE9;ployer uniquement si les tests et le build sont pass&#xE9;s).</p><p>Pour g&#xE9;rer &#xE7;a, il suffit d&#x2019;utiliser l&#x2019;attribut <code>needs</code> pour indiquer les d&#xE9;pendances entre jobs. Exemple :</p><pre><code class="language-yaml">name: CI

on:
	...

jobs:
  test:
	# ...
  build:
    needs: [test]
	# ...
  deploy:
	needs: [build]
	# ...
</code></pre><p>Avec &#xE7;a, vos workflows deviennent beaucoup plus lisibles, et vos futurs &#x201C;vous&#x201D; (ou vos coll&#xE8;gues) vous remercieront le jour o&#xF9; il faudra comprendre pourquoi &#x201C;&#xE7;a marche pas&#x201D;.</p><h1 id="jour-4-act-la-fausse-bonne-id%C3%A9e">Jour 4 : Act, la fausse bonne id&#xE9;e ?</h1><p>Un jour, au milieu de mes errances, je suis tomb&#xE9; sur ce qui semblait &#xEA;tre <strong>l&#x2019;outil qui allait me sauver</strong> de mes commits compulsifs et de mes logs interminables.</p><p>Son nom : <a href="https://github.com/nektos/act?ref=charly-ginevra.fr" rel="noreferrer"><code>act</code></a>.<br>Sa promesse : <strong>ex&#xE9;cuter vos workflows</strong> GitHub Actions directement en <strong>local</strong>.</p><p>Sur les forums et ur YouTube, tout le monde en parlait. Je me suis dit : <em>&#x201C;ok, c&#x2019;est peut-&#xEA;tre la lumi&#xE8;re au bout du tunnel&#x201D;</em>.</p><h2 id="mes-premiers-pas-avec-act">Mes premiers pas avec <code>act</code></h2><p>Au d&#xE9;but, j&#x2019;&#xE9;tais sceptique : encore un outil &#xE0; installer, encore un truc &#xE0; apprendre. Mais &#xE0; force de pleurer sur mes workflows cass&#xE9;s, j&#x2019;ai fini par c&#xE9;der.</p><p>Et je dois avouer : la prise en main est agr&#xE9;able. L&#x2019;outil est bien con&#xE7;u, avec un affichage clair et lisible. On sent qu&#x2019;il y a eu du travail derri&#xE8;re.</p><h2 id="%E2%80%A6-et-les-ennuis-commencent">&#x2026; et les ennuis commencent</h2><p>Mais tr&#xE8;s vite, les premiers bugs sont apparus.</p><p>Un de mes workflows <strong>&#xE9;chouait en local</strong> <strong>alors qu&#x2019;il passait parfaitement sur GitHub</strong>. Apr&#xE8;s quelques recherches, je suis tomb&#xE9; sur <a href="https://github.com/nektos/act/issues/107?ref=charly-ginevra.fr" rel="noreferrer">cette issue</a> qui nous explique que certaines images utilis&#xE9;es par <code>act</code> n&#x2019;ont pas les m&#xEA;mes d&#xE9;pendances que les runners GitHub officiels.</p><p>Et l&#xE0;, on comprend le probl&#xE8;me :</p><ul><li><code>act</code> <strong>n&#x2019;est pas un outil officiel de GitHub</strong>.</li><li>Il simule un runner en utilisant des images Docker gigantesques (plusieurs Go).</li><li>R&#xE9;sultat : votre machine locale se transforme en centrale nucl&#xE9;aire juste pour lancer quelques scripts.</li><li>Et pour couronner le tout, certaines actions&#x2026; ne fonctionnent tout simplement pas.</li></ul><h2 id="mon-ressenti">Mon ressenti</h2><p>&#xC0; mon niveau, <code>act</code> s&#x2019;est r&#xE9;v&#xE9;l&#xE9; &#xEA;tre une <strong>fausse bonne id&#xE9;e</strong> : une belle machine &#xE0; gaz, qui promet beaucoup mais qui ne tient pas toujours ses promesses.</p><h1 id="jour-5-les-actions-deuxi%C3%A8me-fausse-bonne-id%C3%A9e">Jour 5 : Les actions, deuxi&#xE8;me fausse bonne id&#xE9;e ?</h1><p>Bon&#x2026; on ne va pas se mentir : jusque-l&#xE0;, c&#x2019;&#xE9;tait pas gagn&#xE9;.</p><p>Toujours pas moyen de tester facilement mes workflows, donc commits en rafale, temps perdu, et nerfs mis &#xE0; rude &#xE9;preuve.</p><p><em>C&#x2019;est donc &#xE7;a la vie, Manny ?</em></p><h2 id="le-vrai-probl%C3%A8me-les-actions-elles-m%C3%AAmes">Le vrai probl&#xE8;me : les actions elles-m&#xEA;mes</h2><p>En prenant du recul, j&#x2019;ai r&#xE9;alis&#xE9; que la racine du probl&#xE8;me n&#x2019;&#xE9;tait pas GitHub Actions en soi&#x2026; mais <strong>les actions</strong>.</p><p>Celles qu&#x2019;on nous vend comme la solution miracle sont en r&#xE9;alit&#xE9; parfois des pi&#xE8;ges qui nous enferment et rendent le travail encore plus compliqu&#xE9;.</p><p>Attention, je ne dis pas qu&#x2019;elles sont toutes mauvaises !</p><ul><li>Certaines sont <strong>incroyables</strong> : par exemple celles qui g&#xE8;rent les <em>artifacts</em>, super pratiques pour partager des fichiers entre jobs (voire entre workflows).</li><li>Mais d&#x2019;autres&#x2026; franchement, leur valeur ajout&#xE9;e est faible par rapport aux gal&#xE8;res qu&#x2019;elles am&#xE8;nent. Exemple typique : les actions pour builder et pousser une image Docker. &#xC7;a peut para&#xEE;tre sexy, mais en pratique, quelques commandes shell suffisent largement.</li></ul><h2 id="ma-solution-reprendre-la-main">Ma solution : reprendre la main</h2><p>&#xC0; partir de l&#xE0;, j&#x2019;ai d&#xE9;cid&#xE9; de r&#xE9;duire au maximum ma d&#xE9;pendance aux actions.</p><p>J&#x2019;ai cr&#xE9;&#xE9; un d&#xE9;p&#xF4;t d&#xE9;di&#xE9; o&#xF9; je centralise mes <strong>scripts Python</strong> pour effectuer des t&#xE2;ches g&#xE9;n&#xE9;riques (tag, release, docker, etc.), peu importe la techno du projet.</p><p>&#xC7;a me donne une base testable, r&#xE9;utilisable et ind&#xE9;pendante.</p><p>Pour lancer un process, il me suffit de cloner le repo, installer les d&#xE9;pendances&#x2026; et c&#x2019;est parti !</p><p>Mon d&#xE9;p&#xF4;t est disponible ici : </p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://github.com/CharlyGin/pipelines?ref=charly-ginevra.fr"><div class="kg-bookmark-content"><div class="kg-bookmark-title">GitHub - CharlyGin/pipelines</div><div class="kg-bookmark-description">Contribute to CharlyGin/pipelines development by creating an account on GitHub.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" alt="GitHub Actions : De l&#x2019;enfer au paradis"><span class="kg-bookmark-author">GitHub</span><span class="kg-bookmark-publisher">CharlyGin</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://opengraph.githubassets.com/f3d0c499ee4ad69a03e57be224c8c35bc56c0a3bf1af7bcaa523e39a8cc126bb/CharlyGin/pipelines" alt="GitHub Actions : De l&#x2019;enfer au paradis"></div></a></figure><p>Exemple d&#x2019;utilisation dans un workflow :</p><pre><code class="language-yaml">on:
	# ...
	
jobs:
	# ...
	release:
    runs-on: ubuntu-latest
    needs: [test, build, check-version]
    if: needs.check-version.outputs.should-release == &apos;true&apos;
    permissions:
      contents: write
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          name: ${{ github.sha }}
      - name: Install uv
        run: |
          sudo apt update
          sudo apt install -y curl
          sudo curl -LsSf https://astral.sh/uv/install.sh | sh
        shell: bash
      - name: Clone pipelines
        run: |
          cd ~
          git clone https://github.com/CharlyGin/pipelines.git
        shell: bash
      - name: Install dependencies
        run: |
          cd ~/pipelines
          uv sync
        shell: bash
      - name: Run Tag &amp; Release
        run: |
          VERSION=$(jq -r &apos;.version&apos; package.json)
          uv run ~/pipelines/scripts/tag_and_release.py --pre-release --tag $VERSION --app $GITHUB_WORKSPACE --build-dir /dist
        env:
          GH_TOKEN: ${{ secrets.GH_TOKEN }}
        shell: bash</code></pre><h2 id="clarifier-les-workflows">Clarifier les workflows</h2><p>Autre souci : les petits bouts de scripts shell &#xE9;parpill&#xE9;s dans les steps.</p><p>&#xC7;a pollue la lecture des workflows et c&#x2019;est une nouvelle source de bugs (puisqu&#x2019;impossible &#xE0; tester directement).</p><p>Ma solution : les d&#xE9;placer dans des scripts d&#xE9;di&#xE9;s, par exemple dans un dossier <code>.github/scripts</code>.</p><p>Par cons&#xE9;quent, mes workflows ne contiennent plus de logique. Ils se contentent de d&#xE9;clencher des scripts clairs, testables et versionn&#xE9;s. La lisibilit&#xE9; est bien meilleure, et le debug devient plus simple.</p><h1 id="jour-6-un-peu-beaucoup-dorganisation">Jour 6 : Un peu (beaucoup) d&apos;organisation</h1><p>Arriv&#xE9; &#xE0; ce stade, j&#x2019;avais fait du m&#xE9;nage dans mes workflows en externalisant mes scripts. Pourtant, un nouveau probl&#xE8;me est apparu. Je me retrouvais avec <strong>les m&#xEA;mes scripts appel&#xE9;s plusieurs fois</strong>.</p><p>Par exemple :</p><ul><li>une fois pour tester les PRs,</li><li>une fois pour faire une pr&#xE9;-release,</li><li>et encore une autre pour la release finale.</li></ul><p>Bref, beaucoup de r&#xE9;p&#xE9;tition, et une forte envie de factoriser tout &#xE7;a.</p><h2 id="la-solution-workflowcall">La solution : <code>workflow_call</code></h2><p>Heureusement, GitHub Actions propose une fonctionnalit&#xE9; taill&#xE9;e pour &#xE7;a : l&#x2019;&#xE9;v&#xE9;nement <code>workflow_call</code>.</p><p>L&#x2019;id&#xE9;e est simple :</p><ul><li>cr&#xE9;er un workflow par fonction (ex. : <code>test.yml</code>, <code>build.yml</code>, <code>deploy.yml</code>),</li><li>leur passer des param&#xE8;tres (par exemple <code>is_pre-release</code>),</li><li>et les appeler depuis d&#x2019;autres workflows.</li></ul><p>C&#x2019;est propre, c&#x2019;est r&#xE9;utilisable et &#xE7;a r&#xE9;duit &#xE9;norm&#xE9;ment la duplication.</p><h2 id="plus-de-flexibilit%C3%A9-workflowdispatch">Plus de flexibilit&#xE9; : <code>workflow_dispatch</code></h2><p>J&#x2019;ai ajout&#xE9; en bonus l&#x2019;&#xE9;v&#xE9;nement <code>workflow_dispatch</code>.</p><p>Pourquoi ? Pour pouvoir lancer un workflow manuellement en cas de besoin (ex. : un bug qui bloque la release automatique).</p><p>Autre avantage, les workflows s&#x2019;ex&#xE9;cutent dans l&#x2019;environnement GitHub et donc avec acc&#xE8;s aux <strong>secrets</strong> d&#xE9;finis dans le repo, sans que les autres d&#xE9;veloppeurs aient besoin de les stocker (ni d&#x2019;y avoir acc&#xE8;s, d&#x2019;ailleurs &#x1F605;).</p><h1 id="jour-7-conclusion">Jour 7 : Conclusion</h1><p>Beaucoup de rage, quelques larmes et un certain nombre de commits inutiles ont &#xE9;t&#xE9; sacrifi&#xE9;s au cours de cette semaine fictive. Mais comme on dit : <em>apr&#xE8;s la pluie vient le beau temps</em>.</p><p>En chemin, j&#x2019;ai appris :</p><ul><li>&#xE0; &#xE9;viter les jobs fourre-tout,</li><li>&#xE0; me m&#xE9;fier des fausses bonnes id&#xE9;es (<code>act</code> ou certaines actions),</li><li>&#xE0; privil&#xE9;gier mes propres scripts pour garder la main,</li><li>et &#xE0; organiser mes workflows avec <code>workflow_call</code> et <code>workflow_dispatch</code> pour plus de clart&#xE9; et de souplesse.</li></ul><p><strong>GitHub Actions vaut clairement le coup.</strong> Cet outil peut sembler compliqu&#xE9; au d&#xE9;but, mais il est puissant et flexible. Les actions int&#xE9;gr&#xE9;es sont souvent pratiques, mais il ne faut pas h&#xE9;siter &#xE0; reprendre la main quand elles deviennent trop contraignantes. <strong>Avec de l&#x2019;organisation et de la patience, on passe vite de l&#x2019;enfer au paradis.</strong></p><p>Vous pouvez trouver un exemple concret de cette structure dans un template de package Python que j&#x2019;ai cr&#xE9;&#xE9; :</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://github.com/CharlyGin/say_hello?ref=charly-ginevra.fr"><div class="kg-bookmark-content"><div class="kg-bookmark-title">GitHub - CharlyGin/say_hello: Template Python Package using UV</div><div class="kg-bookmark-description">Template Python Package using UV. Contribute to CharlyGin/say_hello development by creating an account on GitHub.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" alt="GitHub Actions : De l&#x2019;enfer au paradis"><span class="kg-bookmark-author">GitHub</span><span class="kg-bookmark-publisher">CharlyGin</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://opengraph.githubassets.com/156cc345e87898b3bbccedf129e2627b928dbe0b15dd733b6e853a9982c0c5f0/CharlyGin/say_hello" alt="GitHub Actions : De l&#x2019;enfer au paradis"></div></a></figure><h1 id="sources">Sources</h1><ul><li><a href="https://docs.github.com/fr/actions?ref=charly-ginevra.fr" rel="noreferrer">GitHub Actions Documentation</a></li><li><a href="https://www.reddit.com/r/devops/comments/1cyo1xm/unpopular_opinion_why_do_you_hate_github_actions/?ref=charly-ginevra.fr" rel="noreferrer">Unpopular opinion: why do you hate GitHub actions ? - Reddit</a></li><li><a href="https://www.reddit.com/r/devops/comments/1bpz8zu/how_do_you_test_github_actions/?ref=charly-ginevra.fr" rel="noreferrer">how do you test github actions - Reddit</a></li><li><a href="https://news.ycombinator.com/item?id=42764762&amp;ref=charly-ginevra.fr" rel="noreferrer">I&apos;ll think twice before using GitHub Actions again - Hacker News</a></li></ul>]]></content:encoded></item><item><title><![CDATA[Utiliser un CDN éco-conçu pour de meilleures performances]]></title><description><![CDATA[<blockquote><strong>TLDR;</strong> J&#x2019;ai mis en place mon propre CDN bas&#xE9; sur Nginx, optimis&#xE9; avec Brotli et quelques bonnes pratiques. R&#xE9;sultat : des performances am&#xE9;lior&#xE9;es et un meilleur contr&#xF4;le sur la gestion de mes assets.</blockquote><p>La gestion des fichiers statiques (images,</p>]]></description><link>https://charly-ginevra.fr/utilisez-un-cdn-pour-avoir-de-meilleurs-performances/</link><guid isPermaLink="false">68888e3f5c08a10001756d68</guid><category><![CDATA[Informatique]]></category><category><![CDATA[Ecoconception]]></category><category><![CDATA[Nginx]]></category><dc:creator><![CDATA[Charly]]></dc:creator><pubDate>Thu, 31 Jul 2025 14:48:09 GMT</pubDate><media:content url="https://charly-ginevra.fr/content/images/2025/07/content-delivery-server-logo.png" medium="image"/><content:encoded><![CDATA[<blockquote><strong>TLDR;</strong> J&#x2019;ai mis en place mon propre CDN bas&#xE9; sur Nginx, optimis&#xE9; avec Brotli et quelques bonnes pratiques. R&#xE9;sultat : des performances am&#xE9;lior&#xE9;es et un meilleur contr&#xF4;le sur la gestion de mes assets.</blockquote><img src="https://charly-ginevra.fr/content/images/2025/07/content-delivery-server-logo.png" alt="Utiliser un CDN &#xE9;co-con&#xE7;u pour de meilleures performances"><p>La gestion des fichiers statiques (images, scripts, feuilles de styles) dans mes applications a longtemps &#xE9;t&#xE9; un vrai sujet pour moi. &#xC0; plusieurs reprises on m&apos;a d&#xE9;conseill&#xE9; de les d&#xE9;poser dans le gestionnaire de version. C&apos;est pourtant ce que j&apos;ai fait par simplicit&#xE9;. Mais aujourd&#x2019;hui, j&#x2019;ai franchi une &#xE9;tape : je suis pass&#xE9; &#xE0; une solution plus propre et plus performante&#x2026; un CDN maison.</p><h1 id="le-livre-qui-tout-d%C3%A9clench%C3%A9">Le livre qui tout d&#xE9;clench&#xE9;</h1><p>R&#xE9;cemment, je suis tomb&#xE9; sur <a href="https://www.fnac.com/a21295266/Frederic-Bordage-Ecoconception-web-les-115-bonnes-pratiques?ref=charly-ginevra.fr" rel="noreferrer"><em>&#xC9;coconception web &#x2013; Les 115 bonnes pratiques</em></a> de Fr&#xE9;d&#xE9;ric Bordage. Dans cet ouvrage, l&#x2019;auteur, ancien d&#xE9;veloppeur et architecte logiciel, explique comment r&#xE9;duire l&#x2019;impact environnemental d&#x2019;un site web en prenant en compte l&#x2019;ensemble de son cycle de vie : de la conception jusqu&#x2019;&#xE0; sa fin de vie, en passant par le d&#xE9;veloppement, la maintenance et l&#x2019;exploitation.</p>
<!--kg-card-begin: html-->
<div style="display: flex; flex-direction: column; align-items: center; justify-content: center;">
  <img src="https://i0.wp.com/www.greenit.fr/wp-content/uploads/2025/06/3D-Ecoconception-web.small_.png?fit=738%2C738&amp;ssl=1" style="max-width: 500px" alt="Utiliser un CDN &#xE9;co-con&#xE7;u pour de meilleures performances">
  <div style="color: gray;">Couverture du livre <i>&#xC9;coconception web - Les 115 bonnes pratiques</i></div>
</div>
<!--kg-card-end: html-->
<h2 id="l%C3%A9co-conception-levier-de-performance">L&apos;&#xE9;co-conception, levier de performance</h2><p>Au premier abord, on pourrait s&#x2019;attendre &#xE0; un discours moralisateur, ou &#xE0; une invitation &#xE0; revenir &#xE0; des sites ultra-sobres dignes du web des ann&#xE9;es 90. Mais ce n&#x2019;est pas le cas.</p><p>L&#x2019;approche d&#xE9;fendue par Fr&#xE9;d&#xE9;ric Bordage repose sur un principe simple : consommer moins de ressources, c&#x2019;est aussi am&#xE9;liorer les performances... et r&#xE9;duire les co&#xFB;ts. Cela passe par l&#x2019;optimisation du code, une infrastructure mieux calibr&#xE9;e, et des choix techniques plus pertinents.</p><p>Loin d&#x2019;un discours alarmiste, cette d&#xE9;marche repose sur une r&#xE9;elle expertise technique. L&#x2019;&#xE9;co-conception, bien appliqu&#xE9;e, n&#x2019;est pas une contrainte mais d&#xE9;note d&apos;une qualit&#xE9; sup&#xE9;rieure.</p><h2 id="rester-critique-et-adapter">Rester critique et adapter</h2><p>M&#xEA;me si je recommande vivement ce livre, il est important de garder un esprit critique et de contextualiser les recommandations propos&#xE9;es.</p><p>Toutes les bonnes pratiques &#xE9;voqu&#xE9;es ne sont pas n&#xE9;cessairement applicables telles quelles. Certaines peuvent m&#xEA;me &#xEA;tre contre-productives selon votre projet.</p><p>Par exemple, l&#x2019;ouvrage cite <a href="http://gwan.com/?ref=charly-ginevra.fr" rel="noreferrer">G-WAN</a>, un serveur web aux performances impressionnantes, bien sup&#xE9;rieures &#xE0; celles de Nginx. Mais ce qu&#x2019;il ne pr&#xE9;cise pas, c&#x2019;est que <a href="http://gwan.com/?ref=charly-ginevra.fr" rel="noreferrer">G-WAN</a> n&#x2019;est plus maintenu depuis 2016. Ce genre de d&#xE9;tail peut induire en erreur si l&#x2019;on ne creuse pas un peu.</p><h1 id="mon-serveur-cdn">Mon serveur CDN</h1><p>Revenons nos moutons. Apr&#xE8;s la lecture du livre de Fr&#xE9;d&#xE9;ric Bordage, j&#x2019;ai pu &#xE9;tablir une liste claire de ce qui me semblait indispensable pour construire un CDN adapt&#xE9; &#xE0; mes besoins.</p><h2 id="maximiser-la-mise-en-cache">Maximiser la mise en cache</h2><p>Pour &#xE9;viter que le navigateur du client ne redemande &#xE0; chaque fois les fichiers statiques (styles, scripts, images&#x2026;), il est crucial de configurer un cache efficace. Cela permet non seulement de gagner en bande passante, mais aussi d&#x2019;all&#xE9;ger la charge serveur.</p><p>En production, ces fichiers changent rarement. Le principal inconv&#xE9;nient serait qu&#x2019;un utilisateur doive vider manuellement son cache&#x2026; ce qui reste g&#xE9;rable (quoique ?).</p><p>Pensez donc &#xE0; ajouter <code>expires max;</code> dans vos directives Nginx pour indiquer une dur&#xE9;e de cache tr&#xE8;s longue.</p><h2 id="compresser-les-fichiers-textes">Compresser les fichiers textes </h2><p>Toujours dans une optique de r&#xE9;duction du poids des &#xE9;changes, la compression des fichiers texte (HTML, CSS, JS, JSON, etc.) &#xE0; la vol&#xE9;e est un incontournable.</p><p>Deux m&#xE9;thodes sont couramment utilis&#xE9;es : Brotli, plus performante, et Gzip, &#xE0; d&#xE9;faut.</p><p>Voici un exemple de configuration :</p><pre><code class="language-nginx"># gzip
gzip              on;
gzip_vary         on;
gzip_proxied      any;
gzip_comp_level   6;
gzip_types        text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;

# brotli
brotli            on;
brotli_comp_level 6;
brotli_types      text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
</code></pre>
<p>Si vous avez acc&#xE8;s &#xE0; une version payante de Nginx, l&#x2019;activation de Brotli est simple. Elle peut se faire via un gestionnaire de paquet classique. Sinon, il faudra le compiler depuis les sources. Le <a href="https://github.com/google/brotli?ref=charly-ginevra.fr" rel="noopener">README du d&#xE9;p&#xF4;t GitHub de Brotli</a> vous guidera, et en cas de doute mon <a href="https://github.com/CharlyGin/Content-Delivery-Server?ref=charly-ginevra.fr" rel="noopener">Dockerfile</a> pourra aussi vous servir d&apos;exemple.</p><blockquote>&#x1F4A1; Cette compression est encore plus efficace si vous <strong>minifiez</strong> les fichiers en amont (suppression des commentaires, espaces inutiles&#x2026;).</blockquote><h2 id="utiliser-http2">Utiliser HTTP/2</h2><p>La version 2 du protocole HTTP apporte de nombreuses am&#xE9;liorations en mati&#xE8;re de performance, notamment gr&#xE2;ce au multiplexage.</p><p>Pour en savoir plus, je vous recommande <a rel="noopener">cet excellent article sur Zeste de Savoir</a>. Il explique tr&#xE8;s bien les principes et l&#x2019;impl&#xE9;mentation derri&#xE8;re un reverse proxy.</p><p>Dans votre configuration Nginx, vous pouvez l&apos;activer avec la directive <code>http2 on;</code>.</p><h2 id="r%C3%A9duire-les-logs-en-production">R&#xE9;duire les logs en production</h2><p>Les logs sont pr&#xE9;cieux en d&#xE9;veloppement ou pour diagnostiquer un incident. Mais en production, ils peuvent vite devenir verbeux, peu utiles et consommer des ressources.</p><p>L&#x2019;id&#xE9;e ici est de ne garder que l&#x2019;essentiel, &#xE0; savoir les avertissements et erreurs. Exemple de configuration :</p><pre><code class="language-nginx">access_log off;
error_log /var/log/nginx/error.log warn;

location = /favicon.ico {
    log_not_found off;
}

location = /robots.txt {
    log_not_found off;
}
</code></pre>
<h2 id="supprimer-les-cookies-inutiles">Supprimer les cookies inutiles</h2><p>Dans le contexte d&#x2019;un CDN, les cookies n&#x2019;ont souvent aucune utilit&#xE9;. Les inclure dans les r&#xE9;ponses ne fait qu&#x2019;augmenter inutilement le poids des requ&#xEA;tes.</p><p>Voici comment les supprimer proprement :</p><pre><code class="language-nginx">proxy_hide_header Set-Cookie;
fastcgi_hide_header Set-Cookie;
add_header Set-Cookie &quot;&quot; always;
</code></pre>
<h1 id="conclusion">Conclusion</h1><p>Vous pouvez retrouver l&#x2019;int&#xE9;gralit&#xE9; du projet sur GitHub :</p><figure class="kg-card kg-bookmark-card kg-card-hascaption"><a class="kg-bookmark-container" href="https://github.com/CharlyGin/Content-Delivery-Server?ref=charly-ginevra.fr"><div class="kg-bookmark-content"><div class="kg-bookmark-title">GitHub - CharlyGin/Content-Delivery-Server: Content delivery server</div><div class="kg-bookmark-description">Content delivery server . Contribute to CharlyGin/Content-Delivery-Server development by creating an account on GitHub.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" alt="Utiliser un CDN &#xE9;co-con&#xE7;u pour de meilleures performances"><span class="kg-bookmark-author">GitHub</span><span class="kg-bookmark-publisher">CharlyGin</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://opengraph.githubassets.com/1a0beac3a286cd5d86681010e724da941056843b9aed66a42c08ffb2a7b9383b/CharlyGin/Content-Delivery-Server" alt="Utiliser un CDN &#xE9;co-con&#xE7;u pour de meilleures performances"></div></a><figcaption><p><span style="white-space: pre-wrap;">D&#xE9;p&#xF4;t Github du projet</span></p></figcaption></figure><p>Et l&#x2019;image Docker associ&#xE9;e est disponible sur <a href="https://hub.docker.com/r/carlitog/content-delivery-server?ref=charly-ginevra.fr" rel="noreferrer">Docker Hub</a>, pr&#xEA;te &#xE0; &#xEA;tre utilis&#xE9;e.</p><p>Ce projet a &#xE9;t&#xE9; l&#x2019;occasion id&#xE9;ale pour me replonger dans la configuration Nginx et concevoir une solution adapt&#xE9;e &#xE0; mes besoins en termes de distribution de contenu.</p><p>La lecture des <em>115 bonnes pratiques</em> m&#x2019;a ouvert de nouvelles perspectives, et j&#x2019;ai h&#xE2;te de continuer &#xE0; les explorer dans mes prochains projets.</p><p>Bien s&#xFB;r, il reste des pistes d&#x2019;am&#xE9;lioration, notamment en int&#xE9;grant des outils comme la minification automatique ou la suppression des m&#xE9;tadonn&#xE9;es. Une version 2 plus compl&#xE8;te, orient&#xE9;e performance et automatisation, pourrait voir le jour ?</p><h1 id="sources">Sources</h1><ul><li><a href="https://www.fnac.com/a21295266/Frederic-Bordage-Ecoconception-web-les-115-bonnes-pratiques?ref=charly-ginevra.fr" rel="noreferrer">Les 115 bonnes pratiques 5&#xE8;me &#xE9;dition</a> - Livre de Fr&#xE9;d&#xE9;ric Bordage</li><li><a href="https://www.digitalocean.com/community/tools/nginx?ref=charly-ginevra.fr" rel="noreferrer">NGINXConfig - Digital Ocean</a> - G&#xE9;n&#xE9;rateur de configuration Nginx en ligne</li><li><a href="https://www.f5.com/content/dam/f5/corp/global/pdf/ebooks/NGINX_Cookbook-final.pdf?ref=charly-ginevra.fr" rel="noreferrer">Nginx Cookbook - F5</a> - Recueil de bonnes pratiques pour Nginx</li><li><a href="https://github.com/google/ngx_brotli?ref=charly-ginevra.fr" rel="noreferrer">ngx_brotli - Github</a> - Module Brotli pour Nginx</li></ul>]]></content:encoded></item><item><title><![CDATA[Chrono-Sport : Pour vos entraînements cardio]]></title><description><![CDATA[<p>Pratiquant de musculation depuis plusieurs ann&#xE9;es, je me suis r&#xE9;cemment int&#xE9;ress&#xE9;  au monde des <a href="https://fr.wikipedia.org/wiki/Girevoy?ref=charly-ginevra.fr" rel="noreferrer">kettlebells</a>, un univers fascinant qui fera s&#xFB;rement l&apos;objet de mon prochain projet. </p><p>Au fil de mes recherches, j&#x2019;ai d&#xE9;couvert l&#x2019;</p>]]></description><link>https://charly-ginevra.fr/chrono-sport-pour-votre-cardio/</link><guid isPermaLink="false">685ecad15c08a10001756a82</guid><dc:creator><![CDATA[Charly]]></dc:creator><pubDate>Thu, 03 Jul 2025 07:31:44 GMT</pubDate><media:content url="https://charly-ginevra.fr/content/images/2025/06/favicon-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://charly-ginevra.fr/content/images/2025/06/favicon-1.png" alt="Chrono-Sport : Pour vos entra&#xEE;nements cardio"><p>Pratiquant de musculation depuis plusieurs ann&#xE9;es, je me suis r&#xE9;cemment int&#xE9;ress&#xE9;  au monde des <a href="https://fr.wikipedia.org/wiki/Girevoy?ref=charly-ginevra.fr" rel="noreferrer">kettlebells</a>, un univers fascinant qui fera s&#xFB;rement l&apos;objet de mon prochain projet. </p><p>Au fil de mes recherches, j&#x2019;ai d&#xE9;couvert l&#x2019;excellent livre du chercheur <a href="https://martingibala.com/?ref=charly-ginevra.fr" rel="noreferrer">Martin Gibala</a>, <a href="https://www.amazon.com/One-Minute-Workout-Science-Smarter-Shorter/dp/0399183663?ref=charly-ginevra.fr" rel="noreferrer"><em>The One Minute Workout</em></a>. Dans ce dernier, le professeur nous explique son parcours et comment lui et son &#xE9;quipe en sont venus &#xE0; la conclusion qu&apos;un activit&#xE9; physique courte mais intense avait plus d&apos;effets b&#xE9;n&#xE9;fiques qu&apos;une activit&#xE9; longue &#xE0; faible intensit&#xE9;.</p><p>Dans son livre, l&apos;auteur propose plusieurs exemples d&apos;entra&#xEE;nements et incite les lecteurs &#xE0; concevoir leurs propres s&#xE9;ances. C&apos;est dans cette optique-l&#xE0; que m&apos;est venue l&apos;id&#xE9;e de cr&#xE9;er une application pour faciliter cette op&#xE9;ration, <a href="http://chrono-sport.charly-ginevra.fr/?ref=charly-ginevra.fr" rel="noreferrer"><em>Chrono-Sport</em></a>.</p><h2 id="un-peu-de-th%C3%A9orie">Un peu de th&#xE9;orie</h2><p>Avant de commencer le d&#xE9;veloppement, il m&#x2019;a fallu r&#xE9;fl&#xE9;chir &#xE0; une mani&#xE8;re de g&#xE9;n&#xE9;raliser un entra&#xEE;nement dit &quot;&#xE0; haute intensit&#xE9;&quot;.</p><p>Dans la majorit&#xE9; des cas, ce type d&#x2019;entra&#xEE;nement se structure autour de trois phases :</p><ol><li><strong>L&#x2019;&#xE9;chauffement</strong> : il permet d&#x2019;augmenter la temp&#xE9;rature corporelle et de lubrifier les articulations.</li><li><strong>La phase de travail</strong> : elle se compose de cycles comprenant un ou plusieurs exercices r&#xE9;alis&#xE9;s &#xE0; diff&#xE9;rentes intensit&#xE9;s, pendant un temps donn&#xE9;.</li><li><strong>Le retour au calme</strong> : il vise &#xE0; faire redescendre le rythme cardiaque et retrouver une respiration normale.</li></ol><p>Un cycle de la phase de travail peut &#xEA;tre vu comme un <em>round</em> dans lequel un ou plusieurs chronom&#xE8;tres se succ&#xE8;dent.</p><p>Cette observation m&#x2019;a permis de mod&#xE9;liser un entra&#xEE;nement de mani&#xE8;re abstraite, comme une succession de blocs chronom&#xE9;tr&#xE9;s.</p><p>Voici un sch&#xE9;ma illustrant le d&#xE9;roul&#xE9; th&#xE9;orique d&#x2019;une s&#xE9;ance de cardio :</p>
<!--kg-card-begin: html-->
<div style="display: flex; flex-direction: column; align-items: center; justify-content: center;">
  <img src="https://charly-ginevra.fr/content/images/2025/06/theorie.svg" style="max-width: 500px" alt="Chrono-Sport : Pour vos entra&#xEE;nements cardio">
  <div style="color: gray;">Sch&#xE9;ma th&#xE9;orique du d&#xE9;roul&#xE9; d&apos;une s&#xE9;ance de cardio</div>
</div>
<!--kg-card-end: html-->
<p>Si on applique ce mod&#xE8;le au format Tabata, on obtient la structure suivante :</p>
<!--kg-card-begin: html-->
<div style="display: flex; flex-direction: column; align-items: center; justify-content: center;">
  <img src="https://charly-ginevra.fr/content/images/2025/06/tabata.svg" style="max-width: 500px" alt="Chrono-Sport : Pour vos entra&#xEE;nements cardio">
  <div style="color: gray;">Sch&#xE9;ma d&#xE9;roul&#xE9; d&apos;une s&#xE9;ance de tabata</div>
</div>
<!--kg-card-end: html-->
<p>Gr&#xE2;ce &#xE0; sa simplicit&#xE9; et &#xE0; sa flexibilit&#xE9;, ce mod&#xE8;le m&#x2019;a sembl&#xE9; suffisamment robuste pour servir de base &#xE0; l&#x2019;application.</p>
<!--kg-card-begin: html-->
<h2 id="un-peu-de-technique">Un peu de technique</h2>
<!--kg-card-end: html-->
<p>Jusqu&#x2019;&#xE0; pr&#xE9;sent, j&#x2019;ai toujours d&#xE9;velopp&#xE9; mes projets web avec le framework <a href="https://vuejs.org/?ref=charly-ginevra.fr" rel="noreferrer">VueJS</a>. Pour cette nouvelle exp&#xE9;rience, j&#x2019;ai voulu explorer une alternative moins courante. Plut&#xF4;t que de se tourner vers les g&#xE9;ants comme <a href="https://fr.react.dev/?ref=charly-ginevra.fr" rel="noreferrer">React</a> ou <a href="https://angular.dev/?ref=charly-ginevra.fr" rel="noreferrer">Angular</a>, j&apos;ai choisi <a href="https://www.solidjs.com/?ref=charly-ginevra.fr" rel="noreferrer"><strong>SolidJS</strong></a>. Sa simplicit&#xE9; d&#x2019;apprentissage et ses excellentes performances m&#x2019;ont rapidement convaincu.</p><p>J&apos;ai &#xE9;galement d&#xE9;cid&#xE9; de le combiner avec la puissance de <a href="https://www.typescriptlang.org/?ref=charly-ginevra.fr" rel="noreferrer"><strong>TypeSript</strong></a> pour le typage, ainsi qu&apos;avec <a href="https://sass-lang.com/?ref=charly-ginevra.fr" rel="noreferrer"><strong>Sass</strong></a> pour mieux organiser et isoler le style de mes composants.</p>
<!--kg-card-begin: html-->
<div style="display: flex; flex-direction: column; align-items: center; justify-content: center;">
  <img src="https://i.imgflip.com/9yv2a5.jpg" style="max-width: 400px" alt="Chrono-Sport : Pour vos entra&#xEE;nements cardio">
</div>
<!--kg-card-end: html-->
<p>C&#xF4;t&#xE9; qualit&#xE9; de code, j&#x2019;ai int&#xE9;gr&#xE9; <a href="https://prettier.io/?ref=charly-ginevra.fr" rel="noreferrer"><strong>Prettier</strong></a>, qui formate automatiquement le code &#xE0; chaque sauvegarde. Toutefois, je n&apos;ai pas mis en place de linter comme <a href="https://eslint.org/?ref=charly-ginevra.fr" rel="noreferrer">ESlint</a> ou ni d&apos;outils de pr&#xE9;-commit tels que <a href="https://typicode.github.io/husky/?ref=charly-ginevra.fr" rel="noreferrer">Husky</a>. &#xC9;tant donn&#xE9; qu&#x2019;il s&#x2019;agit d&#x2019;un projet personnel, j&#x2019;ai jug&#xE9; leur valeur ajout&#xE9;e trop faible par rapport &#xE0; leur mise en place.</p><p>Pour &#xE9;crire le code, j&apos;ai utilis&#xE9; <a href="https://www.cursor.com/?ref=charly-ginevra.fr" rel="noreferrer"><strong>Cursor</strong></a>, une premi&#xE8;re pour moi. Et je dois dire que j&#x2019;ai &#xE9;t&#xE9; agr&#xE9;ablement surpris. Bien que les suggestions ne soient pas toujours parfaites, l&#x2019;&#xE9;diteur m&#x2019;a permis de gagner un temps consid&#xE9;rable sur certaines t&#xE2;ches.</p><p>Enfin, c&#xF4;t&#xE9; CI/CD, je n&#x2019;ai pas voulu mettre en place une pipeline complexe avec <a href="https://github.com/features/actions?ref=charly-ginevra.fr" rel="noreferrer">Github Actions</a>. Par souci de simplicit&#xE9;, je me suis tourn&#xE9; vers <a href="https://vercel.com/?ref=charly-ginevra.fr" rel="noreferrer"><strong>Vercel</strong></a> , qui me permet de d&#xE9;ployer gratuitement deux environnements :</p><ul><li>la branche <code>dev</code> pour l&#x2019;environnement de d&#xE9;veloppement</li><li>la branche <code>main</code> pour la production</li></ul><p>Gr&#xE2;ce &#xE0; une redirection, l&#x2019;application est accessible via mon nom de domaine personnalis&#xE9; : <a href="chrono-sport.charly-ginevra.fr" rel="noreferrer">chrono-sport.charly-ginevra.fr</a></p><p>Voici un sch&#xE9;ma qui r&#xE9;sume cette architecture :</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://charly-ginevra.fr/content/images/2025/06/chrono-sport-code-flow.drawio.png" class="kg-image" alt="Chrono-Sport : Pour vos entra&#xEE;nements cardio" loading="lazy" width="946" height="230" srcset="https://charly-ginevra.fr/content/images/size/w600/2025/06/chrono-sport-code-flow.drawio.png 600w, https://charly-ginevra.fr/content/images/2025/06/chrono-sport-code-flow.drawio.png 946w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Sch&#xE9;ma : Chrono-Sport Code Flow</span></figcaption></figure><h2 id="un-peu-de-pratique">Un peu de pratique</h2><p>Maintenant, il est temps de mettre les mains dans le cambouis et d&apos;utiliser l&apos;application.</p><p>Vous pouvez y acc&#xE9;der via ce lien : <a href="https://chrono-sport.charly-ginevra.fr/?ref=charly-ginevra.fr" rel="noreferrer">https://chrono-sport.charly-ginevra.fr</a></p><h3 id="menu-principal">Menu principal</h3><p>Voici une capture d&#x2019;&#xE9;cran du menu principal de l&#x2019;application. On y trouve trois sections distinctes :</p><ul><li><strong>Classic</strong> : contient une horloge ainsi qu&#x2019;un chronom&#xE8;tre simple.</li><li><strong>Workouts</strong> : propose des entra&#xEE;nements inspir&#xE9;s du livre <em>The One Minute Workout</em>.</li><li><strong>Customs</strong> : permet (pour l&#x2019;instant) d&#x2019;acc&#xE9;der &#xE0; un entra&#xEE;nement vierge, id&#xE9;al pour cr&#xE9;er un programme sur-mesure &#xE0; partir de z&#xE9;ro.</li></ul><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://charly-ginevra.fr/content/images/2025/06/image-1.png" class="kg-image" alt="Chrono-Sport : Pour vos entra&#xEE;nements cardio" loading="lazy" width="2000" height="1311" srcset="https://charly-ginevra.fr/content/images/size/w600/2025/06/image-1.png 600w, https://charly-ginevra.fr/content/images/size/w1000/2025/06/image-1.png 1000w, https://charly-ginevra.fr/content/images/size/w1600/2025/06/image-1.png 1600w, https://charly-ginevra.fr/content/images/2025/06/image-1.png 2000w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Capture d&#x2019;&#xE9;cran du menu principal de Chrono-Sport</span></figcaption></figure><h3 id="param%C3%A9trer-son-entra%E2%80%8Bnement">Param&#xE9;trer son entra&#x200B;nement</h3><p>Pour illustrer les fonctionnalit&#xE9;s, prenons l&#x2019;exemple de l&#x2019;entra&#xEE;nement <a href="https://chrono-sport.charly-ginevra.fr/workouts/tabata?ref=charly-ginevra.fr" rel="noreferrer"><strong>Tabata</strong></a>.</p><div class="kg-card kg-toggle-card" data-kg-toggle-state="close">
            <div class="kg-toggle-heading">
                <h4 class="kg-toggle-heading-text"><span style="white-space: pre-wrap;">Tips</span></h4>
                <button class="kg-toggle-card-icon" aria-label="Expand toggle to read content">
                    <svg id="Regular" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24">
                        <path class="cls-1" d="M23.25,7.311,12.53,18.03a.749.749,0,0,1-1.06,0L.75,7.311"/>
                    </svg>
                </button>
            </div>
            <div class="kg-toggle-content"><p dir="ltr"><span style="white-space: pre-wrap;">Vous pouvez acc&#xE9;der directement &#xE0; un entra&#xEE;nement sp&#xE9;cifique en modifiant l&#x2019;URL suivante :</span> </p><p dir="ltr"><b><code spellcheck="false" style="white-space: pre-wrap;"><strong>https://chrono-sport.charly-ginevra.fr/{</strong></code></b><i><b><code spellcheck="false" style="white-space: pre-wrap;"><strong class="italic">categorie</strong></code></b></i><b><code spellcheck="false" style="white-space: pre-wrap;"><strong>}/{</strong></code></b><i><b><code spellcheck="false" style="white-space: pre-wrap;"><strong class="italic">module</strong></code></b></i><b><code spellcheck="false" style="white-space: pre-wrap;"><strong>}</strong></code></b><br><span style="white-space: pre-wrap;">- </span><i><b><strong class="italic" style="white-space: pre-wrap;">categorie</strong></b></i><span style="white-space: pre-wrap;"> : </span><code spellcheck="false" style="white-space: pre-wrap;"><span>classic</span></code><span style="white-space: pre-wrap;">, </span><code spellcheck="false" style="white-space: pre-wrap;"><span>workouts</span></code><span style="white-space: pre-wrap;">, </span><code spellcheck="false" style="white-space: pre-wrap;"><span>customs</span></code><br><span style="white-space: pre-wrap;">- </span><i><b><strong class="italic" style="white-space: pre-wrap;">module</strong></b></i> <span style="white-space: pre-wrap;">: </span><code spellcheck="false" style="white-space: pre-wrap;"><span>clock</span></code><span style="white-space: pre-wrap;">, </span><code spellcheck="false" style="white-space: pre-wrap;"><span>tabata</span></code><span style="white-space: pre-wrap;">, </span><code spellcheck="false" style="white-space: pre-wrap;"><span>ten-by-one</span></code><span style="white-space: pre-wrap;">, ...</span></p></div>
        </div><p>Apr&#xE8;s avoir s&#xE9;lectionn&#xE9; l&#x2019;entra&#xEE;nement, vous arrivez sur la page de d&#xE9;marrage.<br>Un chronom&#xE8;tre peut se trouver dans trois &#xE9;tats : <strong>initial</strong>, <strong>en cours</strong>, ou <strong>en pause</strong>.<br>Ces &#xE9;tats peuvent &#xEA;tre modifi&#xE9;s gr&#xE2;ce aux boutons <em>start</em>, <em>stop</em> et <em>reset</em>.</p><p>Voici un automate illustrant ce comportement :</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://charly-ginevra.fr/content/images/2025/07/diagrame-automate.drawio.png" class="kg-image" alt="Chrono-Sport : Pour vos entra&#xEE;nements cardio" loading="lazy" width="388" height="329"><figcaption><span style="white-space: pre-wrap;">Automate des &#xE9;tats possibles d&#x2019;un chronom&#xE8;tre</span></figcaption></figure><p>En faisant d&#xE9;filer la page, vous acc&#xE9;dez aux param&#xE8;tres de l&#x2019;entra&#xEE;nement (voir capture ci-dessous).</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://charly-ginevra.fr/content/images/2025/07/image.png" class="kg-image" alt="Chrono-Sport : Pour vos entra&#xEE;nements cardio" loading="lazy" width="2000" height="1311" srcset="https://charly-ginevra.fr/content/images/size/w600/2025/07/image.png 600w, https://charly-ginevra.fr/content/images/size/w1000/2025/07/image.png 1000w, https://charly-ginevra.fr/content/images/size/w1600/2025/07/image.png 1600w, https://charly-ginevra.fr/content/images/size/w2400/2025/07/image.png 2400w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Capture des param&#xE8;tres d&#x2019;un entra&#xEE;nement Tabata</span></figcaption></figure><p>C&#x2019;est ici que vous pouvez modifier la structure de la s&#xE9;ance. Voici un r&#xE9;capitulatif des actions associ&#xE9;es aux boutons de cette interface :</p>
<!--kg-card-begin: html-->
<table>
  <tr>
    
    <td>
      <ol start="1">
        <li>Temps pour le d&#xE9;but/fin de l&apos;entrainement</li>
        <li>Nom du round</li>
        <li>Nombre de fois que le round va se r&#xE9;p&#xE9;ter</li>
        <li>Supprimer le round</li>
        <li>Ajouter un nouveau round</li>
        <li>Valeur de temps pr&#xE9;/post round</li>
      </ol>
    </td>
    <td>
      <ol start="7">
        <li>Code couleur du chrono Active</li>
        <li>Nom du chrono</li>
        <li>Temps du chrono</li>
        <li>Supprimer le chrono</li>
        <li>Ajouter un chrono</li>
      </ol>
    </td>
  </tr>
</table>
<!--kg-card-end: html-->
<h2 id="et-maintenant">Et maintenant ?</h2><p>&#xC0; l&#x2019;heure actuelle, le r&#xE9;sultat me satisfait dans la mesure o&#xF9; l&#x2019;application r&#xE9;pond aux besoins fonctionnels que je m&#x2019;&#xE9;tais fix&#xE9;s. Cela dit, il reste encore beaucoup de travail avant d&#x2019;arriver &#xE0; un produit vraiment abouti. On pourrait qualifier l&#x2019;&#xE9;tat actuel de proof of concept : une base fonctionnelle, mais encore loin d&#x2019;&#xEA;tre polie.</p><h3 id="sur-le-plan-fonctionnel">Sur le plan fonctionnel</h3><p>Soyons honn&#xEA;tes : l&#x2019;interface est encore assez brute (mention sp&#xE9;ciale &#xE0; la page <em>About</em> &#x1F62D;).<br>Plusieurs pistes d&#x2019;am&#xE9;lioration pourraient grandement enrichir l&#x2019;exp&#xE9;rience utilisateur, comme :</p><ul><li>La possibilit&#xE9; de <strong>sauvegarder ses entra&#xEE;nements personnalis&#xE9;s</strong></li><li>Un outil pour <strong>g&#xE9;n&#xE9;rer des s&#xE9;ances en temps r&#xE9;el</strong></li><li>Un syst&#xE8;me de <strong>statistiques</strong> pour suivre et comparer ses performances</li></ul><h3 id="sur-le-plan-technique">Sur le plan technique</h3><p>Comme mentionn&#xE9; dans la section pr&#xE9;c&#xE9;dente, certains outils de d&#xE9;veloppement manquent encore &#xE0; l&#x2019;appel.<br>Int&#xE9;grer un linter, des hooks de commit ou une configuration CI plus robuste permettrait :</p><ul><li>d&#x2019;am&#xE9;liorer la <strong>qualit&#xE9; du code</strong></li><li>de mieux <strong>structurer les futurs d&#xE9;veloppements</strong></li></ul><h3 id="en-conclusion">En conclusion </h3><p>Ce projet m&#x2019;a d&#xE9;j&#xE0; beaucoup apport&#xE9;, tant sur le plan technique que pratique. Et au vu du travail qu&#x2019;il reste &#xE0; faire, je suis convaincu qu&#x2019;il a encore beaucoup &#xE0; m&#x2019;apprendre. &#x1F601;&#x1F4AA;<br></p>]]></content:encoded></item><item><title><![CDATA[UTM : Problème de résolution d'écran]]></title><description><![CDATA[<p>Avec pour objectif de r&#xE9;aliser des tests sur une machine <a href="https://www.debian.org/?ref=charly-ginevra.fr" rel="noreferrer">Debian</a>, je me suis retrouv&#xE9; dans le besoin de passer par une machine virtuelle.<br>Utilisant un MacBook Pro M1 et apr&#xE8;s quelques &#xE9;checs avec <a href="https://www.virtualbox.org/?ref=charly-ginevra.fr" rel="noreferrer">VirtualBox</a> &#x1F92E;, mon choix s&apos;est port&#xE9; sur</p>]]></description><link>https://charly-ginevra.fr/utm-probleme-de-resolution-decran/</link><guid isPermaLink="false">67cb457204165e0001ae50ea</guid><category><![CDATA[Informatique]]></category><category><![CDATA[Virtualisation]]></category><dc:creator><![CDATA[Charly]]></dc:creator><pubDate>Thu, 06 Mar 2025 10:34:01 GMT</pubDate><media:content url="https://charly-ginevra.fr/content/images/2025/03/siteicon.png" medium="image"/><content:encoded><![CDATA[<img src="https://charly-ginevra.fr/content/images/2025/03/siteicon.png" alt="UTM : Probl&#xE8;me de r&#xE9;solution d&apos;&#xE9;cran"><p>Avec pour objectif de r&#xE9;aliser des tests sur une machine <a href="https://www.debian.org/?ref=charly-ginevra.fr" rel="noreferrer">Debian</a>, je me suis retrouv&#xE9; dans le besoin de passer par une machine virtuelle.<br>Utilisant un MacBook Pro M1 et apr&#xE8;s quelques &#xE9;checs avec <a href="https://www.virtualbox.org/?ref=charly-ginevra.fr" rel="noreferrer">VirtualBox</a> &#x1F92E;, mon choix s&apos;est port&#xE9; sur le logiciel de virtualisation <a href="https://mac.getutm.app/?ref=charly-ginevra.fr" rel="noreferrer"><strong>UTM</strong></a> &#x1F47C;:.</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://github.com/utmapp/UTM?ref=charly-ginevra.fr"><div class="kg-bookmark-content"><div class="kg-bookmark-title">GitHub - utmapp/UTM: Virtual machines for iOS and macOS</div><div class="kg-bookmark-description">Virtual machines for iOS and macOS. Contribute to utmapp/UTM development by creating an account on GitHub.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" alt="UTM : Probl&#xE8;me de r&#xE9;solution d&apos;&#xE9;cran"><span class="kg-bookmark-author">GitHub</span><span class="kg-bookmark-publisher">utmapp</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://opengraph.githubassets.com/2352681ded24e20e1c7bdbd756a954b6f49bd1ed6f0553ab45215194098b5366/utmapp/UTM" alt="UTM : Probl&#xE8;me de r&#xE9;solution d&apos;&#xE9;cran"></div></a></figure><p>Apr&#xE8;s la cr&#xE9;ation de la VM et l&apos;installation du syst&#xE8;me d&apos;exploitation, j&apos;ai &#xE9;t&#xE9; confront&#xE9; &#xE0; un gros probl&#xE8;me de r&#xE9;solution d&apos;&#xE9;cran. </p><figure class="kg-card kg-gallery-card kg-width-wide kg-card-hascaption"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://charly-ginevra.fr/content/images/2025/03/Screenshot-2025-03-06-at-10.43.45.png" width="1920" height="1080" loading="lazy" alt="UTM : Probl&#xE8;me de r&#xE9;solution d&apos;&#xE9;cran" srcset="https://charly-ginevra.fr/content/images/size/w600/2025/03/Screenshot-2025-03-06-at-10.43.45.png 600w, https://charly-ginevra.fr/content/images/size/w1000/2025/03/Screenshot-2025-03-06-at-10.43.45.png 1000w, https://charly-ginevra.fr/content/images/size/w1600/2025/03/Screenshot-2025-03-06-at-10.43.45.png 1600w, https://charly-ginevra.fr/content/images/2025/03/Screenshot-2025-03-06-at-10.43.45.png 1920w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="https://charly-ginevra.fr/content/images/2025/03/Screenshot-2025-03-06-at-10.49.04.png" width="1920" height="1080" loading="lazy" alt="UTM : Probl&#xE8;me de r&#xE9;solution d&apos;&#xE9;cran" srcset="https://charly-ginevra.fr/content/images/size/w600/2025/03/Screenshot-2025-03-06-at-10.49.04.png 600w, https://charly-ginevra.fr/content/images/size/w1000/2025/03/Screenshot-2025-03-06-at-10.49.04.png 1000w, https://charly-ginevra.fr/content/images/size/w1600/2025/03/Screenshot-2025-03-06-at-10.49.04.png 1600w, https://charly-ginevra.fr/content/images/2025/03/Screenshot-2025-03-06-at-10.49.04.png 1920w" sizes="(min-width: 720px) 720px"></div></div></div><figcaption><p><span style="white-space: pre-wrap;">Avant installation de spice-vdagent</span></p></figcaption></figure><p>Cela s&apos;explique du fait que la machine h&#xF4;te n&apos;arrive pas &#xE0; communiquer avec la VM, ce qui l&apos;emp&#xEA;che de s&apos;adapter.</p><p>Pour r&#xE9;soudre le probl&#xE8;me, depuis la VM, ouvrez un terminal et ex&#xE9;cutez la commande suivante :</p><pre><code class="language-shell">sudo apt install spice-vdagent</code></pre><p>ou celle-ci si vous &#xEA;tes sur une machine Red Hat :</p><pre><code class="language-shell">sudo yum install spice-vdagent</code></pre><p>Red&#xE9;marrez la VM et le probl&#xE8;me aura disparu. &#x1F601;</p><figure class="kg-card kg-gallery-card kg-width-wide kg-card-hascaption"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://charly-ginevra.fr/content/images/2025/03/Screenshot-2025-03-06-at-10.53.10.png" width="1920" height="1080" loading="lazy" alt="UTM : Probl&#xE8;me de r&#xE9;solution d&apos;&#xE9;cran" srcset="https://charly-ginevra.fr/content/images/size/w600/2025/03/Screenshot-2025-03-06-at-10.53.10.png 600w, https://charly-ginevra.fr/content/images/size/w1000/2025/03/Screenshot-2025-03-06-at-10.53.10.png 1000w, https://charly-ginevra.fr/content/images/size/w1600/2025/03/Screenshot-2025-03-06-at-10.53.10.png 1600w, https://charly-ginevra.fr/content/images/2025/03/Screenshot-2025-03-06-at-10.53.10.png 1920w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="https://charly-ginevra.fr/content/images/2025/03/Screenshot-2025-03-06-at-10.54.00.png" width="1920" height="1080" loading="lazy" alt="UTM : Probl&#xE8;me de r&#xE9;solution d&apos;&#xE9;cran" srcset="https://charly-ginevra.fr/content/images/size/w600/2025/03/Screenshot-2025-03-06-at-10.54.00.png 600w, https://charly-ginevra.fr/content/images/size/w1000/2025/03/Screenshot-2025-03-06-at-10.54.00.png 1000w, https://charly-ginevra.fr/content/images/size/w1600/2025/03/Screenshot-2025-03-06-at-10.54.00.png 1600w, https://charly-ginevra.fr/content/images/2025/03/Screenshot-2025-03-06-at-10.54.00.png 1920w" sizes="(min-width: 720px) 720px"></div></div></div><figcaption><p><span style="white-space: pre-wrap;">Apr&#xE8;s installation de spice-vdagent</span></p></figcaption></figure><h2 id="source">Source</h2><ul><li><a href="https://docs.getutm.app/guest-support/linux/?ref=charly-ginevra.fr" rel="noreferrer">Documentation UTM</a></li><li><a href="https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/7/html/virtualization_deployment_and_administration_guide/sect-spice_agent?ref=charly-ginevra.fr#sect-QEMU_Guest_Agent-Set_Up_Communication_between_SPICE_Agent_and_Host" rel="noreferrer">Documentation Red Hat</a></li></ul>]]></content:encoded></item><item><title><![CDATA[Réveillez vos machines grâce au wake-on-lan !]]></title><description><![CDATA[<p>R&#xE9;cemment, j&apos;ai voulu mettre en place un homelab pour mes futurs projets. </p><p><strong>Probl&#xE8;me n&#xB0;1</strong> : Je n&apos;en ai pas besoin tout le temps (surtout des environnements de tests)<br><strong>Solution</strong> : &#xC9;teindre la ou les machines quand on ne s&apos;en</p>]]></description><link>https://charly-ginevra.fr/reprenez-le-controle-de-vos-machines-grace-au-wake-on-lan/</link><guid isPermaLink="false">67cb457204165e0001ae50e7</guid><category><![CDATA[Informatique]]></category><category><![CDATA[Docker]]></category><category><![CDATA[Rust]]></category><dc:creator><![CDATA[Charly]]></dc:creator><pubDate>Thu, 13 Feb 2025 21:56:15 GMT</pubDate><media:content url="https://charly-ginevra.fr/content/images/2025/03/WakeUp.png" medium="image"/><content:encoded><![CDATA[<img src="https://charly-ginevra.fr/content/images/2025/03/WakeUp.png" alt="R&#xE9;veillez vos machines gr&#xE2;ce au wake-on-lan !"><p>R&#xE9;cemment, j&apos;ai voulu mettre en place un homelab pour mes futurs projets. </p><p><strong>Probl&#xE8;me n&#xB0;1</strong> : Je n&apos;en ai pas besoin tout le temps (surtout des environnements de tests)<br><strong>Solution</strong> : &#xC9;teindre la ou les machines quand on ne s&apos;en sert pas. Merci captain Obvious.</p><p><strong>Probl&#xE8;me n&#xB0;2</strong> : Si je ne suis pas chez, comment je fais pour allumer mes appareils &#xE0; distance ?<br><strong>Solution</strong> : Le Wake-On-Lan !</p><p>C&apos;est donc comme &#xE7;a que m&apos;est venu l&apos;id&#xE9;e de <em>Wake-Up!</em></p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://github.com/TheBaronMc/wake-up?ref=charly-ginevra.fr"><div class="kg-bookmark-content"><div class="kg-bookmark-title">GitHub - TheBaronMc/wake-up</div><div class="kg-bookmark-description">Contribute to TheBaronMc/wake-up development by creating an account on GitHub.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" alt="R&#xE9;veillez vos machines gr&#xE2;ce au wake-on-lan !"><span class="kg-bookmark-author">GitHub</span><span class="kg-bookmark-publisher">TheBaronMc</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://opengraph.githubassets.com/8a1e6181224c47a27cf82f6d5a641fecceff593324d1bb682857d3199e472e26/TheBaronMc/wake-up" alt="R&#xE9;veillez vos machines gr&#xE2;ce au wake-on-lan !"></div></a></figure><p>Plut&#xF4;t que d&apos;ouvrir un port SSH en DNAT sur la box et de lancer un script &#xE0; distance, <em>Wake-Up!</em> permet de r&#xE9;veiller les machines de sont r&#xE9;seau depuis une interface web s&#xE9;curis&#xE9;e par un mot de passe.</p><p>Toute la mise en place est d&#xE9;crite dans le README mais je vais la reprendre ici.</p><p>Vous devez d&apos;abord cr&#xE9;er un fichier de configuration dans lequel vous allez renseigner le mot de passe pour acc&#xE9;der &#xE0; l&apos;interface, le port, les machines et d&apos;autres param&#xE8;tres. Vous trouverez un exemple ci-dessous :</p><pre><code class="language-yaml">password: wake-up!
api_enabled: false
web_enabled: true
port: 12345
groups:
  DHCP:
    Server1:
      address: 9D:2B:4F:7A:12
    Server2:
      port: 6
      address: A0:8C:3D:5E:9F:76
hosts:
  RaspberryPi:
    address: F1:6A:4B:3C:9D:21
  NAS:
    port: 6
    address: B3:11:8E:9F:4A:5D</code></pre><p>Lancez la commande suivante :</p><pre><code class="language-sh">$ docker run -v ./configuration.yml:/app/configuration.yml -p 8080:&lt;port&gt; baronmc/wake-up:1.0.0 </code></pre><p>Pour terminer, depuis un navigateur, connectez-vous &#xE0; l&apos;adresse <code>localhost:8080</code> et voil&#xE0; le r&#xE9;sultat :</p><figure class="kg-card kg-gallery-card kg-width-wide"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://charly-ginevra.fr/content/images/2025/03/Wake-Up-Password.png" width="2000" height="1300" loading="lazy" alt="R&#xE9;veillez vos machines gr&#xE2;ce au wake-on-lan !" srcset="https://charly-ginevra.fr/content/images/size/w600/2025/03/Wake-Up-Password.png 600w, https://charly-ginevra.fr/content/images/size/w1000/2025/03/Wake-Up-Password.png 1000w, https://charly-ginevra.fr/content/images/size/w1600/2025/03/Wake-Up-Password.png 1600w, https://charly-ginevra.fr/content/images/size/w2400/2025/03/Wake-Up-Password.png 2400w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="https://charly-ginevra.fr/content/images/2025/03/Wake-Up-Computer.png" width="2000" height="1300" loading="lazy" alt="R&#xE9;veillez vos machines gr&#xE2;ce au wake-on-lan !" srcset="https://charly-ginevra.fr/content/images/size/w600/2025/03/Wake-Up-Computer.png 600w, https://charly-ginevra.fr/content/images/size/w1000/2025/03/Wake-Up-Computer.png 1000w, https://charly-ginevra.fr/content/images/size/w1600/2025/03/Wake-Up-Computer.png 1600w, https://charly-ginevra.fr/content/images/size/w2400/2025/03/Wake-Up-Computer.png 2400w" sizes="(min-width: 720px) 720px"></div></div></div></figure><p>Si jamais vous souhaitez int&#xE9;grer ce fonctionnement dans vos process, <em>Wake-Up!</em> dispose d&apos;une API REST. Vous trouverez la liste des routes dans le README.</p>]]></content:encoded></item><item><title><![CDATA[Portfolio dans le terminal]]></title><description><![CDATA[<p>Depuis quelques temps, je cherchais une fa&#xE7;on originale de pr&#xE9;senter mon cv dans un portfolio. </p><p>Voulant mettre en avant l&apos;aspect d&#xE9;veloppeur informatique, l&apos;id&#xE9;e d&apos;un site web qui serait une simulation d&apos;un terminal m&apos;</p>]]></description><link>https://charly-ginevra.fr/portfolio-dans-le-terminal/</link><guid isPermaLink="false">67cb457204165e0001ae50e8</guid><category><![CDATA[Informatique]]></category><category><![CDATA[Docker]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[Vue]]></category><dc:creator><![CDATA[Charly]]></dc:creator><pubDate>Wed, 12 Feb 2025 21:24:07 GMT</pubDate><media:content url="https://charly-ginevra.fr/content/images/2025/03/terminal-portfolio.png" medium="image"/><content:encoded><![CDATA[<img src="https://charly-ginevra.fr/content/images/2025/03/terminal-portfolio.png" alt="Portfolio dans le terminal"><p>Depuis quelques temps, je cherchais une fa&#xE7;on originale de pr&#xE9;senter mon cv dans un portfolio. </p><p>Voulant mettre en avant l&apos;aspect d&#xE9;veloppeur informatique, l&apos;id&#xE9;e d&apos;un site web qui serait une simulation d&apos;un terminal m&apos;est apparue.</p><p>Avant de penser &#xE0; la conception et la r&#xE9;alisation du projet, je voulais une id&#xE9;e plus pr&#xE9;cise de &#xE0; quoi je voulais que mon portfolio ressemble. J&apos;ai donc r&#xE9;alis&#xE9; des planches avec l&apos;outil <a href="figma.com" rel="noreferrer">Figma</a>. Simple et puissant, cet outil est devenu un incontournable pour la phase de r&#xE9;flexion de mes projets.</p>
<!--kg-card-begin: html-->
<iframe style="border: 1px solid rgba(0, 0, 0, 0.1);" width="800" height="450" src="https://embed.figma.com/design/WMHHEG4ITXENbI1tklLrVL/Portefolio?node-id=0-1&amp;embed-host=share" allowfullscreen></iframe>
<!--kg-card-end: html-->
<blockquote>Cliquer <a href="https://www.figma.com/design/WMHHEG4ITXENbI1tklLrVL/Portefolio?node-id=0-1&amp;t=vkIw3Q89rlCBlaxZ-1&amp;ref=charly-ginevra.fr" rel="noreferrer">ici</a> dans le cas o&#xF9; la page Figma ne se chargerais pas</blockquote><p>Au niveau des technologies, pour du d&#xE9;veloppement web, il n&apos;y a pas beaucoup de solutions. Javascript est un incontournable. Cependant, afin de r&#xE9;aliser un projet assez cons&#xE9;quent et de mani&#xE8;re propre, Typescript apporte un vrai plus en termes de structure et de lisibilit&#xE9; du code.</p><p>Pour ne pas partir de z&#xE9;ro, j&apos;ai aussi choisi d&apos;utiliser le Framework Vue. Je l&apos;ai d&#xE9;j&#xE0; utilis&#xE9; par le pass&#xE9; sur d&apos;autres projets avec toujours une bonne exp&#xE9;rience et un r&#xE9;sultat au rendez-vous.</p><p>Ce projet m&apos;a permis d&apos;utiliser deux outils que je voulais d&#xE9;couvrir depuis un certain temps d&#xE9;j&#xE0; : <a href="https://bun.sh/?ref=charly-ginevra.fr" rel="noreferrer">Bun</a>, un environnement d&apos;ex&#xE9;cution Javascript r&#xE9;put&#xE9; pour sa rapidit&#xE9;, et <a href="https://github.com/features/actions?ref=charly-ginevra.fr" rel="noreferrer">Github Actions</a>, pour g&#xE9;rer la CI/CD. </p><p>Au moment o&#xF9; j&apos;&#xE9;cris ces lignes, le projet dispose d&apos;un syst&#xE8;me de fichier basique, et de quelques commandes de base (ls, cd, echo, mkdir, ...). Pour visualiser les informations relatives &#xE0; mon CV, ce qui &#xE9;tait l&apos;objectif du projet, il faut lancer la commande <code>help</code> qui nous dit toutes les informations &#xE0; r&#xE9;cup&#xE9;rer et comment le faire.</p><p>A l&apos;avenir, l&apos;objectif est d&apos;ajouter les droits d&apos;acc&#xE8;s aux fichiers, un moyen de faire des petits scripts et un peu de styles pour donner un look plus r&#xE9;tro.</p><p>Retrouvez le r&#xE9;sultat &#xE0; l&apos;adresse <a href="https://portfolio.charly-ginevra.fr/shell?ref=charly-ginevra.fr">portfolio.charly-ginevra.fr</a> et le code du projet sur Github. :-) </p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://github.com/TheBaronMc/portfolio-terminal?ref=charly-ginevra.fr"><div class="kg-bookmark-content"><div class="kg-bookmark-title">GitHub - TheBaronMc/portfolio-terminal: Shell Simulation</div><div class="kg-bookmark-description">Shell Simulation. Contribute to TheBaronMc/portfolio-terminal development by creating an account on GitHub.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" alt="Portfolio dans le terminal"><span class="kg-bookmark-author">GitHub</span><span class="kg-bookmark-publisher">TheBaronMc</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://opengraph.githubassets.com/a0b49ac29b7857aaa1246eecbf0d48fd541109d896087157e03a66ef76147a9e/TheBaronMc/portfolio-terminal" alt="Portfolio dans le terminal"></div></a></figure>]]></content:encoded></item></channel></rss>