<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Git on Zwindler's Reflection</title><link>https://blog.zwindler.fr/tags/git/</link><description>Recent content in Git on Zwindler's Reflection</description><generator>Hugo -- gohugo.io</generator><language>fr</language><copyright>Licensed under CC BY-SA 4.0</copyright><lastBuildDate>Fri, 24 Nov 2023 14:00:00 +0200</lastBuildDate><atom:link href="https://blog.zwindler.fr/tags/git/index.xml" rel="self" type="application/rss+xml"/><item><title>Une issue ouverte sur un projet, 7 ans après ?</title><link>https://blog.zwindler.fr/2023/11/24/issue-ouverte-apres-7-ans/</link><pubDate>Fri, 24 Nov 2023 14:00:00 +0200</pubDate><guid>https://blog.zwindler.fr/2023/11/24/issue-ouverte-apres-7-ans/</guid><description>&lt;img src="https://blog.zwindler.fr/2016/09/article_docker_xwiki.webp" alt="Featured image of post Une issue ouverte sur un projet, 7 ans après ?" /&gt;&lt;h2 id="introduction"&gt;Introduction
&lt;/h2&gt;&lt;p&gt;Il y a 7 ans, en août 2016 (!!), je créais ma première &amp;ldquo;vraie&amp;rdquo; image docker.&lt;/p&gt;
&lt;p&gt;Il s&amp;rsquo;agissait d&amp;rsquo;une image custom pour un outil que j&amp;rsquo;utilisais énormément &lt;a class="link" href="https://blog.zwindler.fr/recherche/?keyword=xwiki" target="_blank" rel="noopener"
&gt;XWiki&lt;/a&gt;, un outil de Knowledge management open source (et français) que j&amp;rsquo;apprécie particulièrement et qui remplace avantageusement un Confluence (si vous voulez mon avis).&lt;/p&gt;
&lt;p&gt;A l&amp;rsquo;époque, mon image fournissait un XWiki prêt à l&amp;rsquo;emploi avec Tomcat 8 et le driver JDBC pour postgresql.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/zwindler/docker-xwiki" target="_blank" rel="noopener"
&gt;github.com/zwindler/docker-xwiki&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;J&amp;rsquo;avais fait ce projet car les images officielles du projet étaient encore balbutiantes (ça date !) et ne proposaient pas cette alternative.&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://blog.zwindler.fr/2016/09/15/installer-xwiki-8-2-1-avec-docker-compose-en-2-lignes-de-commandes/" &gt;J&amp;rsquo;avais d&amp;rsquo;ailleurs écrit un article pour l&amp;rsquo;occasion (Installer XWiki 8.2.1 avec Docker (compose) en 2 lignes de commandes)&lt;/a&gt; et fourni au fil des mois suivants des manifests pour Kubernetes.&lt;/p&gt;
&lt;h2 id="et-aujourdhui-"&gt;Et aujourd&amp;rsquo;hui ?
&lt;/h2&gt;&lt;p&gt;Ca fait bien longtemps que ce projet n&amp;rsquo;a plus aucun intérêt, même si mes images ont été téléchargées environ 30000 fois (quand même !), avec un dernier téléchargement l&amp;rsquo;an dernier, malgré une version vielle de plus de 6 ans (mais pourquoiiiiii ?).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://hub.docker.com/repository/docker/zwindler/xwiki-tomcat8/general" target="_blank" rel="noopener"
&gt;hub.docker.com - zwindler/xwiki-tomcat8&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Les images officielles proposent désormais (depuis bien longtemps) toutes les options les plus courantes pour toutes les versions supportées&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2023/11/dockerhub_xwiki.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="pourtant-"&gt;Pourtant ?!?
&lt;/h2&gt;&lt;p&gt;Pourtant, début novembre, j&amp;rsquo;ai reçu une issue, d&amp;rsquo;un utilisateur qui m&amp;rsquo;informait qu&amp;rsquo;il ne pouvait pas rebuild mon image car l&amp;rsquo;URL permettant de télécharger les artefacts WAR ne répondait plus (effectivement, elle a changé).&lt;/p&gt;
&lt;p&gt;Même si au début j&amp;rsquo;étais un peu interloqué, je me suis dis que ça pouvait être fun de remettre les mains dedans et de tenter de mettre à jour mon image sur toute la stack, pour voir si ça fonctionne encore.&lt;/p&gt;
&lt;h2 id="voyons-voir-ce-qui-a-changé-depuis-2016"&gt;Voyons voir ce qui a changé depuis 2016&amp;hellip;
&lt;/h2&gt;&lt;p&gt;Évidemment, beaucoup de choses !&lt;/p&gt;
&lt;p&gt;D&amp;rsquo;abord, les versions de XWiki (de 10 à 14), qui ont forcément évoluées, ainsi que cette fameuse URL de téléchargement des artefacts qui avait changé.&lt;/p&gt;
&lt;p&gt;La version de postgres est passée de 9.5 à 16, les versions du driver JDBC ont évoluées de plusieurs mineures.&lt;/p&gt;
&lt;p&gt;Plus impactant, tomcat est passé de la version 8 à la version 10, avec un gros breaking change entre la 9 et la 10, notamment à cause de JEE, renommé en JakartaEE !&lt;/p&gt;
&lt;p&gt;Ca parlera aux Javaistes ;-)&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2023/11/javax.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Plus anecdotique, le MAINTAINER a disparu depuis bien longtemps des Dockerfile (remplacé par un LABEL opencontainers), le MaxPermSize n&amp;rsquo;existe plus en Java et le format des fichiers docker-compose est passé en version 3.&lt;/p&gt;
&lt;h2 id="les-modifs"&gt;Les modifs
&lt;/h2&gt;&lt;p&gt;Pour le fun, j&amp;rsquo;ai donc réparé mon image pour qu&amp;rsquo;elle marche (et pas plus), puis j&amp;rsquo;ai passé le repo en readonly, pour la postérité, en prenant soin d&amp;rsquo;informer l&amp;rsquo;auteur de l&amp;rsquo;issue qu&amp;rsquo;il valait mieux regarder du côté des images officielles ;-).&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://github.com/zwindler/docker-xwiki/commit/c5955f1c35f809cdf3b4f56b20cc204a37a27f17" target="_blank" rel="noopener"
&gt;Le code de fix est disponible ici, pour les curieux/curieuses&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Mais&amp;hellip; ça fonctionne :-p&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2023/11/xwiki-14.avif"
loading="lazy"
&gt;&lt;/p&gt;</description></item><item><title>Automatiser son site Hugo sans Github Action ou Vercel</title><link>https://blog.zwindler.fr/2023/08/01/automatiser-hugo-sans-github-action/</link><pubDate>Tue, 01 Aug 2023 06:00:00 +0200</pubDate><guid>https://blog.zwindler.fr/2023/08/01/automatiser-hugo-sans-github-action/</guid><description>&lt;img src="https://blog.zwindler.fr/2021/11/wordpress-to-hugo.webp" alt="Featured image of post Automatiser son site Hugo sans Github Action ou Vercel" /&gt;&lt;h2 id="contexte"&gt;Contexte
&lt;/h2&gt;&lt;p&gt;Fin 2021, après plus de 10 ans à écrire des articles de blog tech sur Wordpress, je prenais la décision radicale d&amp;rsquo;arrêter de maintenir cette bouse infâme (je mâche mes mots) et de partir sur des articles rédigés en markdown et un site statique avec Hugo.&lt;/p&gt;
&lt;p&gt;Au tout début, je gérais le blog moi-même mais assez vite j&amp;rsquo;en ai eu assez de devoir aller rebuild le blog à chaque modification. J&amp;rsquo;ai rapidement mis un cron qui faisait des &lt;code&gt;git pull&lt;/code&gt; régulièrement, mais on ne va pas se mentir, c&amp;rsquo;est assez crado&amp;hellip;&lt;/p&gt;
&lt;p&gt;Finalement, on m&amp;rsquo;a rapidement pointé que je devrais arrêter de m&amp;rsquo;embêter et utiliser &lt;a class="link" href="https://www.netlify.com/" target="_blank" rel="noopener"
&gt;Netlify&lt;/a&gt; ou &lt;a class="link" href="https://vercel.com/" target="_blank" rel="noopener"
&gt;Vercel&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;étais pas super chaud, car ça allait à l&amp;rsquo;encontre de ma volonté d&amp;rsquo;auto héberger mon contenu et de limiter l&amp;rsquo;impact sur la vie privée de mes lecteurs, mais finalement, l&amp;rsquo;expérience utilisateur sur Vercel était tellement bonne que j&amp;rsquo;avais craqué. Je ferai peut-être un article là-dessus d&amp;rsquo;ailleurs, c&amp;rsquo;est la première fois que j&amp;rsquo;ai compris (ressenti) l&amp;rsquo;intérêt d&amp;rsquo;un PaaS.&lt;/p&gt;
&lt;p&gt;Mais aujourd&amp;rsquo;hui, je reviens sur cette décision et j&amp;rsquo;essaye de voir ce qu&amp;rsquo;il est nécessaire de mettre en place pour disposer soi-même d&amp;rsquo;un site hugo qui se refresh tout seul dès qu&amp;rsquo;un commit arrive sur le dépôt git, sans utiliser de plateforme type Vercel ni d&amp;rsquo;outils types Github action+pages.&lt;/p&gt;
&lt;h2 id="prérequis"&gt;Prérequis
&lt;/h2&gt;&lt;p&gt;Je pars du principe que vous avez déjà un site statique généré avec Hugo. Si ce n&amp;rsquo;est pas le cas je vous invite à aller lire mes articles précédents sur le sujet (&lt;a class="link" href="https://blog.zwindler.fr/2019/06/10/comment-migrer-de-wordpress-a-hugo/" &gt;premiers pas&lt;/a&gt;, &lt;a class="link" href="https://blog.zwindler.fr/2019/06/18/mes-stats-de-visites-hugo-sans-google-analytics-avec-matomo/" &gt;stats avec matomo&lt;/a&gt;, &lt;a class="link" href="https://blog.zwindler.fr/2021/11/22/jai-enfin-migre-de-wordpress-a-hugo-partie-1/" &gt;migration wordpress vers hugo&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Vous avez donc un serveur Linux sur lequel vous avez la main pour installer des choses et un dépôt git (sous Github dans mon cas, mais on peut probablement adapter l&amp;rsquo;article pour autre chose).&lt;/p&gt;
&lt;p&gt;Hugo étant d&amp;rsquo;abord un générateur de site statique, je vais utiliser nginx en frontal pour servir les fichiers qu&amp;rsquo;on va générer. Jusqu&amp;rsquo;à il y a peu, l&amp;rsquo;usage du mode &amp;ldquo;server&amp;rdquo; de hugo n&amp;rsquo;était d&amp;rsquo;ailleurs pas conseillé en production (mais ça ne semble plus être le cas, je n&amp;rsquo;ai pas vu de warning dernièrement ?).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt install nginx git
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="déposer-les-sources-sur-le-serveur"&gt;Déposer les sources sur le serveur
&lt;/h2&gt;&lt;p&gt;Dans mon cas, les sources de mon blog ne sont pas disponibles publiquement (parce que j&amp;rsquo;ai pas envie, c&amp;rsquo;est comme ça ¯\_(ツ)_/¯).&lt;/p&gt;
&lt;p&gt;Il faut donc préalablement se loguer en SSH avec git avant de pouvoir &lt;em&gt;pull&lt;/em&gt; le code. Et comme je n&amp;rsquo;ai pas envie de laisser ma clé privée sur le serveur qui va héberger mon blog, il faut que j&amp;rsquo;utilise une autre clé.&lt;/p&gt;
&lt;p&gt;Dans mon cas, Github, qui héberge le code markdown de mon blog, a une notion de &amp;ldquo;deploy keys&amp;rdquo;, qui servent justement pour ça :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.github.com/en/authentication/connecting-to-github-with-ssh/managing-deploy-keys" target="_blank" rel="noopener"
&gt;docs.github.com/en/authentication/connecting-to-github-with-ssh/managing-deploy-keys&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Je vais donc créer une clé sur le serveur qui héberge le blog :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t ed25519 -C &lt;span class="s2"&gt;&amp;#34;xxx@xxx.tld&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Generating public/private ed25519 key pair.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Enter file in which to save the key &lt;span class="o"&gt;(&lt;/span&gt;/home/toto/.ssh/id_ed25519&lt;span class="o"&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;...&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Et je la copie dans le dossier de &lt;em&gt;www-data&lt;/em&gt; (l&amp;rsquo;utilisateur nginx sous Ubuntu)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;600&lt;/span&gt; /root/.ssh/id_ed25519
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mkdir /var/www/.ssh/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo cp ~/.ssh/id_ed25519* /var/www/.ssh/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chown www-data: /var/www/.ssh/*
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Une fois la clé créée, on doit l&amp;rsquo;ajouter dans Github.com. Je ne lui donne que les droits &amp;ldquo;read only&amp;rdquo; puisque le but c&amp;rsquo;est seulement de récupérer le code et générer le site statique, pas qu&amp;rsquo;on puisse éditer le code (&lt;em&gt;cé pour la sécuritay&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2023/07/github-deploy-keys2.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Je retourne ensuite sur mon serveur et j&amp;rsquo;essaye de télécharger les sources et le thème:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/share/nginx/html
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;GIT_SSH_COMMAND&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ssh -i /var/www/.ssh/id_ed25519 -o IdentitiesOnly=yes&amp;#39;&lt;/span&gt; git clone git@github.com:zwindler/blog.example.org.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; blog.example.org/themes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git submodule add -f https://github.com/CaiJimmy/hugo-theme-stack.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chown -R www-data: /usr/share/nginx/html/blog.example.org
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="webhook"&gt;Webhook
&lt;/h2&gt;&lt;p&gt;Pour réagir à l&amp;rsquo;arrivée d&amp;rsquo;un nouveau commit sur notre dépôt source, on va utiliser 2 choses :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;un projet qui s&amp;rsquo;appelle sobrement &amp;ldquo;Webhook&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;configurer un webhook dans github, qui va envoyer l&amp;rsquo;info que quelque chose est arrivé sur le dépôt (mais on verra ça plus tard)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Revenons à &amp;ldquo;Webhook&amp;rdquo; dans un premier temps :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;webhook is a lightweight configurable tool written in Go, that allows you to easily create HTTP endpoints (hooks) on your server, which you can use to execute configured commands. You can also pass data from the HTTP request (such as headers, payload or query variables) to your commands. webhook also allows you to specify rules which have to be satisfied in order for the hook to be triggered.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;On récupère la dernière release et déposer le binaire sur notre serveur :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/adnanh/webhook/releases/tag/2.8.1" target="_blank" rel="noopener"
&gt;github.com/adnanh/webhook/releases/tag/2.8.1&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2.8.1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget https://github.com/adnanh/webhook/releases/download/&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/webhook-linux-amd64.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tar -xvf webhook*.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mv webhook-linux-amd64/webhook /usr/local/bin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm -rf webhook-linux-amd64*
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;webhook --version
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Une fois que c&amp;rsquo;est fait, on va générer une chaîne aléatoire qui va nous servir de &amp;ldquo;secret&amp;rdquo; qui sera partagé entre le binaire &lt;em&gt;webhook&lt;/em&gt; qui tourne sur notre serveur et un &lt;em&gt;webhook&lt;/em&gt; sur Github.com :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;WHSECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;uuidgen &lt;span class="p"&gt;|&lt;/span&gt; base64&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On crée un fichier de configuration &lt;code&gt;hook.json&lt;/code&gt; pour déclarer nos webhooks&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;mkdir&lt;/span&gt; &lt;span class="err"&gt;/etc/webhook&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;cat&lt;/span&gt; &lt;span class="err"&gt;&amp;gt;&lt;/span&gt; &lt;span class="err"&gt;/etc/webhook/hook.json&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="err"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;redeploy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;execute-command&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/usr/share/nginx/html/blog.example.org/blog_refresh.sh&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;command-working-directory&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/usr/share/nginx/html/blog.example.org&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;trigger-rule&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;match&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;payload-hmac-sha1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;secret&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;$WHSECRET&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;parameter&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;source&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;header&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;X-Hub-Signature&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ici, quand le serveur va recevoir l&amp;rsquo;url /hooks/redeploy, on va lancer le script &lt;code&gt;/usr/share/nginx/html/blog.example.org/blog_refresh.sh&lt;/code&gt; depuis le répertoire /usr/share/nginx/html/blog.example.org.&lt;/p&gt;
&lt;p&gt;Charge à nous de créer un script qui va soit :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;récupérer les sources (git pull)&lt;/li&gt;
&lt;li&gt;relancer un build&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Voilà à quoi pourrait ressembler le script &lt;code&gt;blog_refresh.sh&lt;/code&gt; :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/share/nginx/html/blog.example.org
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#pull latest version&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;GIT_SSH_COMMAND&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ssh -i /var/www/.ssh/id_ed25519 -o IdentitiesOnly=yes&amp;#39;&lt;/span&gt; git clone git@github.com:zwindler/blog.example.org.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#refresh theme submodule&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git submodule init
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git submodule update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#rebuild (fire and forget)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo --minify --gc &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On va ensuite créer un service systemd qui va lancer le binaire &lt;em&gt;webhook&lt;/em&gt; en tâche de fond&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat &amp;gt; /etc/systemd/system/webhook.service &lt;span class="s"&gt;&amp;lt;&amp;lt; EOF
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;[Unit]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;Description=Simple Golang webhook server
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;ConditionPathExists=/usr/local/bin/webhook
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;After=network.target
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;[Service]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;User=www-data
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;Group=www-data
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;Type=simple
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;WorkingDirectory=/usr/share/nginx/html/blog.example.org
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;ExecStart=/usr/local/bin/webhook -ip 127.0.0.1 -hooks /etc/webhook/hook.json -verbose
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;Restart=on-failure
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;[Install]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;WantedBy=default.target
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; webhook
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl start webhook
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Côté Github.com, on crée le webhook qui va contacter le serveur webhook de la façon suivante :&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2023/07/github-webhook.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;On a maintenant un serveur web qui est en attente de certains événements webhooks et qui va lancer un script si jamais l&amp;rsquo;URL de webhook est appelée par Github.com.&lt;/p&gt;
&lt;h2 id="configuration-nginx"&gt;Configuration nginx
&lt;/h2&gt;&lt;p&gt;Il reste maintenant toute la configuration de notre nginx en frontal à faire. En partant du principe qu&amp;rsquo;on vient juste de faire l&amp;rsquo;installation du package, on commence par supprimer le fichier &lt;code&gt;/etc/nginx/sites-enabled/default&lt;/code&gt;, et on en crée un nouveau :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm /etc/nginx/sites-enabled/default
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat &amp;gt; /etc/nginx/sites-available/blog.example.org.conf &lt;span class="s"&gt;&amp;lt;&amp;lt; EOF
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;# Root configuration
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;server {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; listen 80;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; server_name blog.example.org;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; location /hooks/ {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; proxy_pass http://127.0.0.1:9000/hooks/;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; error_page 404 /404.html;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; location / {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; root /usr/share/nginx/html/blog.example.org/public;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; index index.html;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ln -s /etc/nginx/sites-&lt;span class="o"&gt;{&lt;/span&gt;available,enabled&lt;span class="o"&gt;}&lt;/span&gt;/blog.example.org.conf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On vérifie que la configuration est valide et si oui on redémarre nginx&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nginx -t
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl reload nginx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A partir de maintenant, toutes les URLs qui arriveront jusqu&amp;rsquo;à votre serveur en /hooks seront redirigées sur le logiciel &amp;ldquo;webhook&amp;rdquo; et le reste ira sur votre site statique (/usr/share/nginx/html/blog.example.org/public).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;curl https://blog.example.org/hooks/redeploy -L
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Hook rules were not satisfied.%
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ici le hook renvoie une erreur, car on a pas envoyé le token secret mais c&amp;rsquo;est probable que ça fonctionne. Toutes les autres pages renvoient bien une page du blog :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;curl https://blog.example.org/
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;&amp;lt;!DOCTYPE html&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;&amp;lt;html lang=&amp;#34;fr-fr&amp;#34; dir=&amp;#34;ltr&amp;#34;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; &amp;lt;head&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; &amp;lt;meta name=&amp;#34;generator&amp;#34; content=&amp;#34;Hugo 0.115.1&amp;#34;&amp;gt;&amp;lt;meta charset=&amp;#39;utf-8&amp;#39;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;[...]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On peut maintenant envoyer des commits et voir si ça déclenche des rebuilds de notre blog. Ou alors, on peut récupérer un push précédent et cliquer sur &amp;ldquo;Redeliver&amp;rdquo; si on veut trigger un rebuild du blog.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2023/07/github-redelivery.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@hugo:~# systemctl status webhook
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;* webhook.service - Simple Golang webhook server
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Loaded: loaded (/etc/systemd/system/webhook.service; enabled; vendor preset: enabled)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Active: active (running) since Mon 2023-07-31 07:34:35 UTC; 33s ago
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Main PID: 900109 (webhook)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Tasks: 15 (limit: 4574)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Memory: 240.4M
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; CPU: 45.504s
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; CGroup: /system.slice/webhook.service
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; |-900109 /usr/local/bin/webhook -ip 127.0.0.1 -hooks /etc/webhook/hook.json -verbose
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; `-900161 hugo --minify --gc
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:34:35 hugo webhook[900109]: [webhook] 2023/07/31 07:34:35 attempting to load hooks from /etc/webhook/hook.json
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:34:35 hugo webhook[900109]: [webhook] 2023/07/31 07:34:35 found 1 hook(s) in file
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:34:35 hugo webhook[900109]: [webhook] 2023/07/31 07:34:35 loaded: redeploy
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:34:35 hugo webhook[900109]: [webhook] 2023/07/31 07:34:35 serving hooks on http://127.0.0.1:9000/hooks/{id}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:34:35 hugo webhook[900109]: [webhook] 2023/07/31 07:34:35 os signal watcher ready
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:34:41 hugo webhook[900109]: [webhook] 2023/07/31 07:34:41 [f089a0] incoming HTTP POST request from 127.0.0.1:43258
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:34:41 hugo webhook[900109]: [webhook] 2023/07/31 07:34:41 [f089a0] redeploy got matched
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:34:41 hugo webhook[900109]: [webhook] 2023/07/31 07:34:41 [f089a0] redeploy hook triggered successfully
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:34:41 hugo webhook[900109]: [webhook] 2023/07/31 07:34:41 [f089a0] 200 | 0 B | 1.151688ms | 127.0.0.1:9000 | POST /hooks/redeploy
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:34:41 hugo webhook[900109]: [webhook] 2023/07/31 07:34:41 [f089a0] executing /usr/share/nginx/html/blog.example.org/blog_refresh.sh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;[...]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:37:28 hugo webhook[900109]: Pages | 3572
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:37:28 hugo webhook[900109]: Paginator pages | 516
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:37:28 hugo webhook[900109]: Non-page files | 14
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:37:28 hugo webhook[900109]: Static files | 2282
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:37:28 hugo webhook[900109]: Processed images | 2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:37:28 hugo webhook[900109]: Aliases | 1563
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:37:28 hugo webhook[900109]: Sitemaps | 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:37:28 hugo webhook[900109]: Cleaned | 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:37:28 hugo webhook[900109]: Total in 166131 ms
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 31 07:37:28 hugo webhook[900109]: [webhook] 2023/07/31 07:37:28 [f089a0] finished handling redeploy
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="conclusion"&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;Si vous êtes à l&amp;rsquo;aise avec Linux et nginx, ces quelques manipulations sont assez rapides à faire, il n&amp;rsquo;y a rien de vraiment complexe.&lt;/p&gt;
&lt;p&gt;Cependant, ça demande à l&amp;rsquo;usage un peu d&amp;rsquo;administration et de vouloir mettre les mains dans le cambouis (avoir une VM à gérer). Je ne peux reprocher à personne de préférer l&amp;rsquo;utilisation de Github/Gitlab pages, couplé à de Github actions/Gitlab runners, voire de tout déléguer à Vercel/Netlify&amp;hellip;&lt;/p&gt;
&lt;p&gt;Mais j&amp;rsquo;avais envie de reprendre la main sur le hosting de mon blog (avec tous les inconvénients que ça va avoir en termes de maintien en condition opérationnelle), notamment pour disposer à nouveau de l&amp;rsquo;IPv6 (perdue lors du passage à Vercel) et une navigation sur mon blog plus respectueuse de votre vie privée (pas que j&amp;rsquo;aie pas confiance en Vercel, mais bon&amp;hellip;).&lt;/p&gt;
&lt;p&gt;Et c&amp;rsquo;est en revanche beaucoup plus simple que d&amp;rsquo;héberger son propre serveur Gitlab + Gitlab runners + Gitlab pages ;-).&lt;/p&gt;
&lt;p&gt;Donc, pour mon usage, ça fait le taf :)&lt;/p&gt;
&lt;h2 id="ressources-additionnelles"&gt;Ressources additionnelles
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://ansonvandoren.com/posts/deploy-hugo-from-github/" target="_blank" rel="noopener"
&gt;ansonvandoren.com/posts/deploy-hugo-from-github/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://magefan.com/blog/configure-webhooks-in-github" target="_blank" rel="noopener"
&gt;magefan.com/blog/configure-webhooks-in-github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>J'ai enfin migré de Wordpress vers Hugo - partie 2</title><link>https://blog.zwindler.fr/2021/11/29/jai-enfin-migre-de-wordpress-a-hugo-partie-2/</link><pubDate>Mon, 29 Nov 2021 08:00:00 +0000</pubDate><guid>https://blog.zwindler.fr/2021/11/29/jai-enfin-migre-de-wordpress-a-hugo-partie-2/</guid><description>&lt;img src="https://blog.zwindler.fr/2021/11/wordpress-to-hugo.webp" alt="Featured image of post J'ai enfin migré de Wordpress vers Hugo - partie 2" /&gt;&lt;p&gt;Cette article fait partie d&amp;rsquo;une suite d&amp;rsquo;articles :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2021/11/22/jai-enfin-migre-de-wordpress-a-hugo-partie-1/" &gt;J&amp;rsquo;ai enfin migré de Wordpress vers Hugo - partie 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2021/11/29/jai-enfin-migre-de-wordpress-a-hugo-partie-2/" &gt;J&amp;rsquo;ai enfin migré de Wordpress vers Hugo - partie 2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="extraire-les-données-de-wordpress"&gt;Extraire les données de WordPress
&lt;/h2&gt;&lt;p&gt;Normalement &lt;a class="link" href="https://blog.zwindler.fr/2021/11/22/jai-enfin-migre-de-wordpress-a-hugo-partie-1/" &gt;si vous avez lu la première partie&lt;/a&gt;, vous savez qu&amp;rsquo;on a un Hugo fonctionnel (mais vide). Et que dans mon cas, l&amp;rsquo;objectif était de migrer 12 ans d&amp;rsquo;historique (350 articles tout de même) de Wordpress vers notre Hugo.&lt;/p&gt;
&lt;p&gt;Vous vous en doutez, le but n&amp;rsquo;est pas de reprendre les articles uns par uns (sauf si vous n&amp;rsquo;en avez qu&amp;rsquo;une dizaine, ça doit se faire) mais bien de trouver une méthode pour exporter le contenu existant en markdown pour repartir comme si de rien n&amp;rsquo;était.&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://gohugo.io/tools/migrations/#wordpress" target="_blank" rel="noopener"
&gt;La documentation officielle de Hugo donne plusieurs pistes&lt;/a&gt; pour migrer depuis Wordpress et c&amp;rsquo;est la première que j&amp;rsquo;avais utilisé en 2019 (la première fois que j&amp;rsquo;avais tenté de migrer, sans succès). J&amp;rsquo;ai re-installé l&amp;rsquo;extension &lt;code&gt;wordpress-to-hugo-exporter&lt;/code&gt; (je vous invite quand même à regarder les alternatives car il n&amp;rsquo;est pas impossible que ça ait évolué depuis).&lt;/p&gt;
&lt;h2 id="wordpress-to-hugo-exporter"&gt;wordpress-to-hugo-exporter
&lt;/h2&gt;&lt;p&gt;La première chose à faire pour installer cette extension est de vérifier que votre serveur qui héberge le WordPress dispose bien de l’extension PHP &lt;code&gt;zip.so&lt;/code&gt;.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cat /etc/php.d/40-zip.ini
; Enable ZIP extension module
extension=zip.so
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On peut ensuite cloner le projet git du plugin directement dans le dossier plugin de WordPress&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cd PATH_TO_WORDPRESS/wp-content/plugins/
git clone https://github.com/SchumacherFM/wordpress-to-hugo-exporter
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A partir de là, il est possible de démarrer un export soit depuis l&amp;rsquo;interface, soit via un script en PHP lancé depuis le serveur en ligne de commandes. Évidemment, dans ce genre de procédures, on arrive toujours à un moment où on se tape un timeout quelque part. Dans mon cas, les données exportées (articles + medias, environ ~1.5 Go) prenaient 500 Mo de RAM et 20 minutes d&amp;rsquo;exécution.&lt;/p&gt;
&lt;p&gt;On oublie donc le clic dans l&amp;rsquo;interface (sauf à tuner votre nginx pour autoriser des requêtes clients avec un timeout &amp;gt; 60s) et on lance depuis la ligne de commande. Et bien entendu, on augmente toutes les limites possibles et imaginables, notamment celle de wordpress via le fichier wp-config.php.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-PHP" data-lang="PHP"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Set initial default constants including WP_MEMORY_LIMIT, WP_MAX_MEMORY_LIMIT, WP_DEBUG, SCRIPT_DEBUG, WP_CONTENT_DIR and WP_CACHE.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;wp_initial_constants&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;WP_MEMORY_LIMIT&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;2048M&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;WP_MAX_MEMORY_LIMIT&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;2048M&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; PATH_TO_WORDPRESS/wp-content/plugins/wordpress-to-hugo-exporter/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;php hugo-export-cli.php &lt;span class="nv"&gt;memory_limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;-1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Qui devrait se terminer, si tout se passe bien, par un :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;This is your file!
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/tmp/wp-hugo.zip
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;Note: on peut également exporter les commentaires, il faut modifier manuellement une ligne dans le fichier &lt;code&gt;hugo-export.php&lt;/code&gt; (voir la doc)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;A partir de là, on a une archive qui contient vos posts, vos pages et vos médias importés (grosso modo tout wp-content).&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;archive a l&amp;rsquo;arborescence suivante :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;un dossier &lt;strong&gt;posts&lt;/strong&gt; qui contient tous les articles (&lt;em&gt;posts&lt;/em&gt; dans la terminologie wordpress) dans un mélange de markdown + html brut (ce qui n&amp;rsquo;aura pas été correctement converti, on y reviendra)&lt;/li&gt;
&lt;li&gt;un dossier &lt;strong&gt;wp-content&lt;/strong&gt; qui contient tous les médias&lt;/li&gt;
&lt;li&gt;des dossiers pour chacune de vos &amp;ldquo;&lt;em&gt;pages&lt;/em&gt; (&amp;ldquo;à propos&amp;rdquo;, &amp;ldquo;mentions légales&amp;rdquo;, etc).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="importer-dans-hugo"&gt;Importer dans Hugo
&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;arborescence de Hugo est elle un peu différente. De base, tout ce qui est markdown doit être dans &lt;strong&gt;content&lt;/strong&gt;, avec des sous dossiers en fonction du type de page (&lt;em&gt;post&lt;/em&gt; ou &lt;em&gt;page&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;La première petite &amp;ldquo;blaguounette&amp;rdquo; est que les &lt;em&gt;posts&lt;/em&gt; doivent être déposés dans le sous-dossier &lt;strong&gt;content/post&lt;/strong&gt; (sans S à la fin !!!).&lt;/p&gt;
&lt;p&gt;Chaque post commence par des métadonnées encadrées par des triples tirets &amp;ldquo;&amp;mdash;&amp;rdquo; avant et après. Ca donne quelque chose comme ça :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;title: &amp;#39;ESXi 4.0 &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Explorons l&amp;amp;rsquo;Hidden Console Part 1&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;authors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;zwindler&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;post&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ld"&gt;2010-04-28T08:32:20&lt;/span&gt;&lt;span class="m"&gt;+00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;00&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;/2010/04/28/esxi-4-0-explorons-lhidden-console-part-1/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;featured_image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://blog.example.org/wp-content/uploads/2014/10/vmware-220x162.jpg&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;Virtualisation&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ESX(i)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;Hidden Console&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;SSH&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;L&amp;#39;article lui même...]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ca peut différer un peu selon les thèmes je pense, mais grosso modo les markdown des &lt;em&gt;pages&lt;/em&gt; iront eux dans &lt;strong&gt;content/page&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Enfin, tout ce qui est media (dossier wp-media) va dans un dossier &lt;strong&gt;static&lt;/strong&gt;. On peut garder la même arborescence que wordpress (/année/mois/) mais rien ne nous y oblige.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;So far, so good&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="emile-et-images"&gt;Emile et Images
&lt;/h2&gt;&lt;p&gt;Enfin&amp;hellip; &lt;em&gt;so good&lt;/em&gt;, c&amp;rsquo;est vite dit&amp;hellip;&lt;/p&gt;
&lt;p&gt;Et oui parce que l&amp;rsquo;exporter n&amp;rsquo;exporte pas hyper bien un certain nombre de choses, à commencer par l&amp;rsquo;image de garde de chaque article :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;featured_image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://blog.example.org/wp-content/uploads/2014/10/vmware-220x162.jpg&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On peut remarquer plusieurs soucis avec cette variable. D&amp;rsquo;abord, la variable utilisée pour indiquer le chemin de l&amp;rsquo;image dans les métadonnées générées est &lt;code&gt;featured_image&lt;/code&gt; alors qu&amp;rsquo;Hugo attend &lt;code&gt;image&lt;/code&gt;. Petit &lt;code&gt;sed&lt;/code&gt; sur vos md pour corriger ça :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -i &lt;span class="s2"&gt;&amp;#34;s/featured_image/image/g&amp;#34;&lt;/span&gt; fichier.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Mais bien sûr, ce n&amp;rsquo;est pas fini ;-)&lt;/p&gt;
&lt;p&gt;Ensuite, on remarque qu&amp;rsquo;on a un chemin est une URL complète et non pas relative. Si vous gardez les média dans le chemin &lt;strong&gt;static/wp-content/uploads/YYYY/MM&lt;/strong&gt; ça marchera, mais je trouve ça moche.&lt;/p&gt;
&lt;p&gt;2 solutions :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;on supprime &lt;strong&gt;/wp-content/uploads&lt;/strong&gt; avec un bête &lt;code&gt;sed -i &amp;quot;s!/wp-content/uploads!!g fichier.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;on passe en relatif en supprimant carrément toute la première partie de l&amp;rsquo;URL &lt;strong&gt;&lt;a class="link" href="https://yourblog.example.org/wp-content/uploads" target="_blank" rel="noopener"
&gt;https://yourblog.example.org/wp-content/uploads&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si vous choisissez la 2ème solution (mon choix), faites quand même bien attention. En fonction de &lt;em&gt;comment&lt;/em&gt; vous rédigez votre expression régulière, ça pourrait affecter aussi toutes les autres images que vous auriez en lien dans vos articles. Ce n&amp;rsquo;est pas forcément une mauvaise chose (moi j&amp;rsquo;aime mieux les liens relatifs car c&amp;rsquo;est plus flexible) mais ça demande un travail supplémentaire.&lt;/p&gt;
&lt;h2 id="images-intermédiaires"&gt;Images intermédiaires
&lt;/h2&gt;&lt;p&gt;Toujours dans les images, vous remarquerez aussi que l&amp;rsquo;image &amp;ldquo;mise en avant&amp;rdquo; (dans les métadonnées) possède un suffixe de type &lt;code&gt;-111x222&lt;/code&gt; juste avant l&amp;rsquo;extension. En fait, chaque fois que vous importez une image dans wordpress, celui ci la convertie en plusieurs tailles pour accélérer le chargement des pages.&lt;/p&gt;
&lt;p&gt;Sauf que le &lt;strong&gt;wordpress-to-hugo-exporter&lt;/strong&gt; choisi une des plus petites résolution pour l&amp;rsquo;image en tête de l&amp;rsquo;article. Ca sera souvent hyper moche&amp;hellip;&lt;/p&gt;
&lt;p&gt;Là encore, j&amp;rsquo;ai donc passé un gros &lt;code&gt;sed&lt;/code&gt; pour virer tous les suffixes &lt;code&gt;-111x222&lt;/code&gt; avant l&amp;rsquo;extension, puis je n&amp;rsquo;ai copié QUE les images originales dans le dossier &lt;strong&gt;static&lt;/strong&gt; (regex non triviale) :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; PATH_TO_EXPORT/wp-content/uploads
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; i in &lt;span class="sb"&gt;`&lt;/span&gt;seq &lt;span class="m"&gt;2010&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; 2021&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; find &lt;span class="nv"&gt;$i&lt;/span&gt; -mindepth &lt;span class="m"&gt;1&lt;/span&gt; -type f -regextype posix-egrep -not -iregex &lt;span class="s2"&gt;&amp;#34;.*/.*-[0-9]{1,4}x[0-9]{1,4}.*\..*&amp;#34;&lt;/span&gt; -exec cp &lt;span class="o"&gt;{}&lt;/span&gt; PATH_TO_HUGO/static/&lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="se"&gt;\;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="nettoyer-les-caractères-spéciaux-html"&gt;Nettoyer les caractères spéciaux HTML
&lt;/h2&gt;&lt;p&gt;Si vous avez bien lu l&amp;rsquo;exemple de métadonnées exportées que j&amp;rsquo;ai donné, vous aurez peut être remarqué la présence d&amp;rsquo;un caractère spécial encodé &lt;code&gt;&amp;amp;rsquo;&lt;/code&gt; dans le titre.&lt;/p&gt;
&lt;p&gt;Dans une page HTML, ce n&amp;rsquo;est pas grave, mais Hugo lui, ne les interprète pas comme tel dans le markdown. Il faut donc leur faire la chasse et tous les convertir 🤦. Et encore, il faut faire attention, car certains de ces caractères pourraient être légitimement écris en HTML (si vous faite un tuto sur HTML, ce n&amp;rsquo;est pas impossible par exemple)&amp;hellip;&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;ai pour ma part lancé un gros &lt;code&gt;sed&lt;/code&gt; (une fois de plus) sur tous mes articles mais prudence !&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -i &lt;span class="s2"&gt;&amp;#34;s/&amp;amp;rsquo;/’/g&amp;#34;&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -i &lt;span class="s2"&gt;&amp;#34;s/&amp;amp;#8211;/--/g&amp;#34;&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -i &lt;span class="s2"&gt;&amp;#34;s/&amp;amp;#8230;/.../g&amp;#34;&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -i &lt;span class="s2"&gt;&amp;#34;s/&amp;amp;gt;/&amp;gt;/g&amp;#34;&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -i &lt;span class="s2"&gt;&amp;#34;s/&amp;amp;lt;/&amp;lt;/g&amp;#34;&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -i &lt;span class="s2"&gt;&amp;#34;s/&amp;amp;#8212;/-/g&amp;#34;&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -i &lt;span class="s2"&gt;&amp;#34;s/&amp;amp;#8217;/&amp;#39;/g&amp;#34;&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -i &lt;span class="s2"&gt;&amp;#34;s/&amp;amp;#215;/×/g&amp;#34;&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Je n&amp;rsquo;ai pas osé modifier les caractères suivants, très souvent présents dans les URLs :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;amp;#038
&amp;amp;#039
&amp;amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Mais c&amp;rsquo;est quand même une bonne idée de faire une grosse recherche avec votre éditeur de texte favori pour voir s&amp;rsquo;il ne reste pas des &lt;code&gt;&amp;amp;#&lt;/code&gt; qui traînent dans votre contenu.&lt;/p&gt;
&lt;h2 id="html-désactivé"&gt;HTML désactivé
&lt;/h2&gt;&lt;p&gt;Au delà des caractères spéciaux, il arrive aussi que l&amp;rsquo;exporter est un peu de mal avec les différents types d&amp;rsquo;éditeurs que Wordpress a pu avoir au fil du temps.&lt;/p&gt;
&lt;p&gt;Typiquement, beaucoup du contenu &amp;ldquo;non texte&amp;rdquo; que j&amp;rsquo;ai ajouté au fil des années s&amp;rsquo;est retrouvé non converti par ce que j&amp;rsquo;ai rédigé s&amp;rsquo;est retrouvé exporté tel quel, en HTML brut inséré dans mon markdown.&lt;/p&gt;
&lt;p&gt;C&amp;rsquo;est hyper traître car Hugo ne renvoie aucune erreur. Il manque &amp;ldquo;juste&amp;rdquo; des bouts ! On peut les retrouver en allant voir le code source de la page, qui affiche alors les commentaires HTML suivants :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-HTML" data-lang="HTML"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;&amp;lt;!-- raw HTML omitted --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En attendant de nettoyer tout ça à grand coup de &lt;code&gt;sed&lt;/code&gt;, on peut résoudre une partie des problèmes en &amp;ldquo;réactivant le support du code HTML dans le markdown dans votre &lt;code&gt;config.yaml&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;markup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;goldmark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;## Set to true if you have HTML content inside Markdown&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;unsafe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ca permet de sauver les meubles mais ce n&amp;rsquo;est pas suffisant&amp;hellip;&lt;/p&gt;
&lt;h2 id="markdown-hates-html"&gt;Markdown hates HTML
&lt;/h2&gt;&lt;p&gt;Même comme ça, on grosse partie du HTML sera HS&amp;hellip; Tous les tableaux (table/tr/td) et listes (ul/li) HTML sont pétés car l&amp;rsquo;exporter laisse des sauts de lignes entre les blocs, que le markdown interprète mal. Il faudra supprimer tous les sauts de lignes en trop (ou réécrire en markdown)&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;table class=&amp;#34;Content&amp;#34; border=&amp;#34;0&amp;#34; width=&amp;#34;750&amp;#34;&amp;gt;
&amp;lt;tr&amp;gt;
&amp;lt;td class=&amp;#34;LargeBold&amp;#34;&amp;gt;
SEND_CUSTOM_SVC_NOTIFICATION
&amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;
&amp;lt;td class=&amp;#34;MediumBold&amp;#34;&amp;gt;
Command Format:
&amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sachez également que toutes les &amp;ldquo;videos embedded&amp;rdquo; Youtube disparaîtront purement et simplement, et que pour les tweets, vous aurez une version très moche du tweet, sans l&amp;rsquo;image&amp;hellip;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-HTML" data-lang="HTML"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;blockquote&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;twitter-tweet&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;data-width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;550&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;data-lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;en&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;data-dnt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;data-partner&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;jetpack&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;fr&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ltr&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; [[#SAPHANA](ht tps://tw itter.com/hashtag/SAPHANA?src=hash&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;ref_src=twsrc%5Etfw)] Finies les mises à jour incompatibles avec votre plateforme, optez pour la simplicité et la tranquillité, chez SAP : on collecte, on connecte, ça marche : [t.co/2AdCCEQ97L](https://t.c o/2AdCCEQ97L) [pic.twi tter.com/yy7moMnZmC](ht tps://t.c o/yy7moMnZmC)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- SAP France (@SAPFrance)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; [October 8, 2018](ht tps://twiter.com/SAPFrance/status/1049286253533962241?ref_src=twsrc%5Etfw)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;blockquote&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;J&amp;rsquo;en avais peu heureusement, j&amp;rsquo;ai donc pris des captures d&amp;rsquo;écran et ajouté des liens.&lt;/p&gt;
&lt;h2 id="balises-de-code-pre-etc"&gt;Balises de code, pre, etc.
&lt;/h2&gt;&lt;p&gt;Une autre grosse catégorie de code &amp;ldquo;mal exporté&amp;rdquo; est le &amp;ldquo;code&amp;rdquo;. Je donne souvent des bouts de scripts ou de code ou tout simplement des commandes à passer sur des serveurs. Et au fil des années, j&amp;rsquo;ai (&amp;amp; wordpress) changé plusieurs fois la façon d&amp;rsquo;afficher du code dans mes articles.&lt;/p&gt;
&lt;p&gt;D&amp;rsquo;abord avec des balises HTML &lt;code&gt;&amp;lt;pre&amp;gt;&amp;lt;/pre&amp;gt;&lt;/code&gt;, puis des balises &lt;code&gt;&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;/code&gt;, puis via des extensions (pour avoir la coloration syntaxique), puis via du markdown via Jetpack, puis de nouveau via les extensions&amp;hellip;&lt;/p&gt;
&lt;p&gt;Autant dire que le HTML généré par Wordpress ne ressemble à rien&amp;hellip;&lt;/p&gt;
&lt;p&gt;Il a fallut faire un gros gros boulot pour détecter toutes les balises de code ouvrantes et fermantes pour les convertir en ``` de markdown&amp;hellip;&lt;/p&gt;
&lt;p&gt;Quelques exemples que j&amp;rsquo;ai rencontré :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-HTML" data-lang="HTML"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;pre&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;pre&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;brush: plain; title: ; notranslate&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;pre&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;brush: perl; collapse: false; title: ; wrap-lines: false; notranslate&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;pre&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;EnlighterJSRAW&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;data-enlighter-language&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;null&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;pre&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;EnlighterJSRAW&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;data-enlighter-language&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;generic&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;pre&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;EnlighterJSRAW&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;data-enlighter-language&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;generic&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;data-enlighter-theme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;... et bien d&amp;#39;autres encore
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="final-words"&gt;Final words
&lt;/h2&gt;&lt;p&gt;Je m&amp;rsquo;arrête là car l&amp;rsquo;article est déjà très long, mais il y a eu d&amp;rsquo;autres petits problèmes du même style, plus sporadiques&amp;hellip;&lt;/p&gt;
&lt;p&gt;Vous voyez donc qu&amp;rsquo;exporter le blog sur Hugo n&amp;rsquo;aura pas été de tout repos, dans mon cas. Et encore ! Je n&amp;rsquo;ai pas exporté les commentaires historiques (plus de 1600) !&lt;/p&gt;
&lt;p&gt;Cependant, si vous avez un blog plus petit que celui ci, vous devriez avoir moins de mal et les conseils que je donne ici devraient vous permettre de régler rapidement 90% des problèmes.&lt;/p&gt;
&lt;p&gt;Enjoy !&lt;/p&gt;</description></item><item><title>J'ai enfin migré de Wordpress vers Hugo - partie 1</title><link>https://blog.zwindler.fr/2021/11/22/jai-enfin-migre-de-wordpress-a-hugo-partie-1/</link><pubDate>Mon, 22 Nov 2021 08:00:00 +0000</pubDate><guid>https://blog.zwindler.fr/2021/11/22/jai-enfin-migre-de-wordpress-a-hugo-partie-1/</guid><description>&lt;img src="https://blog.zwindler.fr/2021/11/wordpress-to-hugo.webp" alt="Featured image of post J'ai enfin migré de Wordpress vers Hugo - partie 1" /&gt;&lt;p&gt;Cette article fait partie d&amp;rsquo;une suite d&amp;rsquo;articles :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2021/11/22/jai-enfin-migre-de-wordpress-a-hugo-partie-1/" &gt;J&amp;rsquo;ai enfin migré de Wordpress vers Hugo - partie 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.zwindler.fr/2021/11/29/jai-enfin-migre-de-wordpress-a-hugo-partie-2/" &gt;J&amp;rsquo;ai enfin migré de Wordpress vers Hugo - partie 2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="plus-de-2-ans-et-demi"&gt;Plus de 2 ans et demi
&lt;/h2&gt;&lt;p&gt;Ca fait plus de 2 ans et demi que je râle que j&amp;rsquo;en ai ma claque de Wordpress.&lt;/p&gt;
&lt;p&gt;Stack LEMP à maintenir, perfs bof (j&amp;rsquo;ai du mettre un cache pour passer sous la seconde, wtf&amp;hellip;), plugins aux MAJs hasardeuses, failles de sécu, pas de support propre du markdown, éditeur à ch*** (Gutenberg, je te hais), &amp;hellip; you name it.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2021/tweet_mieuxavant.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Après 12 ans de blogging, il était temps de faire l&amp;rsquo;effort et de quitter Wordpress pour quelque chose qui me convient mieux : un moteur de blog statique (rien de dynamique dans ce que je poste) en markdown (parce que de toute façon c&amp;rsquo;est comme ça que j&amp;rsquo;écris mes articles à la base). Le tout dans git pour historiser tout ça.&lt;/p&gt;
&lt;p&gt;Et j&amp;rsquo;ai choisi Hugo pour des raisons que &lt;a class="link" href="https://blog.zwindler.fr/2019/06/10/comment-migrer-de-wordpress-a-hugo/" &gt;je détaille dans l&amp;rsquo;article 2019 &amp;ldquo;Comment migrer de Wordpress à Hugo&amp;rdquo; si ça vous intéresse&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="forcément-cest-pas-si-facile"&gt;Forcément, c&amp;rsquo;est pas si facile
&lt;/h2&gt;&lt;p&gt;J&amp;rsquo;en parlais déjà dans l&amp;rsquo;article de 2019 : migrer de Wordpress à Hugo, forcément ce n&amp;rsquo;est pas si facile. D&amp;rsquo;ailleurs, j&amp;rsquo;avais même abandonné l&amp;rsquo;idée devant l&amp;rsquo;ampleur da tâche !&lt;/p&gt;
&lt;p&gt;Ce n&amp;rsquo;est pas tant la partie technique (installation de Hugo, export du blog existant) le problème. En quelques minutes, on a un blog fonctionnel, l&amp;rsquo;export prend guère plus de temps. Rajouter l&amp;rsquo;outillage pour automatiser certaines tâches prend un peu de temps mais rien d&amp;rsquo;incroyable.&lt;/p&gt;
&lt;p&gt;Mon problème était plutôt que je voulais obtenir au moins aussi bien que ce que j&amp;rsquo;avais avant, existant inclus.&lt;/p&gt;
&lt;p&gt;Et c&amp;rsquo;est là que le bat blesse : wordpress, avec mes 12 ans (350 articles) d&amp;rsquo;historique, c&amp;rsquo;est au fil des années 15 façons différentes d&amp;rsquo;afficher du HTML&amp;hellip; que le plugin d&amp;rsquo;export gère comme il peut ! Nous y reviendrons.&lt;/p&gt;
&lt;p&gt;Je vais donc vous guider un peu sur la partie technique, puis j&amp;rsquo;aborderai ensuite les points pénibles du nettoyage du markdown, qui m&amp;rsquo;a pris un bonne partie de mes vacances (plusieurs journées à ~2-3 heures par jour). Il y aura aussi, plus tard, des articles sur l&amp;rsquo;outillage à mettre en place pour se faciliter la vie au quotidien.&lt;/p&gt;
&lt;h2 id="installation"&gt;Installation
&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;installation en elle même est triviale. On a un binaire compilé en go packagé dans un &lt;strong&gt;.deb&lt;/strong&gt; (ou les sources si vous voulez le builder vous même) disponible sur github. Fin.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt upgrade
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;VER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;0.88.1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget https://github.com/gohugoio/hugo/releases/download/v&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;VER&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/hugo_&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;VER&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;_Linux-64bit.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ou https://github.com/gohugoio/hugo/releases/download/v${VER}/hugo_extended_${VER}_Linux-64bit.deb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install ./hugo*_0.88.1_Linux-64bit.deb
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A noter que dans mon cas, je n&amp;rsquo;ai pas téléchargé la version ci dessus, mais la version &amp;ldquo;extended&amp;rdquo;, nécessaire pour le thème que j&amp;rsquo;ai choisi, mais le principe est le même.&lt;/p&gt;
&lt;h2 id="initialisation-du-site-et-du-dépôt-git"&gt;Initialisation du site et du dépôt git
&lt;/h2&gt;&lt;p&gt;Hugo est maintenant disponible sur votre machine.&lt;/p&gt;
&lt;p&gt;A partir de là, je vous invite fortement à versionner tout ce que vous allez faire avec votre blog. C&amp;rsquo;est bien entendu optionnel mais pourquoi se priver de toute la puissance du couple markdown + git ?&lt;/p&gt;
&lt;p&gt;On commence par créer un dossier puis on génère un squelette de site vierge avec &lt;code&gt;hugo new site&lt;/code&gt; :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;mkdir hugo &amp;amp;&amp;amp; cd hugo
hugo new site toto
Congratulations! Your new Hugo site is created in toto.
Just a few more steps and you&amp;#39;re ready to go:
1. Download a theme into the same-named folder.
Choose a theme from https://themes.gohugo.io/ or
create your own with the &amp;#34;hugo new theme &amp;lt;THEMENAME&amp;gt;&amp;#34; command.
2. Perhaps you want to add some content. You can add single files
with &amp;#34;hugo new &amp;lt;SECTIONNAME&amp;gt;/&amp;lt;FILENAME&amp;gt;.&amp;lt;FORMAT&amp;gt;&amp;#34;.
3. Start the built-in live server via &amp;#34;hugo server&amp;#34;.
Visit https://gohugo.io/ for quickstart guide and full documentation.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A partir de là, on va pouvoir initialiser notre dépôt git&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; toto
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git init
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Bon, si jamais vous lancez la génération du blog avec simplement la commande de preview &lt;code&gt;hugo server&lt;/code&gt;, vous allez être assez déçus, ça donne une page blanche. Mais, ça marche !&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo server
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Start building sites …
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo v0.88.1-5BC54738+extended linux/amd64 &lt;span class="nv"&gt;BuildDate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2021-09-04T09:39:19Z &lt;span class="nv"&gt;VendorInfo&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gohugoio
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;WARN 2021/11/14 06:57:47 found no layout file &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;HTML&amp;#34;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; kind &lt;span class="s2"&gt;&amp;#34;taxonomy&amp;#34;&lt;/span&gt;: You should create a template file which matches Hugo Layouts Lookup Rules &lt;span class="k"&gt;for&lt;/span&gt; this combination.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;WARN 2021/11/14 06:57:47 found no layout file &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;HTML&amp;#34;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; kind &lt;span class="s2"&gt;&amp;#34;home&amp;#34;&lt;/span&gt;: You should create a template file which matches Hugo Layouts Lookup Rules &lt;span class="k"&gt;for&lt;/span&gt; this combination.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;WARN 2021/11/14 06:57:47 found no layout file &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;HTML&amp;#34;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; kind &lt;span class="s2"&gt;&amp;#34;taxonomy&amp;#34;&lt;/span&gt;: You should create a template file which matches Hugo Layouts Lookup Rules &lt;span class="k"&gt;for&lt;/span&gt; this combination.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;|&lt;/span&gt; EN
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-------------------+-----
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Pages &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Paginator pages &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Non-page files &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Static files &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Processed images &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Aliases &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Sitemaps &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Cleaned &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Built in &lt;span class="m"&gt;1&lt;/span&gt; ms
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Watching &lt;span class="k"&gt;for&lt;/span&gt; changes in /toto/&lt;span class="o"&gt;{&lt;/span&gt;archetypes,content,data,layouts,static&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Watching &lt;span class="k"&gt;for&lt;/span&gt; config changes in /toto/config.toml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Environment: &lt;span class="s2"&gt;&amp;#34;development&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Serving pages from memory
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Web Server is available at http://localhost:1313/ &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;bind&lt;/span&gt; address 127.0.0.1&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Press Ctrl+C to stop
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="ajout-dun-thème"&gt;Ajout d&amp;rsquo;un thème
&lt;/h2&gt;&lt;p&gt;Avant même de commencer à ajouter du contenu, il est probable que vous allez vouloir choisir un thème. Il existe une liste de thèmes, plus fournie qu&amp;rsquo;en 2019, &lt;a class="link" href="https://themes.gohugo.io/" target="_blank" rel="noopener"
&gt;disponible ici&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Une fois le thème choisi, on va l&amp;rsquo;ajouter au site à l&amp;rsquo;aide de la (très utile) commande git &lt;code&gt;git submodule&lt;/code&gt; qui va nous permettre de gérer notre thème et ses mises à jour avec git sans pour autant commiter tous les fichiers.&lt;/p&gt;
&lt;p&gt;Dans mon cas j&amp;rsquo;ai choisi le thème &amp;ldquo;stack&amp;rdquo; mais le principe est grosso modo le même pour tous (à quelques détails d&amp;rsquo;implémentation près) :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; themes/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git submodule add https://github.com/CaiJimmy/hugo-theme-stack.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="avant-le-premier-article-"&gt;Avant le premier article !
&lt;/h2&gt;&lt;p&gt;Si on veut bosser un peu proprement, on va vouloir éviter de commiter n&amp;rsquo;importe quoi. Comme hugo est un générateur de blog statique, on va bien entendu éviter de commiter le code statique généré par la commande &lt;code&gt;hugo&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On utilise simplement un fichier &lt;strong&gt;.gitignore&lt;/strong&gt; à la racine du projet pour ignorer tout ce qui est technique ou qui n&amp;rsquo;est pas du code :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat &amp;gt; .gitignore &lt;span class="s"&gt;&amp;lt;&amp;lt; EOF
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;themes
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;resources/_gen
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;assets/jsconfig.json
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;public
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On va aussi vouloir paramétrer a minima notre site. Vous aurez peut être remarqué qu&amp;rsquo;il existe un fichier &lt;code&gt;config.toml&lt;/code&gt; généré par défaut par la commande &lt;code&gt;hugo new site&lt;/code&gt;. Il s&amp;rsquo;agit de &amp;ldquo;l&amp;rsquo;ancienne&amp;rdquo; manière de faire de la configuration Hugo, mais surtout d&amp;rsquo;un fichier agnostique du thème utilisée. Généralement, il vaut mieux le supprimer et repartir du fichier d&amp;rsquo;exemple inclus avec votre thème.&lt;/p&gt;
&lt;p&gt;Dans mon cas, il s&amp;rsquo;agit du fichier &lt;strong&gt;theme/hugo-theme-stack/config.yaml&lt;/strong&gt; que j&amp;rsquo;ai donc copié à la racine du projet et modifié pour correspondre à mon site et mes besoins.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;baseurl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://blog.zwindler.fr&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;languageCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;fr-fr&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;hugo-theme-stack&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Zwindler&amp;#39;s Reflection&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="l"&gt;...]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="le-premier-commit"&gt;Le premier commit
&lt;/h2&gt;&lt;p&gt;C&amp;rsquo;est un petit moment agréable dans n&amp;rsquo;importe quel projet informatique. Le premier commit.&lt;/p&gt;
&lt;p&gt;Bon moi, comme j&amp;rsquo;ai hébergé le dépôt sur Github et qu&amp;rsquo;ils ont décidé de renommer &lt;strong&gt;master&lt;/strong&gt; en &lt;strong&gt;main&lt;/strong&gt; dans le nom de la branche par défaut on a un peu de gymnastique à faire, mais pourquoi pas.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git add .
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git commit -m &lt;span class="s2"&gt;&amp;#34;first commit&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch -M main
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git remote add origin git@github.com:zwindler/example.org.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git push -u origin main
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Le &amp;ldquo;code&amp;rdquo; de notre (absence de) blog est publié Internet :)&lt;/p&gt;
&lt;h2 id="et-en-prod-"&gt;Et en prod ?
&lt;/h2&gt;&lt;p&gt;Vous pouvez donc commencer à écrire (dans &lt;strong&gt;content/post&lt;/strong&gt;), tester votre blog en local, puis pousser le code sur git. Mais si jamais vous voulez héberger votre site ailleurs que sur votre laptop (et je parie que c&amp;rsquo;est le cas) ?&lt;/p&gt;
&lt;p&gt;Et bien c&amp;rsquo;est là où c&amp;rsquo;est chouette d&amp;rsquo;utiliser git et un dépôt accessible depuis Internet. Vous n&amp;rsquo;avez qu&amp;rsquo;à reproduire l&amp;rsquo;installation de hugo, ajouter votre dépôt, initialiser les submodules (notre thème) et le tour est joué !&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;VER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;0.88.1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget https://github.com/gohugoio/hugo/releases/download/v&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;VER&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/hugo_&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;VER&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;_Linux-64bit.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ou https://github.com/gohugoio/hugo/releases/download/v${VER}/hugo_extended_${VER}_Linux-64bit.deb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install ./hugo*_0.88.1_Linux-64bit.deb
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/zwindler/toto.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git submodule init
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git submodule update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Normalement, le site devrait se générer, comme en local. Si vous n&amp;rsquo;avez pas d&amp;rsquo;historique à migrer, comme moi, vous êtes donc l&amp;rsquo;heureux propriétaire d&amp;rsquo;un blog statique fonctionnel :-). La classe !&lt;/p&gt;
&lt;p&gt;Sinon, dans le prochain article, j&amp;rsquo;aborderai un plus gros morceau, à savoir l&amp;rsquo;export et le nettoyage du markdown depuis un Wordpress existant.&lt;/p&gt;</description></item><item><title>Comment migrer de WordPress à Hugo</title><link>https://blog.zwindler.fr/2019/06/10/comment-migrer-de-wordpress-a-hugo/</link><pubDate>Mon, 10 Jun 2019 11:35:20 +0000</pubDate><guid>https://blog.zwindler.fr/2019/06/10/comment-migrer-de-wordpress-a-hugo/</guid><description>&lt;img src="https://blog.zwindler.fr/2019/06/wordpress_vers_hugo.webp" alt="Featured image of post Comment migrer de WordPress à Hugo" /&gt;&lt;h2 id="mais-cest-qui-ce-hugo-"&gt;Mais c’est qui ce Hugo ?
&lt;/h2&gt;&lt;p&gt;Dans la rétrospective des &lt;a class="link" href="https://blog.zwindler.fr/2019/02/27/250eme-article-un-peu-plus-dun-an-de-10000-a-20000/" &gt;9 ans / 250ème articles sur le blog&lt;/a&gt;, je vous ai parlé de mes futurs projets.&lt;/p&gt;
&lt;p&gt;Une bonne partie des projets concernent le blog lui-même, en particulier abandonner WordPress et passer à un blog statique.&lt;/p&gt;
&lt;p&gt;Car les reproches que je fais à WordPress sont nombreux :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Une techno d’un autre âge, d’une lenteur infernale dès qu’on commence à avoir un peu de contenu&lt;/li&gt;
&lt;li&gt;Besoin de nombreux plugins pour avoir un rendu correct pour un blog tech, pour le partage, les stats, l’antispam, les protections/firewall, des jolies balises pour les bouts de code, &amp;hellip;&lt;/li&gt;
&lt;li&gt;Des sauvegardes BDD + plugins + média à paramétrer (et complexes à tester)&lt;/li&gt;
&lt;li&gt;Des caches à mettre partout pour éviter que la moindre page avec quelques images mette 5 secondes à charger&amp;hellip;&lt;/li&gt;
&lt;li&gt;Gutenberg, le nouvel éditeur qui par défaut vous fait écrire sur 550 px de large (1/5ème de mon écran, à peine plus large qu’une carte de visite)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2021/tweet_mieuxavant.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="bref-jen-ai-marre"&gt;Bref, j’en ai marre
&lt;/h2&gt;&lt;p&gt;Alors je le suis dis : pourquoi j’ai un bousin infâme qui fait le café (franchement ça fait tout et n’importe quoi WordPress, du e-commerce au CV interactif) alors que moi, j’ai juste besoin d’un bidule où je peux écrire mes bêtises, que ça soit lisible sans avoir besoin de mettre un cache en frontal et &lt;em&gt;éventuellement&lt;/em&gt; qu’on puisse me laisser un commentaire pour me remonter une coquille (ou juste discuter) ?&lt;/p&gt;
&lt;p&gt;En gros, un site web statique avec un bon éditeur de texte quoi&amp;hellip;&lt;/p&gt;
&lt;h2 id="les-sites-statiques-cest-fantastique"&gt;Les sites statiques, c’est fantastique
&lt;/h2&gt;&lt;p&gt;Alors c’est sûr, on peut aussi écrire le HTML/CSS soit même. Mais bon, avoir une application pour nous mâcher le travail et n’avoir que le contenu à gérer, c’est quand même plus sympa.&lt;/p&gt;
&lt;p&gt;Quand j’ai commencé à m’y intéresser, un nom revenait souvent : Jekyll (et Ghost encore avant). Mais je n’ai jamais sauté le pas. Mais depuis, un petit nouveau fait parler de lui. Et comme d’autres, j’ai voulu tester Hugo pour remplacer WordPress. Hugo est un moteur de blog statique écrit en Go. Il a plutôt le vent en poupe et est assez simple à prendre en main.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2019/06/hugo-logo.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;C’est open source donc je peux l’auto-héberger de façon pérenne (coucou les gens qui postent une vie de travail sur Medium). Mais bien plus encore que ca, le contenu, c’est juste du Markdown. On a donc un site entièrement réversible au cas où Hugo viendrait à disparaître.&lt;/p&gt;
&lt;p&gt;La syntaxe utilisée (Markdown, je viens de le dire) est archi connue et relativement simple à prendre en main. D’ailleurs, on peut très bien utiliser des blocs Markdown avec Jetpack dans WordPress pour écrire ses articles.&lt;/p&gt;
&lt;h2 id="tu-te-moques-pas-un-peu-de-nous-"&gt;Tu te moques pas un peu de nous ?
&lt;/h2&gt;&lt;p&gt;Depuis le début, je vous dis que WordPress c’est tout moisi et que Hugo ça a l’air trop cool. Mais ce site&amp;hellip; est encore sous WordPress !&lt;/p&gt;
&lt;p&gt;Pour être honnête, c’était plus difficile à migrer que je le pensais, d’où cet article. &lt;del&gt;A date, j’ai une copie du blog en ligne sous Hugo (EDIT : Down maintenant), qui fonctionne, mais pas totalement isopérimètre en terme de fonctionnalités. Je vais donc laisser vivre en parallèle les deux versions, le temps que je fixe tout ce qui manque.&lt;/del&gt;&lt;/p&gt;
&lt;p&gt;Mais en attendant, je vous propose de me suivre pour cette merveilleuse aventure : Migrer de WordPress vers Hugo.&lt;/p&gt;
&lt;h2 id="installation"&gt;Installation
&lt;/h2&gt;&lt;p&gt;A en croire le site, c’est hyper simple !&lt;/p&gt;
&lt;p&gt;C’est comme toutes les docs d’installs en page principale d’un site pour un logiciel open source, c’est simple mais en fait ça marche jamais (du premier coup). Fou cette coïncidence ! ;-P&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://gohugo.io/getting-started/installing/" target="_blank" rel="noopener"
&gt;gohugo.io/getting-started/installing/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="prérequis"&gt;Prérequis
&lt;/h3&gt;&lt;p&gt;Les prérequis sont en effet plutôt simples. Sous Debian/Ubuntu :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;apt-get update
apt-get upgrade
apt-get install git python-pip
pip install Pygments
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On va ensuite chercher le numéro de la dernière release sur le site &lt;a class="link" href="https://github.com/gohugoio/hugo/releases" target="_blank" rel="noopener"
&gt;github.com/gohugoio/hugo/releases&lt;/a&gt; puis on la wget + dpkg -i comme des cochons :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;export VER=&amp;#34;0.54&amp;#34;
wget https://github.com/gohugoio/hugo/releases/download/v${VER}.0/hugo_${VER}.0_Linux-64bit.deb
dpkg -i ./hugo_0.54.0_Linux-64bit.deb
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="initialiser-le-site"&gt;Initialiser le site
&lt;/h2&gt;&lt;p&gt;Ok, pour l’instant, ils ne nous ont pas trop menti. Ça a l’air simple. On peut initialiser un nouveau site simplement avec la commande hugo new site. Puis ensuite, on peut versionner / sauvegarder blog et tout son contenu avec un dépôt git :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;mkdir hugo &amp;amp;&amp;amp; cd hugo
hugo new site blog.zwindler.fr
git init
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="trouver-un-thème"&gt;Trouver un thème
&lt;/h2&gt;&lt;p&gt;Un des soucis que j’ai avec Hugo (mais avec WordPress aussi alors je suis peut-être juste quelqu’un de pénible ?), c’est de trouver un thème.&lt;/p&gt;
&lt;p&gt;Je veux un thème de blog (mais qu’est ce que vous avez tous à faire du e-commerce avec des moteurs de blog!!!), avec une colonne centrale assez large pour que les bouts de codes/lignes de commandes soient lisibles, avec la possibilité de mettre une image en avant sur la page d’accueil.&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://themes.gohugo.io/" target="_blank" rel="noopener"
&gt;themes.gohugo.io/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Personnellement, le thème qui se rapproche le plus de ce que j’ai aujourd’hui, c’est le thème aether, auquel j’ai apporté quelques modifications. Pour ajouter un thème, le plus propre est d’utiliser la encore git, via la fonctionnalité des submodules.&lt;/p&gt;
&lt;p&gt;Je vous donne mes modifs personnelles sur ce thème (colonne centrale plus large, modification de la taille des images sur la page d’accueil) mais cette étape n’est absolument pas nécessaire.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;diff ./themes/aether/assets/css/style.css.ori ./themes/aether/assets/css/style.css
25c25
&amp;lt; max-width: 50rem;
---
&amp;gt; max-width: 60rem;
165c165
&amp;lt; max-width: 49rem;
---
&amp;gt; max-width: 59rem;
419,420c419,421
&amp;lt; height: 100%;
&amp;lt; width: 15em;
---
&amp;gt; height: 83%;
&amp;gt; padding: 1.5em 0em;
&amp;gt; width: 20em;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="configurer-le-site"&gt;Configurer le site
&lt;/h2&gt;&lt;p&gt;Maintenant qu’on a initialisé le site et choisi un thème, on peut commencer à configurer le site et le thème. En effet, de nombreux paramètres dépendent du thème que vous aurez choisi et des fonctionnalités qu’il intègre. Je ne peux donc que vous donner un exemple :&lt;/p&gt;
&lt;p&gt;Dans le fichier &lt;em&gt;config.toml&lt;/em&gt; à la racine du site, voici ce qui a été paramétré&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;baseURL = &amp;#34;https://blog.example.org/&amp;#34;
languageCode = &amp;#34;fr-fr&amp;#34;
title = &amp;#34;Zwindler&amp;#39;s Reflection&amp;#34;
theme = &amp;#34;aether&amp;#34;
disqusShortname = &amp;#34;zwindler&amp;#34;
[params]
brand = &amp;#34;Zwindler&amp;#39;s Reflection&amp;#34;
description = &amp;#34;Ma vie parmi les lol-cats || Je mine des bitcoins dans mon garage&amp;#34;
homeimg = &amp;#34;./wp-content/uploads/2019/05/servers.jpg&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;De plus, pour ajouter la coloration syntaxique sur les partions de code, il faut ajouter dans la conf les deux paramètres suivants :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;pygmentsCodefences = true
pygmentsStyle = &amp;#34;pygments&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Puis lancer la commande suivante :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hugo gen chromastyles --style=monokai &amp;gt; themes/aether/assets/css/syntax.css
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="extraire-les-données-de-wordpress"&gt;Extraire les données de WordPress
&lt;/h2&gt;&lt;p&gt;OK ! Notre site est paramétré. Si vous êtes sur cet article simplement pour découvrir Hugo, vous avez déjà un blog fonctionnel. Il ne reste plus qu’à écrire du contenu et générer le code statique.&lt;/p&gt;
&lt;p&gt;cependant, dans mon cas, j’ai parlé depuis le début de migrer depuis WordPress. Je pars donc du principe que, comme moi, vous avez de nombreux articles (et éventuellement commentaires) que vous souhaitez conserver. Il serait dommage de devoir repartir de 0.&lt;/p&gt;
&lt;p&gt;Heureusement, il est possible de récupérer les données existantes d’un WordPress pour les réimporter dans Hugo. Le &lt;a class="link" href="https://gohugo.io/tools/migrations/" target="_blank" rel="noopener"
&gt;site officiel liste les options possibles&lt;/a&gt; et notamment un plugin qui converti les articles (et éventuellement les commentaires sous les articles) en Markdown.&lt;/p&gt;
&lt;p&gt;Tout simplement (enfin&amp;hellip; n’exagérons rien).&lt;/p&gt;
&lt;h2 id="wordpress-to-hugo-exporter"&gt;wordpress-to-hugo-exporter
&lt;/h2&gt;&lt;p&gt;Je suis donc parti sur le projet &lt;a class="link" href="https://github.com/SchumacherFM/wordpress-to-hugo-exporter" target="_blank" rel="noopener"
&gt;wordpress-to-hugo-exporter&lt;/a&gt;, qui est une extension native à WordPress permettant de réaliser cet export &amp;ldquo;en un clic&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;La première chose à faire pour installer cette extension est de vérifier que votre serveur qui héberge le WordPress dispose bien de l’extension PHP zip.so.&lt;/p&gt;
&lt;p&gt;Si c’est bien le cas, on peut cloner le projet git directement dans le dossier plugin de WordPress&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cat /etc/php.d/40-zip.ini
; Enable ZIP extension module
extension=zip.so
cd /var/www/html/wp-content/plugins/
git clone https://github.com/SchumacherFM/wordpress-to-hugo-exporter
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="il-nous-faut-plus-de-ziggourats-ram"&gt;Il nous faut plus de &lt;del&gt;ziggourats&lt;/del&gt; RAM
&lt;/h2&gt;&lt;p&gt;Ça arrive tout le temps&amp;hellip; Il n’est pas rare que les processus de ce genre (export/import/package de sauvegarde) nécessitent une grande quantité de RAM. &lt;a class="link" href="https://blog.zwindler.fr/2016/04/30/resoudre-erreurs-de-fichiers-gros-lors-imports-xwiki/" &gt;J’avais déjà eu le souci avec Xwiki&lt;/a&gt;, je savais à quoi m’attendre ici.&lt;/p&gt;
&lt;p&gt;Si vous aussi vous avez comme moi pas mal de contenu (250 articles, 500 Mo de media), sachez que vous devrez probablement augmenter les tailles mémoires autorisées par WordPress dans le fichier wp-config.php.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;// Set initial default constants including WP_MEMORY_LIMIT, WP_MAX_MEMORY_LIMIT, WP_DEBUG, SCRIPT_DEBUG, WP_CONTENT_DIR and WP_CACHE.
wp_initial_constants();
define( &amp;#39;WP_MEMORY_LIMIT&amp;#39;, &amp;#39;2048M&amp;#39; );
define( &amp;#39;WP_MAX_MEMORY_LIMIT&amp;#39;, &amp;#39;2048M&amp;#39; );
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;De même, le temps que le processus d’export arrive à son terme, votre page web sera peut être partie en timeout. Deux possibilités dans ce cas.&lt;/p&gt;
&lt;p&gt;Soit vous exécutez l’export depuis la ligne de commande&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cd wp-content/plugins/wordpress-to-hugo-exporter/
This is your file!
/tmp/wp-hugo.zip
php hugo-export-cli.php
#ou pour s&amp;#39;affranchir des limites RAM en même temps
php hugo-export-cli.php memory_limit=-1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Dans tous les cas, vous devriez finir par obtenir un ZIP, contenant tous vos articles et toutes vos pages, au format Markdown. Le contenu de ce ZIP est à déposer dans le sous dossier content de votre arborescence de blog Hugo :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;unzip wp-hugo.zip
cd hugo-export
cp -r posts wp-content ~/hugo/blog.zwindler.fr/content/
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="nettoyage-du-markdown"&gt;Nettoyage du markdown
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Ca y est ? On peut générer le site statique maintenant ?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Et bien non&amp;hellip; pas encore. En fait, le processus d’export de WordPress vers Markdown n’est pas parfait.&lt;/p&gt;
&lt;p&gt;J’ai du &amp;ldquo;nettoyer&amp;rdquo; le code Markdown pour que le résultat soit enfin acceptable.&lt;/p&gt;
&lt;p&gt;La première chose, difficilement compréhensible, est que s’il y a bien les données correspondant à l’image &amp;ldquo;mise en avant&amp;rdquo; pour chacun de nos article, le nom de la variable est image alors qu’Hugo attend le nom image.&lt;/p&gt;
&lt;p&gt;On peut régler ça avec un bête &amp;ldquo;sed&amp;rdquo;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;find . -name &amp;#34;*.md&amp;#34; -exec sed -i &amp;#34;s/featuredImage/image/g&amp;#34; {} \;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Par défaut, toutes les images de wordpress sont réduites dans plusieurs tailles, pour optimiser les temps de chargement. Cependant, dans l’export, on se retrouver avec des vignettes très petites, difficilement lisibles.&lt;/p&gt;
&lt;p&gt;Pour me simplifier la vie, j’ai utilisé cette commande pour remettre les images en taille complète. Attention cependant, cela peut avoir un impact important sur les temps de chargement des pages si vous avez de très grandes images&amp;hellip;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;find . -name &amp;#34;*.md&amp;#34; -exec sed -i &amp;#39;s/-220x162//g&amp;#39; {} \;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Un des problèmes que j’ai avec l’éditeur de WordPress, c’est justement qu’il réencode tous les caractères spéciaux avec leurs codes HTML. D’un point de vue lecture de texte simple, ça ne pose souvent pas de problème. Cependant pour tout ce qui est scripts et bouts de code, ça génère très souvent des erreurs.&lt;/p&gt;
&lt;p&gt;Voici une liste des caractères que j’ai remplacés dans mon Markdown. Attention cependant, il pourrait que cela remplace des caractères spéciaux que vous auriez légitimement (pour une raison qui m’échappe) encodé en HTML&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;find . -name &amp;#34;*.md&amp;#34; -exec sed -i &amp;#34;s/&amp;gt;/&amp;gt;/g&amp;#34; {} \;
find . -name &amp;#34;*.md&amp;#34; -exec sed -i &amp;#34;s/&amp;lt;/&amp;lt;/g&amp;#34; {} \;
find . -name &amp;#34;*.md&amp;#34; -exec sed -i &amp;#34;s/&amp;amp;/&amp;amp;/g&amp;#34; {} \;
find . -name &amp;#34;*.md&amp;#34; -exec sed -ie &amp;#34;s/ /\n/g&amp;#34; {} \;
find . -name &amp;#34;*.md&amp;#34; -exec sed -i &amp;#34;s/–/–/g&amp;#34; {} \;
find . -name &amp;#34;*.md&amp;#34; -exec sed -i &amp;#34;s/—/—/g&amp;#34; {} \;
find . -name &amp;#34;*.md&amp;#34; -exec sed -i &amp;#34;s/…/…/g&amp;#34; {} \;
find . -name &amp;#34;*.md&amp;#34; -exec sed -i &amp;#34;s/″/″/g&amp;#34; {} \;
find . -name &amp;#34;*.md&amp;#34; -exec sed -i &amp;#34;s/′/″/g&amp;#34; {} \;
find . -name &amp;#34;*.md&amp;#34; -exec sed -i &amp;#34;s/«/«/g&amp;#34; {} \;
find . -name &amp;#34;*.md&amp;#34; -exec sed -i &amp;#34;s/»/»/g&amp;#34; {} \;
find . -name &amp;#34;*.md&amp;#34; -exec sed -i &amp;#34;s/’/’/g&amp;#34; {} \;
find . -name &amp;#34;*.md&amp;#34; -exec sed -i &amp;#34;s/‘/‘/g&amp;#34; {} \;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;J’ai aussi trouvé les caractères suivants, que je n’ai pas osé réencoder de peur de casser des URLs :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;amp;#038&lt;/li&gt;
&lt;li&gt;&amp;amp;#039&lt;/li&gt;
&lt;li&gt;&amp;quot;&lt;/li&gt;
&lt;li&gt;'&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Et pour finir, dans WordPress, j’utilisais dans WordPress un plugin qui entourait mes bouts de code de balises HTML &lt;em&gt;pre&lt;/em&gt; pour afficher du code avec la coloration syntaxique.&lt;/p&gt;
&lt;p&gt;Dans Hugo, les balises sont celle de markdown. Voici donc la commande pour convertir les balises pre en balise de code Markdown&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;find . -name &amp;#34;*.md&amp;#34; -exec sed -ie &amp;#34;s/&amp;lt;pre.*&amp;gt;/\n\`\`\`\n/g&amp;#34; {} \;
find . -name &amp;#34;*.md&amp;#34; -exec sed -ie &amp;#34;s/&amp;lt;\/pre&amp;gt;/\n\`\`\`\n/g&amp;#34; {} \;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="tester-le-blog"&gt;Tester le blog
&lt;/h2&gt;&lt;p&gt;Voila !!! Vous pouvez enfin tester votre blog, avec votre contenu Markdown. Hugo propose un serveur web que vous pouvez utiliser localement pour vous assurer que tout vas bien avant d’uploader votre site statique.&lt;/p&gt;
&lt;p&gt;Il n’est évidement pas question d’utiliser ce mode en production. Il s’agit seulement d’un mode &amp;ldquo;preview&amp;rdquo;.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ hugo server
Start building sites …
hugo v0.88.1-5BC54738+extended linux/amd64 BuildDate=2021-09-04T09:39:19Z VendorInfo=gohugoio
| FR
-------------------+-------
Pages | 3234
Paginator pages | 354
Non-page files | 0
Static files | 0
Processed images | 1
Aliases | 1439
Sitemaps | 1
Cleaned | 0
Built in 4895 ms
Watching for changes in /home/zwindler/sources/hugo/blog.zwindler.fr/{assets,content,data,layouts,static,themes}
Watching for config changes in /home/zwindler/sources/hugo/blog.zwindler.fr/config.yaml, /home/zwindler/sources/hugo/blog.zwindler.fr/themes/hugo-theme-stack/config.yaml
Environment: &amp;#34;development&amp;#34;
Serving pages from memory
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="sauvegardergénérerdéployer-le-site"&gt;Sauvegarder/générer/déployer le site
&lt;/h2&gt;&lt;p&gt;Si après vérification, votre blog vous convient, vous n’avez alors plus qu’à &amp;ldquo;sauvegarder&amp;rdquo; votre site via git.&lt;/p&gt;
&lt;p&gt;Vous pouvez ensuite générer le site statique en invoquant simplement la commande hugo&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ hugo
| EN
+------------------+-------+
Pages | 2634
Paginator pages | 231
Non-page files | 10951
Static files | 73
Processed images | 0
Aliases | 1187
Sitemaps | 1
Cleaned | 0
Total in 5555 ms
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Les pages statiques seront générées et sauvegardées dans le sous dossier public. Vous pourrez enfin simplement copier ce dossier sur n’importe quel serveur web (voire même des blobs sur un cloud provider) et vous aurez votre site statique !!!&lt;/p&gt;
&lt;p&gt;Enjoy !&lt;/p&gt;</description></item><item><title>Fusionner plusieurs dépôts Git tout en gardant l’historique</title><link>https://blog.zwindler.fr/2017/03/24/fusionner-plusieurs-repos-git-avec-historique/</link><pubDate>Fri, 24 Mar 2017 13:00:31 +0000</pubDate><guid>https://blog.zwindler.fr/2017/03/24/fusionner-plusieurs-repos-git-avec-historique/</guid><description>&lt;img src="https://blog.zwindler.fr/2017/03/git_logo.webp" alt="Featured image of post Fusionner plusieurs dépôts Git tout en gardant l’historique" /&gt;&lt;h2 id="je-découvre-git"&gt;Je découvre Git
&lt;/h2&gt;&lt;p&gt;L’avantage de travailler en &lt;strong&gt;#DevOps&lt;/strong&gt; (et c’est d’ailleurs tout le principe), est que la proximité avec les Devs (et inversement les Ops) incite à comprendre les méthodes de travail et à utiliser les outils des autres. Et bien sûr, en cas de difficulté, je n’ai qu’à me retourner et demander un coup de main aux experts ;-). Dans mon exemple, j’avais un petit souci avec Git.&lt;/p&gt;
&lt;p&gt;J’avais initialement stocké des playbooks Ansible dans des dépôts Git distincts et bien sûr quand j’ai commencé à en avoir beaucoup (~20) j’ai changé d’avis. Cela devenait trop contraignant à exploiter sachant que les playbooks (découpés en rôles) sont parfois interdépendants.&lt;/p&gt;
&lt;p&gt;Le plus simple aurait été de regrouper l’ensemble des sources à la version actuelle dans un même dossier, puis de tout simplement recréer un dépôt. Cependant, de cette manière, je perdais l’ensemble de l’historique des commits. Idem si j’avais copié les fichiers dans un des dépôts existant (je n’aurai gardé que l’historique d’un seul dépôt).&lt;/p&gt;
&lt;p&gt;N’étant pas expert Git, il y a probablement plusieurs façon, cependant, je peux attester que celle a fonctionné dans mon cas ;-).&lt;/p&gt;
&lt;h2 id="regarder-comment-git-fonctionne"&gt;Regarder comment Git fonctionne
&lt;/h2&gt;&lt;p&gt;Je ne vais pas vous faire un cours pour vous expliquer comment Git fonctionne, il existe de nombreuses ressources qui mettent en avant les avantages de Git par rapport à d’autres logiciels de gestion de version.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note : Si vous débutez sur ce &lt;a class="link" href="https://fr.wikipedia.org/wiki/Logiciel_de_gestion_de_versions" target="_blank" rel="noopener"
&gt;VCS&lt;/a&gt;, je vous conseille vivement de commencer par dérouler un tutoriel pour comprendre les bases et pourquoi par faire quelques tutoriels interactifs (sous la forme de petites « énigmes »). Je donne quelques exemples en fin d’article.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Je me contenterais simplement rappeler que Git est un logiciel de gestion de version qui, à la différence de SVN, n’a pas de serveur centralisé. Ce point, pas forcément intuitif si vous venez de SVN, est extrêmement important.&lt;/p&gt;
&lt;p&gt;Au delà du fait que ce caractère décentralisé est un des points qui a fait la popularité de ce VCS, cela va nous permettre de régler mon problème :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;je vais créer un nouveau dépôt vierge&lt;/li&gt;
&lt;li&gt;lui ajouter l’URL dans sa configuration les dépôts existants en tant que &lt;strong&gt;remote&lt;/strong&gt;, lui faisant croire que ce sont des dépôts provenant du même code source&lt;/li&gt;
&lt;li&gt;recréer artificiellement entre les deux dépôts un historique « commun » avec &lt;strong&gt;git rebase&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="au-travail-maintenant"&gt;Au travail maintenant
&lt;/h2&gt;&lt;p&gt;La première étape consiste donc à créer un nouveau dépôt git. Créez un dossier vide, mettez vous dedans et initialisez un nouveau dépôt grâce à la commande suivante :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git init #pour créer un nouveau repo dans le dossier courant
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Que fait Git ?&lt;/p&gt;
&lt;p&gt;Et bien dans le cas présent, il se contente de créer un dossier &lt;strong&gt;.git&lt;/strong&gt; dans lequel il stockera ses métadata, ainsi qu’un fichier &lt;strong&gt;config&lt;/strong&gt; dans lequel on retrouve toutes les options du dépôt. Ouvrez le avec votre éditeur de texte préféré, voilà à quoi ça devrait ressembler :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
symlinks = false
ignorecase = true
hideDotFiles = dotGitOnly
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On va donc maintenant y ajouter les URLs des dépôts en tant que « remotes ». Dans mon cas, les dépôts sont accessibles via des URL HTTPS via Gitlab, mais ce n’est aucunement un prérequis. Vous devez juste pouvoir renseigner les « remotes » dans votre fichier &lt;strong&gt;.git/config&lt;/strong&gt;.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[remote &amp;#34;depot_ansible_1&amp;#34;]
url = https://@IPgitlab/automatisation/depot_ansible_1.g1t
fetch = +refs/heads/*:refs/remotes/origin/*
[remote &amp;#34;depot_ansible_2&amp;#34;]
url = https://@IPgitlab/automatisation/depot_ansible_2.g1t
fetch = +refs/heads/*:refs/remotes/origin/*
[remote &amp;#34;depot_ansible_3&amp;#34;]
url = https://@IPgitlab/automatisation/depot_ansible_3.g1t
fetch = +refs/heads/*:refs/remotes/origin/*
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Dans l’exemple suivant, j’ai donc ajouté des dépôts, nommés &lt;strong&gt;depot_ansible_1&lt;/strong&gt;, &lt;strong&gt;depot_ansible_2&lt;/strong&gt; et &lt;strong&gt;depot_ansible_3&lt;/strong&gt;, tous accessibles depuis mon Gitlab aux URLs données.&lt;/p&gt;
&lt;p&gt;Comme on part d’un dépôt vide, le premier git pull vers &lt;strong&gt;depot_ansible_1&lt;/strong&gt; devrait bien se passer. Git se contente d’intégrer l’ensemble du code et des commits du dépôt &lt;strong&gt;depot_ansible_1&lt;/strong&gt; comme si on avait fait un « clone ».&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git pull depot_ansible_1 master
&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;So far, so good&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="ca-se-complique-un-peu"&gt;Ca se complique « un peu »
&lt;/h2&gt;&lt;p&gt;Évidemment on ne peut plus reproduire la manœuvre précédente. Si vous tentez de le faire, vous recevrez un message qui vous dira que les deux dépôts ne partagent pas d’historique commun. On va donc faire un pull avec l’option &lt;strong&gt;rebase&lt;/strong&gt;. Mais avant tout un petit coup d’œil au &lt;strong&gt;man&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/03/git_pull_rebase.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Dans mon cas, c’est précisément ce que je souhaite faire. Pour autant, je vous engage moi aussi à faire attention ;-).&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git pull -r depot_ansible_2 master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A partir de ce moment là, git tente de trouver un point commun entre les deux arbres des 2 premiers dépôts (potentiellement jusqu’à l’initialisation du dépôt), puis recréée un historique à partir des deux dépôts en rejouant un à un les commits des deux dépôts.&lt;/p&gt;
&lt;p&gt;Un dernier point, si vous tombez, lors du rebase, sur un conflit, vous devez le résoudre manuellement. Ajoutez les fichiers corrigés avec « add », puis continuez avec « rebase &amp;ndash;continue »&lt;/p&gt;
&lt;h2 id="cest-fini-on-nettoie-un-peu"&gt;C’est fini, on nettoie un peu
&lt;/h2&gt;&lt;p&gt;Mission accomplie pour ces deux dépôts, qui sont maintenant fusionnés dans un seul dépôts avec leurs historiques de commits respectifs ! Vous n’avez plus qu’à reproduire la procédure pour chacun des dépôts (si vous en avez d’autre, &lt;strong&gt;depot_ansible_3&lt;/strong&gt; dans mon exemple).&lt;/p&gt;
&lt;p&gt;Cependant, si vous avez des messages du genre « premier commit » dans chacun de vos dépôts, ces messages n’ont pas vraiment de sens. On peut donc réutiliser le principe du rebase pour réécrire une nouvelle fois l’historique. Le rebase vous proposera la liste des commits dans un éditeur et vous pourrez sélectionner manuellement ceux que vous voulez garder (pick) ou modifier (reword).&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git rebase -i HEAD~X #puis sélectionner les commit à modifier et les corriger un à un
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Par exemple, si j’ai 4 commits, et que je veux réécrire le 1er de depot_ansible_2&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git rebase -i HEAD~3
pick 8c98724 commit 1 de depot_ansible_1
reword 5ad60bb commit 1 de depot_ansible_2
pick 82b0cc3 commit de depot_ansible_2
# Rebase dff1fb2..82b0cc3 onto dff1fb2 (3 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# [...]
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="documentation-complémentaire"&gt;Documentation complémentaire
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://@IPgit-scm.com/book/fr/v2" target="_blank" rel="noopener"
&gt;Pro Git : la référence des livres sur Git&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://try.github.io/levels/1/challenges/1" target="_blank" rel="noopener"
&gt;Un tutoriel interactif de GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://delicious-insights.com/fr/articles/bien-utiliser-git-merge-et-rebase/" target="_blank" rel="noopener"
&gt;Un article intéressant sur la différence entre git merge et git rebase&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Automatiser la création d’une image Dockerhub</title><link>https://blog.zwindler.fr/2017/01/24/automatiser-la-creation-dune-image-dockerhub/</link><pubDate>Tue, 24 Jan 2017 13:00:53 +0000</pubDate><guid>https://blog.zwindler.fr/2017/01/24/automatiser-la-creation-dune-image-dockerhub/</guid><description>&lt;img src="https://blog.zwindler.fr/2017/01/dockerhub.webp" alt="Featured image of post Automatiser la création d’une image Dockerhub" /&gt;&lt;h2 id="créer-un-automated-build-sur-le-dockerhub"&gt;Créer un automated build sur le Dockerhub
&lt;/h2&gt;&lt;p&gt;Ça fait quelques semaines maintenant que j’ai mis à disposition &lt;a class="link" href="https://blog.zwindler.fr/2016/09/15/installer-xwiki-8-2-1-avec-docker-compose-en-2-lignes-de-commandes/" &gt;sur le Dockerhub ma première image Docker&lt;/a&gt;. Sans aller jusqu’à dire qu’elle a déplacé les foules, je suis assez content de voir que je ne suis pas le seul à l’utiliser avec une 100aine de « pull », même si sur le segment des images préconfigurées pour XWiki, les builds de Hellyna et Lavadiablo sont bien plus souvent téléchargées. Et c’était sans compter sur &lt;a class="link" href="https://hub.docker.com/_/xwiki/" target="_blank" rel="noopener"
&gt;l’image Docker officielle de XWiki&lt;/a&gt; qui est sortie juste avant que je ne publie cet article !&lt;/p&gt;
&lt;p&gt;Mais aussi auto-satisfait que je suis, je suis forcé de le reconnaître, cette image Docker pêche d’un défaut de jeunesse : la mise à disposition d’une nouvelle version nécessite :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Que je modifie (et éventuellement que je le push sur Github) mon code sur mon repository git&lt;/li&gt;
&lt;li&gt;Que je la build moi même à partir du code&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker build -t zwindler/xwiki-tomcat8:latest .
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Et une fois l’image sur mon Docker registry local, que je lance la commande&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker push zwindler/xwiki-tomcat
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Mais, vous l’aurez deviné, il y a mieux ;-)&lt;/p&gt;
&lt;p&gt;Une fonctionnalité de Dockerhub vous permet de créer une image que vous poussez manuellement ou une image dont la création est &lt;strong&gt;automatique&lt;/strong&gt;. On peut distinguer ces deux types d’images par la mention &lt;strong&gt;automated build&lt;/strong&gt; sous le nom de celle ci.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/01/dockerhub_automated_build.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h2 id="comment-en-profiter-"&gt;Comment en profiter ?
&lt;/h2&gt;&lt;p&gt;Tout commence d’abord par renseigner quelques informations dans votre profil. Dans les propriétés de votre compte, il y a un menu « Linked Accounts &amp;amp; Services ».&lt;/p&gt;
&lt;p&gt;Ce menu vous permet de lier le Dockerhub avec un ou plusieurs comptes Github/Bitbucket via une autorisation de type OAuth.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/01/dockerhub_profile_2.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Au delà de simplement lier les deux comptes, Dockerhub paramètre vos dépôts git et y ajoute des services (webhooks préconfigurés) permettant de prévenir automatiquement Dockerhub de la présence de code mise à jour sur GitHub.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/01/dockerhub_profile_3.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/01/dockerhub_profile_5.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;On autorise l’accès en lecture/écriture sur le compte. On peut le mettre en lecture seule mais il faudra paramétrer les webhooks à la main !&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/01/dockerhub12.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Présence du service dans les paramètres du projet Github&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="créer-son-premier-automated-build"&gt;Créer son premier automated build
&lt;/h2&gt;&lt;p&gt;Maintenant que les permissions sont bien passées entre Github et Dockerhub, on peut créer son image automatique.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/01/dockerhub_profile_6.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Ici j’ai sélectionné mon compte Github, puis le projet qui contient mon projet &lt;strong&gt;xwiki-tomcat&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/01/dockerhub_profile_7.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;La suite de la création de l’image est similaire à la création d’une image « non automatique ». On donne un nom à l’image ainsi qu’une petite description et on valide en cliquant sur &lt;strong&gt;create&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/01/dockerhub_profile_8.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Dans mon cas, ça n’a pas fonctionné du premier coup et le &lt;em&gt;build&lt;/em&gt; a échoué car par défaut l’image cherchait le Dockerfile à la racine du projet Github. Sur mon dépôt git, le Dockerfile est situé dans un sous dossier, la racine contenant le README et un fichier docker-compose.&lt;/p&gt;
&lt;p&gt;Dans ce cas précis, il faut donc aller dans le &lt;strong&gt;build settings&lt;/strong&gt; et renseigner la variable « Dockerfile location ».&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/01/dockerhub_profile_9.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A noter :&lt;/strong&gt; pour plus de clarté dans mes images, j’ai indiqué que la branche Master dans git correspondait au tag « latest » et ait ajouté une seconde ligne avec la branche Master taguée avec le numéro de version (actuellement 8.4.4).&lt;/p&gt;
&lt;p&gt;Ainsi, les utilisateurs pourront soit récupérer la dernière version, soit spécifier la version 8.4.4 manuellement.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/01/dockerhub_profile_11.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Et cerise sur le gâteau, j’ai également &lt;strong&gt;ajouté une branche 7.4.5-lts&lt;/strong&gt; dans Github qui me permet de proposer de manière optionnelle une image préconfigurées avec la version LTS actuelle de XWiki.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;Il est très simple de créer un &lt;strong&gt;automated build&lt;/strong&gt; dans Dockerhub et vous avez donc tout intérêt à arrêter de pusher manuellement vos images si vous déposer votre code Github.com.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/01/dockerhub_automated_build_front.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Seul bémol, le manque d’intégration avec Git ou même Gitlab qui sera un vrai point noir si vous avez votre propre dépôt personnel ou d’entreprise en dehors des deux services en lignes proposés par Dockerhub.&lt;/p&gt;
&lt;h2 id="sources"&gt;Sources
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.docker.com/docker-hub/builds/" target="_blank" rel="noopener"
&gt;docs.docker.com/docker-hub/builds/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Installer XWiki 8.2.1 avec Docker (compose) en 2 lignes de commandes</title><link>https://blog.zwindler.fr/2016/09/15/installer-xwiki-8-2-1-avec-docker-compose-en-2-lignes-de-commandes/</link><pubDate>Thu, 15 Sep 2016 11:00:28 +0000</pubDate><guid>https://blog.zwindler.fr/2016/09/15/installer-xwiki-8-2-1-avec-docker-compose-en-2-lignes-de-commandes/</guid><description>&lt;img src="https://blog.zwindler.fr/2016/09/article_docker_xwiki.webp" alt="Featured image of post Installer XWiki 8.2.1 avec Docker (compose) en 2 lignes de commandes" /&gt;&lt;h2 id="automatiser-linstallation-du-xwiki-avec-docker-compose"&gt;Automatiser l’installation du XWiki avec Docker compose
&lt;/h2&gt;&lt;p&gt;Pour ceux qui ne le savent, XWiki est une plateforme collaborative de gestion de la connaissance (généralement appelé wiki, KMDB en ITIL). L’exemple le plus connu de wiki est bien entendu Wikipedia qui tourne par contre lui sous Mediawiki (un autre wiki, moins convivial mais très répandu). J’ai déjà écris pas mal au sujet du XWiki donc si vous voulez un petit tour d’horizon de ce qu’on peut faire avec, vous pouvez &lt;a class="link" href="https://blog.zwindler.fr/recherche/?keyword=xwiki" &gt;cliquer ici&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Je commence à en avoir installé un certain nombre :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;que ce soit pour tester les nouvelles version&lt;/li&gt;
&lt;li&gt;en recette ou en production pour de nouvelles équipes&lt;/li&gt;
&lt;li&gt;faire des tests sur Docker&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si l’installation d’un XWiki est simplissime si vous utilisez les outils préconfigurés par défaut dans l’installeur JAR, l’installation d’une instance XWiki avec Tomcat et PostgreSQL est un peu plus complexe. Du coup, j’ai eu besoin à plusieurs reprise d’ouvrir mon propre tutoriel qui guide pas à pas &lt;a class="link" href="https://blog.zwindler.fr/2015/12/16/installation-de-xwiki-redhat-7/" &gt;l’installation de la version 7 de XWiki sur un Redhat Entreprise Linux 7 (ou CentOS)&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="vous-avez-dit-docker-"&gt;Vous avez dit Docker ?
&lt;/h2&gt;&lt;p&gt;Et c’est notamment grâce au besoin que j’ai eu de faire des tests sur Docker que j’en suis venu à réaliser une image Docker XWiki.&lt;/p&gt;
&lt;p&gt;XWiki était le parfait exemple pour s’initier à :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;la création d’un service multi-conteneurs séparés par Tiers (Tomcat, PostgreSQL)&lt;/li&gt;
&lt;li&gt;la rédaction d’un DockerFile qui automatise entièrement l’installation et la configuration de l’application java XWiki à partir de l’image standard Tomcat 8&lt;/li&gt;
&lt;li&gt;l’ajout d’une orchestration de base avec Docker Compose&lt;/li&gt;
&lt;li&gt;la mise en ligne d’une image publique avec Docker Hub&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Un des avantages de Docker, c’est que grâce à l’aspect « portable » des conteneurs :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Avec ce conteneur, je peux garantir que les fichiers de configuration que j&amp;rsquo;embarque avec l’image seront compatibles.&lt;/li&gt;
&lt;li&gt;Sans conteneur, avec un serveur Tomcat déjà existant et en fonction des fichiers de configurations embarqués selon telle ou telle distribution, les instructions que je donne dans &lt;a class="link" href="https://blog.zwindler.fr/2015/12/16/installation-de-xwiki-redhat-7/" &gt;mon article « pas à pas »&lt;/a&gt; pourraient ne pas toujours fonctionner.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="pour-les-plus-pressés"&gt;Pour les plus pressés
&lt;/h2&gt;&lt;p&gt;Quelque soit la méthode que vous choisirez, le XWiki sera opérationnel et accessible sur le port 8080 à l’issue de ces commandes. Il faudra juste passer le &lt;a class="link" href="https://blog.zwindler.fr/2015/12/16/installation-de-xwiki-redhat-7/" &gt;« First Installation Wizard »&lt;/a&gt; et &lt;a class="link" href="https://blog.zwindler.fr/2016/09/01/personnalisation-de-base-apres-installation-mise-a-jour-dun-xwiki/" &gt;commencer à configurer le XWiki&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="avec-docker-compose"&gt;Avec Docker Compose
&lt;/h3&gt;&lt;p&gt;Docker compose se charge pour vous, à partir du fichier &lt;strong&gt;&lt;em&gt;docker-compose.yml&lt;/em&gt;&lt;/strong&gt;, de :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;télécharger/builder l’image des conteneurs Postgresql et XWiki&lt;/li&gt;
&lt;li&gt;configurer ces conteneurs&lt;/li&gt;
&lt;li&gt;démarrer les conteneurs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C’est donc forcément plus simple de le faire marcher en 2 lignes de commandes ;-).&lt;/p&gt;
&lt;p&gt;[Edit]&lt;br&gt;
A priori il n’est plus nécessaire de faire un « &lt;strong&gt;chmod +x xwiki-tomcat/xwiki-tomcat-entrypoint.sh&lt;/strong&gt; » sinon ça ne fonctionne pas, j’ai corrigé les permissions sur le github&lt;br&gt;
[/Edit]&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git clone https://github.com/zwindler/docker-xwiki.git &amp;amp;&amp;amp; cd docker-xwiki
docker-compose -f compose/docker-compose.yml up -d
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="avec-docker-depuis-les-sources"&gt;Avec Docker depuis les sources
&lt;/h3&gt;&lt;p&gt;Avec Docker uniquement, il faudra forcément tout faire à la main. Donc il faudra créer le network, démarrer successivement l’image PostgreSQL puis l’image Tomcat modifiée par mes soins.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker network create -d bridge xwiki-nw
docker run --net=xwiki-nw -itd --name xwiki-postgres -e POSTGRES_DB=xwiki -e POSTGRES_USER=xwiki -e POSTGRES_PASSWORD=xwiki postgres
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;git clone https://github.com/zwindler/docker-xwiki.git &amp;amp;&amp;amp; cd docker-xwiki
chmod +x xwiki-tomcat/xwiki-tomcat-entrypoint.sh
docker build -t zwindler/xwiki-tomcat8:latest .
docker run --net=xwiki-nw -itd --name xwiki-tomcat -p 8080:8080 -e POSTGRES_INSTANCE=xwiki-postgres zwindler/xwiki-tomcat8
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="avec-docker-et-docker-hub"&gt;Avec Docker et Docker Hub
&lt;/h3&gt;&lt;p&gt;Un cran plus simple que la version précédente car je viens d’uploader l’image zwindler/xwiki-tomcat sur Docker Hub. Elle est donc automatiquement téléchargée depuis Docker hub lors de la commande &lt;strong&gt;docker run&lt;/strong&gt;. Pas besoin de « chmod » ni de builder l’image.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker network create -d bridge xwiki-nw
docker run --net=xwiki-nw -itd --name xwiki-postgres -e POSTGRES_DB=xwiki -e POSTGRES_USER=xwiki -e POSTGRES_PASSWORD=xwiki postgres
docker run --net=xwiki-nw -itd --name xwiki-tomcat -p 8080:8080 -e POSTGRES_INSTANCE=xwiki-postgres zwindler/xwiki-tomcat8
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="limage-en-question"&gt;L’image en question
&lt;/h2&gt;&lt;p&gt;L’ensemble des sources sont disponibles sur &lt;a class="link" href="https://github.com/zwindler/docker-xwiki" target="_blank" rel="noopener"
&gt;Github dans mon repository docker-xwiki&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Voici le contenu du DockerFile :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;FROM tomcat:8-jre8
MAINTAINER Denis GERMAIN &amp;lt;denis@example.com&amp;gt;
ENV POSTGRES_INSTANCE=xwiki-pgsql
ENV POSTGRES_PORT=5432
ENV POSTGRES_DB=xwiki
ENV POSTGRES_USER=xwiki
ENV POSTGRES_PASSWORD=xwiki
RUN rm -rf webapps/* &amp;amp;&amp;amp; \
curl -L \
&amp;#39;http://download.forge.ow2.org/xwiki/xwiki-enterprise-web-8.2.1.war&amp;#39; \
-o xwiki.war &amp;amp;&amp;amp; \
unzip -d webapps/xwiki xwiki.war &amp;amp;&amp;amp; \
rm -f xwiki.war
RUN curl -L \
&amp;#39;https://jdbc.postgresql.org/download/postgresql-9.4.1208.jar&amp;#39; \
-o &amp;#39;webapps/xwiki/WEB-INF/lib/postgresql-9.4-1208.jdbc42.jar&amp;#39;
COPY hibernate.cfg.xml webapps/xwiki/WEB-INF/
COPY xwiki.cfg webapps/xwiki/WEB-INF/
COPY setenv.sh bin/setenv.sh
RUN sed -i &amp;#34;s/redirectPort=\&amp;#34;8443\&amp;#34; /redirectPort=\&amp;#34;8443\&amp;#34; URIEncoding=\&amp;#34;UTF-8\&amp;#34; /&amp;#34; conf/server.xml
COPY xwiki-tomcat-entrypoint.sh /
ENTRYPOINT [&amp;#34;/xwiki-tomcat-entrypoint.sh&amp;#34;]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Des variables d’environnement ENV sont à votre disposition pour adapter à votre contexte (on en parlera un peu plus loin). La première étape consiste à télécharger la dernière version en date du XWiki, puis le pilote JDBC PostgreSQL correspondant.&lt;/p&gt;
&lt;p&gt;Les fichiers de Tomcat sont adaptés pour un fonctionnement avec XWiki (Xmx java, autorisation des « / » dans les URLs, &amp;hellip;) et les fichiers de configuration de XWiki sont paramétrés pour accepter l’instance PostgreSQL.&lt;/p&gt;
&lt;h2 id="personnalisation"&gt;Personnalisation
&lt;/h2&gt;&lt;p&gt;Pour permettre un peu plus de souplesse dans l’utilisation de la base de données, j’ai volontairement ajouté des variables d’environnement et un script « ENTRYPOINT ». Ce script sert à paramétrer à la première exécution les valeurs définies en début de DockerFile (ENV).&lt;/p&gt;
&lt;p&gt;Ceci permet à la fois de mettre à disposition une image Docker clé en main si l’utilisateur ne souhaite rien modifier et tout laisser par défaut, ou à l’inverse, de fournir des variables qui lui sont propres et personnaliser automatiquement son instance.&lt;/p&gt;
&lt;p&gt;Vous pourrez ainsi par exemple changer le mot de passe et/ou le nom de l’instance PostgreSQL (soit via modification du docker-compose.yml, soit directement en modifiant le DockerFile).&lt;/p&gt;
&lt;h2 id="problème-allow_encoded_slashtrue"&gt;Problème ALLOW_ENCODED_SLASH=true
&lt;/h2&gt;&lt;p&gt;Malgré l’ajout de &lt;em&gt;ALLOW_ENCODED_SLASH=true&lt;/em&gt; dans &lt;strong&gt;catalina.properties&lt;/strong&gt;, j’avais des problèmes pour ouvrir les pages avec des / dans les noms de pages.&lt;/p&gt;
&lt;p&gt;J’en ai profité pour essayer de déplacer l’application du paramètres et l’intégrer au niveau du setenv.sh avec la variable d’environnement CATALINA_OPTS. Ca n’a pas corrigé le problème (situé à un autre niveau) mais a permis de simplifier le Dockerfile, ce qui est toujours bon à prendre.&lt;/p&gt;
&lt;p&gt;En réalité, la variable était bien prise en compte dans les deux cas. Je l’avais vérifié et cela marchait depuis le début. En réalité, j’ai un reverse proxy Apache (ProxyPass) qui lui aussi fout le boxon avec les « / » dans mes titres de pages de XWiki.&lt;/p&gt;
&lt;p&gt;La réponse suivante &lt;a class="link" href="http://stackoverflow.com/a/9933890" target="_blank" rel="noopener"
&gt;sur StackOverflow explique très bien ce qu’il se passe&lt;/a&gt;. Pour autant dans mon cas, impossible d’accéder à ces pages, quelque soit le paramètre essayé, dans le cas où le XWiki est derrière mon proxy Apache. Je peux y accéder sans, je vais donc devoir les renommer pour contourner le problème. De toute façon, ça ne me plait pas que ces pages aient un « / » dans leur URL ;-).&lt;/p&gt;</description></item></channel></rss>