<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>rigelk</title>
        <link>https://rigelk.frama.io/blog</link>
        <author>
            <name>Rigel Kent</name>
            <email>sendmemail@rigelk.eu</email>
        </author>
        <description>Opinions, projects and reviews from rigelk</description>
        <generator uri="https://www.getzola.org/">Zola</generator>
        <language>en</language>
        <atom:link href="https://rigelk.frama.io/blog/atom.xml" rel="self" type="application/rss+xml"/>
        <lastBuildDate>Fri, 08 Aug 2025 00:00:00 +0000</lastBuildDate>
        
            <item>
                <title>Desktop de voyage</title>
                <pubDate>Fri, 08 Aug 2025 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/desktop-de-voyage/</link>
                <guid>https://rigelk.frama.io/blog/blog/desktop-de-voyage/</guid>
                <description>&lt;p&gt;Qui n’a pas rêvé d’avoir un ordinateur puissant capable de le suivre ? Bienvenue dans les années 80, avec les premiers laptops Compaq ! Dans un futur pas si lointain, les laptops sont partout. Ils sont presque glamour. Mais qui cherche un tant soit peu de puissance trouvera surtout des prix aux sommes bien rondelettes. Après 3 laptops sympathiques mais poussifs sur leurs dernières années, me revoilà à envisager l’achat d’un équipement que je peux balader. Pour voir le cycle se répéter ?&lt;&#x2F;p&gt;
&lt;p&gt;Force est de constater, mon ordinateur de bureau n’est pas plus jeune et pourtant, ses performances résistent bien mieux au temps qui passe. Sa batterie ne s’use pas. Son alimentation ne se débranche pas spontanément. Sa carte réseau continue d’être supportée. Je ne m’arrache pas les cheveux sur son bluetooth, ou son support hasardeux d’un dock plutôt qu’un autre. Quand on sait l’usage que j’ai de mes laptops en mobilité, c’est à dire assez rarement …eh bien il me faut peut-être plus un ordinateur de bureau transportable matin et soir entre chez moi et le travail.&lt;&#x2F;p&gt;
&lt;p&gt;Faisons l’inventaire. Pas de batterie. L’écran et le clavier seront externes et déjà sur place (bureau, domicile). Doit passer dans un sac à dos, voire mieux, un sac de vélo léger. Le poids est donc un critère mais le volume passe d’abord. Dans tous les cas, il faut préciser un truc : je n’ai pas besoin de GPU. Mon travail ne le requiert pas, et de toute façon j’ai déjà un GPU à la maison sur un serveur que je peux demander à distance au besoin.&lt;&#x2F;p&gt;
&lt;p&gt;Avec ça, une rapide recherche amène à lister les fameux NUC et formats micro.&lt;&#x2F;p&gt;
&lt;p&gt;Malheureusement, si ceux-ci restent moins chers à performance égale à un laptop, ils restent plus chers que des plateformes classiques. Sans parler du fait que beaucoup utilisent des processeurs dans leurs versions mobile (donc rebelotte la performance !), et que leur conception n’est pas modulaire ni ne prête à l’upgrade. Et de toute façon j’ai une carte-mère en mini-ITX qui traîne ! 😆&lt;&#x2F;p&gt;
&lt;h2 id=&quot;plateforme&quot;&gt;Plateforme&lt;a class=&quot;zola-anchor&quot; href=&quot;#plateforme&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Petit point d’étape. Le mini-ITX a recycler, c’est bien. Mais est-ce optimal sur le long terme ? Le but de toute cette configuration est d’optimiser recyclage &lt;em&gt;et&lt;&#x2F;em&gt; capacité à upgrader à moindre coût, après tout. Un modèle assez ancien en AM4 mais que l’on &lt;del&gt;peut&lt;&#x2F;del&gt; doit rafraîchir avec un nouveau processeur possédant un chipset graphique, comme le Ryzen 7 5700G. Cela pose donc plusieurs questions :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;y a-t-il des processeurs plus puissants ?
&lt;blockquote&gt;
&lt;p&gt;Oui mais pas avec iGPU en AM4&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;y a-t-il des générations plus modernes de sockets en mini-ITX ?
&lt;blockquote&gt;
&lt;p&gt;Oui, AM5&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;ces générations auront-elles encore des APU&#x2F;iGPU ?
&lt;blockquote&gt;
&lt;p&gt;Oui, le 8500G, le 8700G, ou n’importe quel 9xxx&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Globalement, on peut regarder la génération Zen 5 de CPU 9xxx chez AMD pour se rassurer : on trouvera bien des AM5 avec des APUs certes moins puissants (mais je ne cherche qu’à utiliser des moniteurs, pas à jouer…) mais des CPUs bien plus puissants, tout en restant potentiellement dans un TDP contenu. Par exemple le 9600X se trouve à des prix équivalents au 8700G, mais est à la fois plus rapide de 10% et bien moins efficace en iGPU. Tout dépend de si vous voulez faire tourner de petits jeux ou vous concentrer exclusivement sur la performance bureautique (mon cas).&lt;&#x2F;p&gt;
&lt;p&gt;Et Intel dans tout ça ? On a bien les versions K de leurs CPUs, comme le 14600k ou plus récemment le U7 245K. Mais ceux-ci ont un TDP nominal de 125W, trop élevé. Et cela, même si cette génération Core Ultra (Arrow Lake) se repose sur leur génération Lunar Lake optimisée pour laptops ! Il existe bien des Core Ultra 5, 7 et 9 déclinés avec des TDP de 35W (version éco T) et 65W, mais ils n’ont alors pas d’iGPU. Il reste possible de brider la consommation d’un processeur K, chose que l’on explore plus loin lorsqu’on évalue les solutions d’alimentations contenue. Mais en gros : passez votre chemin pour cette génération d’Intel. Et peut-être même la suivante à en croire leur résultats…&lt;&#x2F;p&gt;
&lt;h2 id=&quot;boitier&quot;&gt;Boîtier&lt;a class=&quot;zola-anchor&quot; href=&quot;#boitier&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;On reste donc dans le mini-ITX, avec pour objectif de réutiliser une B550M-ITX&#x2F;ac de Asrock. Notez que d’autres cartes-mères permettent l’emploi de boîtiers de plus faible épaisseur encore, comme le standard Thin mini-ITX très bas profil, ou le standard propre à ASRock qui fait l’impasse sur le port PCIe : DeskMini. Aucune idée de si ces plateformes seront encore là dans 5-10 ans cela dit. Alors que dans quelques &lt;del&gt;mois&lt;&#x2F;del&gt; années quand j’aurais envie de mettre à jour ma configuration, il y aura semble-t-il encore plein de mini-ITX.&lt;&#x2F;p&gt;
&lt;p&gt;Tous les boîtiers que j’ai séléctionnés font l’impasse sur une alimentation intégrée. Ils ont donc besoin d’un pico psu pour transformer du 12&#x2F;20V en toutes les tensions nécessaires à la carte, mais aussi d’un bloc secteur semblable à celui d’un laptop. Certains trouvent ça moche, moi je vois l’économie de volume. J’y reviens plus loin en parlant des potentiels effets de mutualisation.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;i.imgur.com&#x2F;ornbx0G.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ ce n’est qu’une liste non-exhaustive que j’ai réduite à mes choix mais surtout à mes goûts. Une liste plus exhaustive peut se trouver sur https:&#x2F;&#x2F;caseend.com&#x2F;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;En gros en dessous de 20L, les alimentations passent du standard ATX à SFX, souvent plus cher. En dessous de 15L, les GPU sont souvent très contraints en taille. N’espérez pas mettre plus de 250mm de longueur… En dessous de 10L, les alims passent sur des formats particuliers, souvent en GaN. En dessous de 4L oubliez le GPU sauf cas extrêmes, et l’alimentation requiert même un bloc externe en dessous de 3L. Bref, des contraintes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-9l-makerunit-210-x-210-x-66mm&quot;&gt;2.9L Makerunit - 210 x 210 x 66mm&lt;a class=&quot;zola-anchor&quot; href=&quot;#2-9l-makerunit-210-x-210-x-66mm&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;media.printables.com&#x2F;media&#x2F;prints&#x2F;496755&#x2F;images&#x2F;4044480_99470e34-6471-42df-8125-7c7535d6a5d0&#x2F;thumbs&#x2F;inside&#x2F;1280x960&#x2F;jpg&#x2F;dsc00889.webp&quot; alt=&quot;3D-printed case&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Boîte de petit volume (2.9L) à imprimer soi-même &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.printables.com&#x2F;model&#x2F;496755-mini-itx-pc-case&quot;&gt;par Makerunit sur printables&lt;&#x2F;a&gt; en PLA (480g de filament requis ~10€) :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;besoin d’un ventirad de 46mm max (voir ci-après)&lt;&#x2F;li&gt;
&lt;li&gt;besoin d’un pico psu + bloc externe (voir ci-après)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Peut être modifié pour attacher un SSD 2.5“ au boîtier. Question température on est clairement pas sur l’option la plus efficace.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-1l-custom-mod-187-x-190-x-60mm&quot;&gt;2.1L Custom-mod - 187 x 190 x 60mm&lt;a class=&quot;zola-anchor&quot; href=&quot;#2-1l-custom-mod-187-x-190-x-60mm&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    
    
    
      &lt;source srcset=&quot;https:&#x2F;&#x2F;static.wixstatic.com&#x2F;media&#x2F;5bcca1_9d81fcc3a7bf4047a4668f4e97b1a495~mv2.jpg&#x2F;v1&#x2F;fill&#x2F;w_500,h_500,al_c,q_80,usm_0.66_1.00_0.01,enc_avif,quality_auto&#x2F;5bcca1_9d81fcc3a7bf4047a4668f4e97b1a495~mv2.jpg.jpg&quot; type=&quot;image&#x2F;jpeg&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;https:&#x2F;&#x2F;static.wixstatic.com&#x2F;media&#x2F;5bcca1_9d81fcc3a7bf4047a4668f4e97b1a495~mv2.jpg&#x2F;v1&#x2F;fill&#x2F;w_500,h_500,al_c,q_80,usm_0.66_1.00_0.01,enc_avif,quality_auto&#x2F;5bcca1_9d81fcc3a7bf4047a4668f4e97b1a495~mv2.jpg.jpg&quot; style=&quot;width: 60%&quot;&#x2F;&gt;
    
    
  &lt;&#x2F;picture&gt;

  
  &lt;figcaption class=&quot;f7 black-40 tc&quot;&gt;Case SL1 2.1L rev3 de custom-mod&lt;&#x2F;figcaption&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;Boîte de petit volume (2.1L) custom-mod &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.custom-mod.com&#x2F;en&#x2F;stranica-tovara&#x2F;sl1?currency=EUR&quot;&gt;SL1 2.1L rev3&lt;&#x2F;a&gt; (100€ fdpin) en aluminium (0,4kg) :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;besoin d’un ventirad de 43mm max&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#cooler_height&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;li&gt;
&lt;li&gt;besoin d’un pico psu + bloc externe (voir ci-après)&lt;&#x2F;li&gt;
&lt;li&gt;besoin de barrettes de RAM ne dépassant pas 48mm (les miennes font tout juste 34mm)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;L’option la plus légère. Capable de mettre un SSD 2.5“ attaché au boîtier.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-5l-mini-box-192-x-210-x-62mm&quot;&gt;2.5L Mini-box - 192 x 210 x 62mm&lt;a class=&quot;zola-anchor&quot; href=&quot;#2-5l-mini-box-192-x-210-x-62mm&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    
    
    
    
      &lt;source srcset=&quot;https:&#x2F;&#x2F;resources.mini-box.com&#x2F;online&#x2F;ENC-M350&#x2F;moreimages&#x2F;M350-multiple-bracket-options.gif&quot; type=&quot;image&#x2F;gif&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred &#x27;: !open }&quot; src=&quot;https:&#x2F;&#x2F;resources.mini-box.com&#x2F;online&#x2F;ENC-M350&#x2F;moreimages&#x2F;M350-multiple-bracket-options.gif&quot; style=&quot;width: 60%&quot;&#x2F;&gt;
    
  &lt;&#x2F;picture&gt;

  
  &lt;figcaption class=&quot;f7 black-40 tc&quot;&gt;Case 2.5L Mini-box&lt;&#x2F;figcaption&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;Boîte en acier (&lt;strong&gt;1.36 kg&lt;&#x2F;strong&gt;) trouvable pour ~50€ :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;besoin d’un ventirad low profile (à définir)&lt;&#x2F;li&gt;
&lt;li&gt;besoin d’un pico psu + bloc externe (voir ci-après)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Capable de mettre jusqu’à deux SSD 2.5“ attachés au boîtier.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;cooler_height&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;Installer un SSD 2.5“ sur le couvercle du boîtier réduit la hauteur admissible du ventirad&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;3-1l-j-hack-190-x-250-5-x-66mm&quot;&gt;3.1L J-Hack - 190 x 250.5 x 66mm&lt;a class=&quot;zola-anchor&quot; href=&quot;#3-1l-j-hack-190-x-250-5-x-66mm&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    
    
    
      &lt;source srcset=&quot;https:&#x2F;&#x2F;j-hackcompany.com&#x2F;wp-content&#x2F;uploads&#x2F;2020&#x2F;01&#x2F;Pure-Mk2-4-600x400.jpg&quot; type=&quot;image&#x2F;jpeg&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;https:&#x2F;&#x2F;j-hackcompany.com&#x2F;wp-content&#x2F;uploads&#x2F;2020&#x2F;01&#x2F;Pure-Mk2-4-600x400.jpg&quot; style=&quot;width: 80%&quot;&#x2F;&gt;
    
    
  &lt;&#x2F;picture&gt;

  
  &lt;figcaption class=&quot;f7 black-40 tc&quot;&gt;Case 3.1L J-Hack&lt;&#x2F;figcaption&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;La &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;j-hackcompany.com&#x2F;?product=j-hack-pure-mk2&quot;&gt;J-HACK Pure Mk2&lt;&#x2F;a&gt; permet même d’ajouter un GPU. Compter 130€ fdpin vu que ça vient des US. Custom-mod fait des boîtes similaires (239 x 207 x 60 mm pour la &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.custom-mod.com&#x2F;en&#x2F;model-sl3m&quot;&gt;SL3m 2.9L&lt;&#x2F;a&gt;), dispo pour 100€ ou au même prix avec des couleurs au choix…&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Il n’y a pas de mauvaise option, mais clairement si je veux rester léger dans mes déplacements, autant éviter les boîtiers trop lourds …dommage, j’aimais bien le prix de l’option Mini-box 😬&lt;&#x2F;p&gt;
&lt;p&gt;Avec des volumes aussi contraints, tous les boîtiers requièrent une alimentation sur bloc externe. Un simple module interne, appelé pcio PSU, fait le découpage final des tensions.&lt;&#x2F;p&gt;
&lt;p&gt;Mais avant de parler des pico PSUs, il faut d’abord parler de la puissance du bouzin. On a prévu un 5700G plus haut, qui même si son enveloppe TDP n’est pas sensée dépasser 65W en théorie, peut se permettre 1,35x cette valeur lors d’excursions de moins de 300ms. C’est peu mais c’est suffisant pour déstabiliser plus d’un chargeur, et bien sûr, dépasser les petit pico PSUs de 90W que l’on peut trouver si facilement en ligne. Il ne faut en effet pas oublier que la carte-mère et les périphériques branchés sirotent eux-aussi le jus d’alim !&lt;&#x2F;p&gt;
&lt;h2 id=&quot;alimentation&quot;&gt;Alimentation&lt;a class=&quot;zola-anchor&quot; href=&quot;#alimentation&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Pas de PSU dans le boîtier = moins de chaleur à dissiper, mais aussi un bloc secteur à se trimballer ! Sauf si… on mutualise ça avec un bloc secteur pour téléphone. Mais si, vous savez, ces blocs de charge rapide, si gros mais si pratiques. Ils envoient pas mal de puissance dernièrement, pour des recharges en 30min (!) top chrono. C’est souvent grace à des standards qu’ils peuvent fonctionner. Voyons voir s’ils sont assez puissants.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;standards-de-charge-usb-type-c&quot;&gt;Standards de charge USB Type C&lt;a class=&quot;zola-anchor&quot; href=&quot;#standards-de-charge-usb-type-c&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;On a essentiellement QuickCharge de Qualcomm et Power Delivery de l’USB Promoters Group. Ils ont connu plusieurs versions.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;QuickCharge 1.0 allows up to 6V, &lt;strong&gt;up to 2amps&lt;&#x2F;strong&gt;
QuickCharge 2.0 allows 5v, 9v, 12v, and 20v, &lt;strong&gt;up to 3amps&lt;&#x2F;strong&gt;
QuickCharge 3.0 allows 3.6v to 22v, &lt;strong&gt;up to 4,6amps&lt;&#x2F;strong&gt;
QuickCharge 4.0 becomes compatible with USB Power Delivery, &lt;strong&gt;up to 5 amps&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Niveau comptibilité entre standards et téléphones, c’est pas toujours ça, surtout depuis 2015&#x2F;2016 où pas mal de variantes de marques ont émergé, et restent encore très utilisées:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Compatible with&#x2F;based on QC:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;TurboPower (Motorola)&lt;&#x2F;li&gt;
&lt;li&gt;Mi Fast Charging (Xiaomi &#x2F; Redmi)&lt;&#x2F;li&gt;
&lt;li&gt;Adaptive Fast Charging (Samsung)&lt;&#x2F;li&gt;
&lt;li&gt;BoostMaster (Asus)&lt;&#x2F;li&gt;
&lt;li&gt;Dual-Engine Fast Charging (Vivo)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Proprietary:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;VOOC (Oppo)&lt;&#x2F;li&gt;
&lt;li&gt;SuperCharge (Huawei) &amp;lt;– c’est celui de mon Poco X4 Pro 5G 😒&lt;&#x2F;li&gt;
&lt;li&gt;Dash Charge (OnePlus)&lt;&#x2F;li&gt;
&lt;li&gt;Pump Express (MediaTek)&lt;&#x2F;li&gt;
&lt;li&gt;Super FlashCharge (Vivo)&lt;&#x2F;li&gt;
&lt;li&gt;Dart Charge (Realme)&lt;&#x2F;li&gt;
&lt;li&gt;XCHARGE (Infinix)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Il y a une &lt;strong&gt;limitation du standard USB à 5 amps&lt;&#x2F;strong&gt; mais pas de voltage limite. Or les CPUs, même spécifiés à 65W max de TDP, ont tendance à faire des excursions à 1,35x le TDP (35W pour le reste du système + 65 à 65x1,35~=90W) donc 125W. La seule manière de délivrer plus de 100W via USB Type-C est donc d’aller au-delà des 20V, que ce soit en PD ou QC :&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;USB Power Delivery since rev. 1.0 can only deliver &lt;strong&gt;60W at 12V&lt;&#x2F;strong&gt;
USB Power Delivery since rev. 1.0 can only deliver &lt;strong&gt;60W-100W at 20V&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;In May 2021, the USB Promoter Group launched revision 3.1 of the PD specification. Revision 3.1 adds Extended Power Range (EPR) mode which allows higher voltages of 28, 36, and 48V, providing &lt;strong&gt;up to 240W of power (48V at 5A)&lt;&#x2F;strong&gt; &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;USB_hardware#USB_Power_Delivery&quot;&gt;source&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Quick Charge 5 can deliver &lt;strong&gt;more than 100 watts of power&lt;&#x2F;strong&gt; in the same fashion = only through a higher voltage&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Un USB PD à 28V à 5A fournit 140W, suffisants pour notre configuration un peu limite à 20V&#x2F;5A&#x2F;100W. Reste à négocier avec le chargeur ! Mais quel chargeur au juste fournit cette puissance ? Voir l’exemple de l’excellent et performant &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=w10htntCKow&quot;&gt;Framework 180W (sur YouTube)&lt;&#x2F;a&gt; qui fait bien du 28 et 36V ! Compter 100€ quand même.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;distributeur-dc-dc&quot;&gt;Distributeur DC-DC&lt;a class=&quot;zola-anchor&quot; href=&quot;#distributeur-dc-dc&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Communément appelée « Pico PSU » (attention dans vos recherches, PicoPSU est une marque), il s’agit d’une petite carte qui se trouve à l’intérieur de votre système et qui ressemble souvent à un circuit imprimé rectangulaire sur lequel se trouvent des composants électroniques permettant d’obtenir sur le principe d’alimentation à découpage les différentes tensions requises par votre système.&lt;&#x2F;p&gt;
&lt;p&gt;La tâche du distributeur DC-DC est de diviser le courant continu fourni par l’adaptateur en différentes tensions requises par votre système.  Ils ont souvent plusieurs câbles différents avec une variété de connecteurs, un exemple peut être vu ci-dessous :&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;lazer3d.com&#x2F;wp-content&#x2F;uploads&#x2F;2023&#x2F;10&#x2F;Realan-150W-12V-DC-Power-Supply-1.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;On trouve 2 types de PSU DC-DC : Direct Plug et monté sur chassis. Le dernier nécessite plus de place à côté de la carte-mère, on l’évitera donc au possible. Mais il permet de gérer de plus grandes puissances (&amp;gt;200W), parfait pour des GPUs.&lt;&#x2F;p&gt;
&lt;p&gt;Partant sur un modèle de PSU de petite taille alimenté par un bloc secteur finissant d’une manière ou d’une autre, on a un large choix d’alimentations produisant du 12V ou du 19V pour notre Desktop de voyage:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;fr.aliexpress.com&#x2F;item&#x2F;1005003830437385.html?spm=a2g0o.detail.pcDetailTopMoreOtherSeller.1.7efdd6HJd6HJsk&amp;amp;gps-id=pcDetailTopMoreOtherSeller&amp;amp;scm=1007.40050.354490.0&amp;amp;scm_id=1007.40050.354490.0&amp;amp;scm-url=1007.40050.354490.0&amp;amp;pvid=eb881fbf-d3c6-4c16-ab62-6905ac003620&amp;amp;_t=gps-id:pcDetailTopMoreOtherSeller,scm-url:1007.40050.354490.0,pvid:eb881fbf-d3c6-4c16-ab62-6905ac003620,tpp_buckets:668%232846%238109%231935&amp;amp;pdp_ext_f=%7B%22order%22%3A%2222%22%2C%22eval%22%3A%221%22%2C%22sceneId%22%3A%2230050%22%7D&amp;amp;pdp_npi=6%40dis%21EUR%2123.99%2123.99%21%21%2127.11%2127.11%21%40211b816617545026906144826ef278%2112000027294090095%21rec%21FR%21752714805%21XZ%211%210%21&amp;amp;utparam-url=scene%3ApcDetailTopMoreOtherSeller%7Cquery_from%3A&quot;&gt;DB1915A&lt;&#x2F;a&gt; (input 16-24V, 200W) ~23€
&lt;blockquote&gt;
&lt;p&gt;8V amplitude
pas moyen de jouer avec USB PD&#x2F;QC&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;resources.mini-box.com&#x2F;online&#x2F;PWR-PICOPSU-120-WI-25V&#x2F;PWR-PICOPSU-120-WI-25V-manual.pdf&quot;&gt;picoPSU-120 WI 25V&lt;&#x2F;a&gt; (input 12-25V, 120W) ~50€
&lt;blockquote&gt;
&lt;p&gt; &amp;gt;94% Efficiency, 13V amplitude
un peu limite niveau puissance cible (125W en excursion)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;hdplex.com&#x2F;hdplex-200w-dc-atx-power-supply-12v-48v-wide-range-voltage-input.html&quot;&gt;HDPLEX 200W DC-ATX Direct Plug&lt;&#x2F;a&gt; (input 12-48V, 200W) ~80€&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#hdplex&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;
&lt;blockquote&gt;
&lt;p&gt; &amp;gt;94% Efficiency, 36V amplitude (!), 220W Peak
 fourni avec un Φ7.4x5.0mm femelle pour l’input du PC&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;On l’a vu, plus l’entrée supportée est élevée, plus on pourra jouer avec le standard USB PD&#x2F;QC en négociant avec un voltage plus élevé.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;hdplex&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;quasiment tout le temps hors stock ⚠️ je les ai directement contactés par mail et ils ont du stock en EU à ce prix ! 😃&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;relier-les-deux&quot;&gt;Relier les deux&lt;a class=&quot;zola-anchor&quot; href=&quot;#relier-les-deux&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;On distingue l’USB Type C, qui possède une puce E-Mark pour bien négocier la charge, des autres connecteurs plus classiques. Parfois les deux se retrouvent ensemble dans un adaptateur :&lt;&#x2F;p&gt;
&lt;h4 id=&quot;avec-negociation&quot;&gt;Avec négociation&lt;a class=&quot;zola-anchor&quot; href=&quot;#avec-negociation&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;Power Delivery Switch
&lt;blockquote&gt;
&lt;p&gt;What is PD Switch? Well, it’s a cable that forces the AC adapter to deliver 20v (or any other voltage) at all times. You can buy on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;fr.aliexpress.com&#x2F;item&#x2F;1005004980363165.html&quot;&gt;AliExpress for like $10&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;sans-negociation&quot;&gt;Sans négociation&lt;a class=&quot;zola-anchor&quot; href=&quot;#sans-negociation&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Pas de négociation de charge mais ça fournit en général le maximum, sans logique intermédiaire. Les tailles standard les plus courantes pour les prises d’alimentation DC sont 2,1 mm et 2,5 mm, en référence au diamètre intérieur du connecteur. Le diamètre extérieur du connecteur varie généralement entre 5,5 mm et 6,5 mm, selon la conception spécifique et le fabricant.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;lazer3d.com&#x2F;wp-content&#x2F;uploads&#x2F;2023&#x2F;10&#x2F;DC-DC-Power-Jack-Connectors-Male-and-Female.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Coax Φ5.5x2.1mm (standard A slim)&lt;&#x2F;li&gt;
&lt;li&gt;Coax Φ5.5x2.5mm (standard A)&lt;&#x2F;li&gt;
&lt;li&gt;Coax Φ4.5x3.0mm (Dell slim)&lt;&#x2F;li&gt;
&lt;li&gt;Coax Φ7.4x5.0mm (Dell standard)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Barrel jacks&#x2F;Coax connectors are typically only rated for about 11A max
:thinking_face: 11A⎓12V is only 132W
👍 11A⎓19V is 209W&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;solutions&quot;&gt;Solutions&lt;a class=&quot;zola-anchor&quot; href=&quot;#solutions&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Ce n’est pas parce que ce serait bien de mutualiser un chargeur en USB Type C qu’on ne peut pas fonctionner avec un chargeur plus facile à trouver en coaxial. On a ainsi accès à un large panel de bloc alims de laptops, et surtout un large marché de l’occasion. Parfait pour équiper un bureau si on ne veut pas &lt;em&gt;toujours&lt;&#x2F;em&gt; se trimballer un chargeur, même mutualisé. Les “solutions” sont donc en fait des réponses à un problème que je me suis imposé tout seul.&lt;&#x2F;p&gt;
&lt;p&gt;Peu importe la solution choisie, le système peut aisément être alimenté avec un bloc alim de laptop en coaxial, il faut juste que celui-ci soit assez puissant.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;1-utiliser-un-voltage-superieur-28v-pour-atteindre-140w-en-qc-5-0-pd-2-0&quot;&gt;1. utiliser un voltage supérieur (28V) pour atteindre 140W en QC 5.0&#x2F;PD 2.0&lt;a class=&quot;zola-anchor&quot; href=&quot;#1-utiliser-un-voltage-superieur-28v-pour-atteindre-140w-en-qc-5-0-pd-2-0&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Another way to approach this, is to buy 12v picopsu (there are a lot more variants available for 12v) and prepare that voltage by using DC buck converter (20v to 12v) between gan charger and picopsu. That way you will loose around 10%watts available on conversion, but then you can use 28v charger (pd.3.1 140w) instead and actually go beyond 100w limit. (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;sffpc&#x2F;comments&#x2F;11ui82g&#x2F;comment&#x2F;ls8lw93&#x2F;&quot;&gt;source&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Suppose de se balader avec un convertisseur&#x2F;d’avoir une PSU dite “Wide Range” …mais permet théoriquement d’utiliser plus de chargeurs.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;2-utiliser-un-reglage-pour-limiter-la-puissance-tiree&quot;&gt;2. utiliser un réglage pour limiter la puissance tirée&lt;a class=&quot;zola-anchor&quot; href=&quot;#2-utiliser-un-reglage-pour-limiter-la-puissance-tiree&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Au prix d’une réduction de performance de 10% (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;sffpc&#x2F;comments&#x2F;1gdckxj&#x2F;comment&#x2F;lu0oo2v&#x2F;&quot;&gt;source&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;undervolt a bit. Downclock slightly and you’ll get most of the performance for a lower power draw.
As an example, consider the datapoint of -0.1375v: this drops the cinebench score from nearly 5000 down to 4000, and reduces total system power consumption from ~137w to ~110w.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Mais il semble qu’une manière plus intelligente que de sous-volter un CPU existe : le PPT (package power tracking), un réglage BIOS synthétique prenant en compte le couple V&#x2F;Hz et définissant des courbes à adopter pour garder une performance adéquate jusqu’à une limite en Watt. C’est par défaut défini à 88W pour les CPU à 65W de TDP, et 142W pour ceux à 105W de TDP. Le régler permet de réajuster l’ensemble des courbes du couple V&#x2F;Hz du CPU !&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Now consider the datapoint of setting PPT to 48W. This reduces cinebench down to the same ~4000 score, however now system power consumption is ~75w! - so we’re getting the same performance at 35w less system power.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Et pour Intel alors ? On peut prendre un U9 285K (125W) et le faire rentrer par un trou de souris ?&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;…both P-core and E-core frequency is reduced when TDP is crushed down to 65W, leaving a level of performance consistent with, for example, a Ryzen 5 7600X &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.club386.com&#x2F;heres-what-happens-when-you-run-an-intel-core-ultra-9-285k-at-65w&#x2F;&quot;&gt;source&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;La baisse de performance est intéressante sur le papier : un 7600X est 15% plus rapide qu’un 8700G. Mais un U9 285K coûte 2-3x plus cher qu’un 8700G… qui lui-même est 10% moins rapide qu’un 9600X possédant un iGPU moins puissant mais au prix équivalent.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;3-utiliser-un-chargeur-possedant-usb-c-qc-pd-et-coaxial&quot;&gt;3. utiliser un chargeur possédant USB C QC&#x2F;PD et coaxial&lt;a class=&quot;zola-anchor&quot; href=&quot;#3-utiliser-un-chargeur-possedant-usb-c-qc-pd-et-coaxial&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Partant du principe que les chargeurs compatibles sont de toute façon assez rares, et que l’on va devoir en acheter un bien spécifique, autant voir si les chargeurs ne supportent pas d’autres connectiques que le “simple” USB Type-C avec QC&#x2F;PD.&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    
    
    
      &lt;source srcset=&quot;https:&#x2F;&#x2F;slimq.life&#x2F;cdn&#x2F;shop&#x2F;files&#x2F;F150-output.jpg&quot; type=&quot;image&#x2F;jpeg&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;https:&#x2F;&#x2F;slimq.life&#x2F;cdn&#x2F;shop&#x2F;files&#x2F;F150-output.jpg&quot; style=&quot;width: 60%&quot;&#x2F;&gt;
    
    
  &lt;&#x2F;picture&gt;

  
  &lt;figcaption class=&quot;f7 black-40 tc&quot;&gt;Chargeur SlimQ F150&lt;&#x2F;figcaption&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;Un example assez unique est le chargeur &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;slimq.life&#x2F;products&#x2F;150w-usb-c-gan-charger-for-universal&quot;&gt;SlimQ F150&lt;&#x2F;a&gt; (~70€) qui délivre en 20V 150W sur un port DC coaxial Φ5.5x2.5mm assez commun, tout en ayant des ports pour téléphone. Il priorise bien la puissance sur le port DC, et module l’intensité sur les autres ports dans la mesure où l’ensemble ne dépasse pas les 150W nominaux. Des adaptateurs sont disponibles, notamment en Φ7.4x5.0mm.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;synthese-des-solutions&quot;&gt;Synthèse des solutions&lt;a class=&quot;zola-anchor&quot; href=&quot;#synthese-des-solutions&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;cote-secteur&quot;&gt;Côté secteur&lt;a class=&quot;zola-anchor&quot; href=&quot;#cote-secteur&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Le plus simple est de prendre la solution 3 + un adaptateur coaxial male&#x2F;Type C femelle avec une puce E-mark (voir connecteurs ci-avant). Ce dernier permet éventuellement de s’adapter à des situations où le chargeur n’est pas présent, mais le reste du temps la solution 3 fournit un barrel jack suffisant.&lt;&#x2F;p&gt;
&lt;p&gt;D’autant que le barrel jack permet de choisir d’autres chargeurs, plus abordables et standards, en 20V, lorsque la mutualisation avec le chargeur de téléphone n’est pas nécessaire (ex: à la maison).&lt;&#x2F;p&gt;
&lt;h4 id=&quot;cote-psu&quot;&gt;Côté psu&lt;a class=&quot;zola-anchor&quot; href=&quot;#cote-psu&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;L’HDPLEX est le seul&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#seul_psu&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; PSU permettant un large gamme d’entrées (input 12-48V) au-delà de 24V, et l’acheter ouvre la possibilité d’alimentations à la fois plus simples (12V) et plus fortes en type-C (PD 28V&#x2F;5A).&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;seul_psu&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;3&lt;&#x2F;sup&gt;
&lt;p&gt;il y a bien des modèles alternatifs comme ceux de G-Uniq, mais ils sont de diffusion encore plus confidentielle.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;ventirads&quot;&gt;Ventirads&lt;a class=&quot;zola-anchor&quot; href=&quot;#ventirads&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Niveau ventilateurs, on est contraints par la hauteur du boîtier qui, à 6cm de haut, ne laisse plus grand chose pour notre couple ventilateur&#x2F;radiateur. Les petits modèles suivants sont d’ailleurs souvent limités dans leur capacité de refroidissement (logique) et indiquent en général ne supporter que des CPU dont le TDP ne dépasse pas 65W.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jonsbo.com&#x2F;en&#x2F;products&#x2F;HP400.html&quot;&gt;Jonsbo HX400&lt;&#x2F;a&gt; (~22€) 36mm de haut&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;sffpc&#x2F;comments&#x2F;1m4zrzy&#x2F;metalfish_dh380_v4_just_2mm_away_from_being_a_x36&#x2F;&quot;&gt;Metalfish DH380&lt;&#x2F;a&gt; (~23€) 38mm de haut&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.fr&#x2F;Thermalright-AXP120-X67-Refroidisseur-ventilateur-1200000000&#x2F;dp&#x2F;B0BDXKZNK4?th=1&quot;&gt;Thermalright AXP90 X36&lt;&#x2F;a&gt; (~26€) 36mm de haut&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#axp90&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;noctua.at&#x2F;fr&#x2F;nh-l9a-am4&quot;&gt;Noctua L9a&lt;&#x2F;a&gt; (~49,90€) 37mm de haut&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;if you use the am4 backplate, the screws will make [the DH380 and AXP90 X36] taller so it will be better without the plate.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Out of L9a, axp90 x36, and dh380, the dh380 feels and looks the least quality.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;preview.redd.it&#x2F;37mm-coolers-tested-l9a-vs-axp90-x36-vs-hp-400s-for-velka-v0-oqxtqe31n0x91.jpg?width=3337&amp;amp;format=pjpg&amp;amp;auto=webp&amp;amp;s=7d904e539918b63de9925ca777a000cb5eaf7e3e&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Noctua NH-L9a (382 g), Thermalright AXP90-X36 (204 g), JONSBO HP400S (158 g)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;preview.redd.it&#x2F;37mm-coolers-tested-l9a-vs-axp90-x36-vs-hp-400s-for-velka-v0-bhgrxr31n0x91.jpg?width=3711&amp;amp;format=pjpg&amp;amp;auto=webp&amp;amp;s=a7ab851be1ba0747d8ba65e0eb285892181df52e&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The results show that the Thermalright AXP90-X36 has a clear advantage with 1.76% higher scores and 1.74 °C lower temps on average compared to the Noctua NH-L9a. I also tested the AXP90-X36 with two 40x15mm exhaust fans at 40% speed mounted below the cooler (similar to this) and it yielded 2.57% higher scores and 2.10 °C lower temps on average compared to the NH-L9a. So despite being lighter and having less thermal mass than the NH-L9a, the AXP90-X36 performed better likely due to a combination of more heatpipes and optimal vertical fin orientation. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;sffpc&#x2F;comments&#x2F;yhsppo&#x2F;37mm_coolers_tested_l9a_vs_axp90x36_vs_hp400s_for&#x2F;&quot;&gt;source&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;[…] fin orientation affected the cooling performance more than number of heat pipes&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Les deux premières marques sont moins connues, les deux dernières ont bonne réputation. Vu la différence de prix et l’absence de processeur à forte enveloppe (version X à X3D), on peut partir sur l’AXP90 X36 sans risque, surtout vu sa meilleur orientation des dissipateurs à ailettes quand l’ordinateur est positionné à la verticale.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;axp90&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;4&lt;&#x2F;sup&gt;
&lt;p&gt;⚠️ il est possible de swap le ventilateur du AXP90 X36 pour ne garder que son radiateur et lui coller un A9x14 (que j’ai déja ! 😃)&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h1 id=&quot;total&quot;&gt;Total&lt;a class=&quot;zola-anchor&quot; href=&quot;#total&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h1&gt;
&lt;p&gt;Pour 300-400€, on peut aisément changer RAM, MB et CPU pour “rafraîchir” la configuration dans quelques années sans changer de spécifications par ailleurs. Et si on se trouve sur une génération de socket indéboulonnable comme AM4, on peut même espérer n’avoir que le CPU à changer, comme ici :&lt;&#x2F;p&gt;
&lt;table class=&quot;center collapse ba br2 b--black-10 pv2 ph3&quot;&gt;
  &lt;tbody&gt;
    &lt;tr class=&quot;striped--light-gray &quot;&gt;
      &lt;th class=&quot;pv2 ph3 tl f6 fw6 ttu&quot;&gt;Rôle&lt;&#x2F;th&gt;
      &lt;th class=&quot;tr f6 ttu fw6 pv2 ph3&quot;&gt;Référence&lt;&#x2F;th&gt;
      &lt;th class=&quot;tr f6 ttu fw6 pv2 ph3&quot;&gt;Prix&lt;&#x2F;th&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr class=&quot;striped--light-gray &quot;&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;boîtier alu&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;SL1 2.1L rev. 3&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;100€&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr class=&quot;striped--light-gray &quot;&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;cpu&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;R7 5700G&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;100€&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr class=&quot;striped--light-gray &quot;&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;pico psu&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;HDPLEX 200W DC-ATX&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;80€&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr class=&quot;striped--light-gray &quot;&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;bloc fixe&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;Dell 180W HA180PM180&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;30€&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr class=&quot;striped--light-gray &quot;&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;bloc mobile&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;SlimQ F150&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;71,90€&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr class=&quot;striped--light-gray &quot;&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;adaptateurs&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;divers&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;10€&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr class=&quot;striped--light-gray &quot;&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;ventirad&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;AXP90 X36&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;26€&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr class=&quot;striped--light-gray &quot;&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;TOTAL&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;417,90€&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
  &lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;À ce tarif, on peut à peine gratter des laptops équipés de processeurs en version mobile d’il y 3 générations …en occasion …et sans voie d’upgrade. À bon entendeur.&lt;&#x2F;p&gt;
</description>
                <content:encoded>&lt;p&gt;Qui n’a pas rêvé d’avoir un ordinateur puissant capable de le suivre ? Bienvenue dans les années 80, avec les premiers laptops Compaq ! Dans un futur pas si lointain, les laptops sont partout. Ils sont presque glamour. Mais qui cherche un tant soit peu de puissance trouvera surtout des prix aux sommes bien rondelettes. Après 3 laptops sympathiques mais poussifs sur leurs dernières années, me revoilà à envisager l’achat d’un équipement que je peux balader. Pour voir le cycle se répéter ?&lt;&#x2F;p&gt;
&lt;p&gt;Force est de constater, mon ordinateur de bureau n’est pas plus jeune et pourtant, ses performances résistent bien mieux au temps qui passe. Sa batterie ne s’use pas. Son alimentation ne se débranche pas spontanément. Sa carte réseau continue d’être supportée. Je ne m’arrache pas les cheveux sur son bluetooth, ou son support hasardeux d’un dock plutôt qu’un autre. Quand on sait l’usage que j’ai de mes laptops en mobilité, c’est à dire assez rarement …eh bien il me faut peut-être plus un ordinateur de bureau transportable matin et soir entre chez moi et le travail.&lt;&#x2F;p&gt;
&lt;p&gt;Faisons l’inventaire. Pas de batterie. L’écran et le clavier seront externes et déjà sur place (bureau, domicile). Doit passer dans un sac à dos, voire mieux, un sac de vélo léger. Le poids est donc un critère mais le volume passe d’abord. Dans tous les cas, il faut préciser un truc : je n’ai pas besoin de GPU. Mon travail ne le requiert pas, et de toute façon j’ai déjà un GPU à la maison sur un serveur que je peux demander à distance au besoin.&lt;&#x2F;p&gt;
&lt;p&gt;Avec ça, une rapide recherche amène à lister les fameux NUC et formats micro.&lt;&#x2F;p&gt;
&lt;p&gt;Malheureusement, si ceux-ci restent moins chers à performance égale à un laptop, ils restent plus chers que des plateformes classiques. Sans parler du fait que beaucoup utilisent des processeurs dans leurs versions mobile (donc rebelotte la performance !), et que leur conception n’est pas modulaire ni ne prête à l’upgrade. Et de toute façon j’ai une carte-mère en mini-ITX qui traîne ! 😆&lt;&#x2F;p&gt;
&lt;h2 id=&quot;plateforme&quot;&gt;Plateforme&lt;a class=&quot;zola-anchor&quot; href=&quot;#plateforme&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Petit point d’étape. Le mini-ITX a recycler, c’est bien. Mais est-ce optimal sur le long terme ? Le but de toute cette configuration est d’optimiser recyclage &lt;em&gt;et&lt;&#x2F;em&gt; capacité à upgrader à moindre coût, après tout. Un modèle assez ancien en AM4 mais que l’on &lt;del&gt;peut&lt;&#x2F;del&gt; doit rafraîchir avec un nouveau processeur possédant un chipset graphique, comme le Ryzen 7 5700G. Cela pose donc plusieurs questions :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;y a-t-il des processeurs plus puissants ?
&lt;blockquote&gt;
&lt;p&gt;Oui mais pas avec iGPU en AM4&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;y a-t-il des générations plus modernes de sockets en mini-ITX ?
&lt;blockquote&gt;
&lt;p&gt;Oui, AM5&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;ces générations auront-elles encore des APU&#x2F;iGPU ?
&lt;blockquote&gt;
&lt;p&gt;Oui, le 8500G, le 8700G, ou n’importe quel 9xxx&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Globalement, on peut regarder la génération Zen 5 de CPU 9xxx chez AMD pour se rassurer : on trouvera bien des AM5 avec des APUs certes moins puissants (mais je ne cherche qu’à utiliser des moniteurs, pas à jouer…) mais des CPUs bien plus puissants, tout en restant potentiellement dans un TDP contenu. Par exemple le 9600X se trouve à des prix équivalents au 8700G, mais est à la fois plus rapide de 10% et bien moins efficace en iGPU. Tout dépend de si vous voulez faire tourner de petits jeux ou vous concentrer exclusivement sur la performance bureautique (mon cas).&lt;&#x2F;p&gt;
&lt;p&gt;Et Intel dans tout ça ? On a bien les versions K de leurs CPUs, comme le 14600k ou plus récemment le U7 245K. Mais ceux-ci ont un TDP nominal de 125W, trop élevé. Et cela, même si cette génération Core Ultra (Arrow Lake) se repose sur leur génération Lunar Lake optimisée pour laptops ! Il existe bien des Core Ultra 5, 7 et 9 déclinés avec des TDP de 35W (version éco T) et 65W, mais ils n’ont alors pas d’iGPU. Il reste possible de brider la consommation d’un processeur K, chose que l’on explore plus loin lorsqu’on évalue les solutions d’alimentations contenue. Mais en gros : passez votre chemin pour cette génération d’Intel. Et peut-être même la suivante à en croire leur résultats…&lt;&#x2F;p&gt;
&lt;h2 id=&quot;boitier&quot;&gt;Boîtier&lt;a class=&quot;zola-anchor&quot; href=&quot;#boitier&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;On reste donc dans le mini-ITX, avec pour objectif de réutiliser une B550M-ITX&#x2F;ac de Asrock. Notez que d’autres cartes-mères permettent l’emploi de boîtiers de plus faible épaisseur encore, comme le standard Thin mini-ITX très bas profil, ou le standard propre à ASRock qui fait l’impasse sur le port PCIe : DeskMini. Aucune idée de si ces plateformes seront encore là dans 5-10 ans cela dit. Alors que dans quelques &lt;del&gt;mois&lt;&#x2F;del&gt; années quand j’aurais envie de mettre à jour ma configuration, il y aura semble-t-il encore plein de mini-ITX.&lt;&#x2F;p&gt;
&lt;p&gt;Tous les boîtiers que j’ai séléctionnés font l’impasse sur une alimentation intégrée. Ils ont donc besoin d’un pico psu pour transformer du 12&#x2F;20V en toutes les tensions nécessaires à la carte, mais aussi d’un bloc secteur semblable à celui d’un laptop. Certains trouvent ça moche, moi je vois l’économie de volume. J’y reviens plus loin en parlant des potentiels effets de mutualisation.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;i.imgur.com&#x2F;ornbx0G.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ ce n’est qu’une liste non-exhaustive que j’ai réduite à mes choix mais surtout à mes goûts. Une liste plus exhaustive peut se trouver sur https:&#x2F;&#x2F;caseend.com&#x2F;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;En gros en dessous de 20L, les alimentations passent du standard ATX à SFX, souvent plus cher. En dessous de 15L, les GPU sont souvent très contraints en taille. N’espérez pas mettre plus de 250mm de longueur… En dessous de 10L, les alims passent sur des formats particuliers, souvent en GaN. En dessous de 4L oubliez le GPU sauf cas extrêmes, et l’alimentation requiert même un bloc externe en dessous de 3L. Bref, des contraintes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-9l-makerunit-210-x-210-x-66mm&quot;&gt;2.9L Makerunit - 210 x 210 x 66mm&lt;a class=&quot;zola-anchor&quot; href=&quot;#2-9l-makerunit-210-x-210-x-66mm&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;media.printables.com&#x2F;media&#x2F;prints&#x2F;496755&#x2F;images&#x2F;4044480_99470e34-6471-42df-8125-7c7535d6a5d0&#x2F;thumbs&#x2F;inside&#x2F;1280x960&#x2F;jpg&#x2F;dsc00889.webp&quot; alt=&quot;3D-printed case&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Boîte de petit volume (2.9L) à imprimer soi-même &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.printables.com&#x2F;model&#x2F;496755-mini-itx-pc-case&quot;&gt;par Makerunit sur printables&lt;&#x2F;a&gt; en PLA (480g de filament requis ~10€) :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;besoin d’un ventirad de 46mm max (voir ci-après)&lt;&#x2F;li&gt;
&lt;li&gt;besoin d’un pico psu + bloc externe (voir ci-après)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Peut être modifié pour attacher un SSD 2.5“ au boîtier. Question température on est clairement pas sur l’option la plus efficace.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-1l-custom-mod-187-x-190-x-60mm&quot;&gt;2.1L Custom-mod - 187 x 190 x 60mm&lt;a class=&quot;zola-anchor&quot; href=&quot;#2-1l-custom-mod-187-x-190-x-60mm&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    
    
    
      &lt;source srcset=&quot;https:&#x2F;&#x2F;static.wixstatic.com&#x2F;media&#x2F;5bcca1_9d81fcc3a7bf4047a4668f4e97b1a495~mv2.jpg&#x2F;v1&#x2F;fill&#x2F;w_500,h_500,al_c,q_80,usm_0.66_1.00_0.01,enc_avif,quality_auto&#x2F;5bcca1_9d81fcc3a7bf4047a4668f4e97b1a495~mv2.jpg.jpg&quot; type=&quot;image&#x2F;jpeg&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;https:&#x2F;&#x2F;static.wixstatic.com&#x2F;media&#x2F;5bcca1_9d81fcc3a7bf4047a4668f4e97b1a495~mv2.jpg&#x2F;v1&#x2F;fill&#x2F;w_500,h_500,al_c,q_80,usm_0.66_1.00_0.01,enc_avif,quality_auto&#x2F;5bcca1_9d81fcc3a7bf4047a4668f4e97b1a495~mv2.jpg.jpg&quot; style=&quot;width: 60%&quot;&#x2F;&gt;
    
    
  &lt;&#x2F;picture&gt;

  
  &lt;figcaption class=&quot;f7 black-40 tc&quot;&gt;Case SL1 2.1L rev3 de custom-mod&lt;&#x2F;figcaption&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;Boîte de petit volume (2.1L) custom-mod &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.custom-mod.com&#x2F;en&#x2F;stranica-tovara&#x2F;sl1?currency=EUR&quot;&gt;SL1 2.1L rev3&lt;&#x2F;a&gt; (100€ fdpin) en aluminium (0,4kg) :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;besoin d’un ventirad de 43mm max&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#cooler_height&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;li&gt;
&lt;li&gt;besoin d’un pico psu + bloc externe (voir ci-après)&lt;&#x2F;li&gt;
&lt;li&gt;besoin de barrettes de RAM ne dépassant pas 48mm (les miennes font tout juste 34mm)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;L’option la plus légère. Capable de mettre un SSD 2.5“ attaché au boîtier.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-5l-mini-box-192-x-210-x-62mm&quot;&gt;2.5L Mini-box - 192 x 210 x 62mm&lt;a class=&quot;zola-anchor&quot; href=&quot;#2-5l-mini-box-192-x-210-x-62mm&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    
    
    
    
      &lt;source srcset=&quot;https:&#x2F;&#x2F;resources.mini-box.com&#x2F;online&#x2F;ENC-M350&#x2F;moreimages&#x2F;M350-multiple-bracket-options.gif&quot; type=&quot;image&#x2F;gif&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred &#x27;: !open }&quot; src=&quot;https:&#x2F;&#x2F;resources.mini-box.com&#x2F;online&#x2F;ENC-M350&#x2F;moreimages&#x2F;M350-multiple-bracket-options.gif&quot; style=&quot;width: 60%&quot;&#x2F;&gt;
    
  &lt;&#x2F;picture&gt;

  
  &lt;figcaption class=&quot;f7 black-40 tc&quot;&gt;Case 2.5L Mini-box&lt;&#x2F;figcaption&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;Boîte en acier (&lt;strong&gt;1.36 kg&lt;&#x2F;strong&gt;) trouvable pour ~50€ :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;besoin d’un ventirad low profile (à définir)&lt;&#x2F;li&gt;
&lt;li&gt;besoin d’un pico psu + bloc externe (voir ci-après)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Capable de mettre jusqu’à deux SSD 2.5“ attachés au boîtier.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;cooler_height&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;Installer un SSD 2.5“ sur le couvercle du boîtier réduit la hauteur admissible du ventirad&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;3-1l-j-hack-190-x-250-5-x-66mm&quot;&gt;3.1L J-Hack - 190 x 250.5 x 66mm&lt;a class=&quot;zola-anchor&quot; href=&quot;#3-1l-j-hack-190-x-250-5-x-66mm&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    
    
    
      &lt;source srcset=&quot;https:&#x2F;&#x2F;j-hackcompany.com&#x2F;wp-content&#x2F;uploads&#x2F;2020&#x2F;01&#x2F;Pure-Mk2-4-600x400.jpg&quot; type=&quot;image&#x2F;jpeg&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;https:&#x2F;&#x2F;j-hackcompany.com&#x2F;wp-content&#x2F;uploads&#x2F;2020&#x2F;01&#x2F;Pure-Mk2-4-600x400.jpg&quot; style=&quot;width: 80%&quot;&#x2F;&gt;
    
    
  &lt;&#x2F;picture&gt;

  
  &lt;figcaption class=&quot;f7 black-40 tc&quot;&gt;Case 3.1L J-Hack&lt;&#x2F;figcaption&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;La &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;j-hackcompany.com&#x2F;?product=j-hack-pure-mk2&quot;&gt;J-HACK Pure Mk2&lt;&#x2F;a&gt; permet même d’ajouter un GPU. Compter 130€ fdpin vu que ça vient des US. Custom-mod fait des boîtes similaires (239 x 207 x 60 mm pour la &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.custom-mod.com&#x2F;en&#x2F;model-sl3m&quot;&gt;SL3m 2.9L&lt;&#x2F;a&gt;), dispo pour 100€ ou au même prix avec des couleurs au choix…&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Il n’y a pas de mauvaise option, mais clairement si je veux rester léger dans mes déplacements, autant éviter les boîtiers trop lourds …dommage, j’aimais bien le prix de l’option Mini-box 😬&lt;&#x2F;p&gt;
&lt;p&gt;Avec des volumes aussi contraints, tous les boîtiers requièrent une alimentation sur bloc externe. Un simple module interne, appelé pcio PSU, fait le découpage final des tensions.&lt;&#x2F;p&gt;
&lt;p&gt;Mais avant de parler des pico PSUs, il faut d’abord parler de la puissance du bouzin. On a prévu un 5700G plus haut, qui même si son enveloppe TDP n’est pas sensée dépasser 65W en théorie, peut se permettre 1,35x cette valeur lors d’excursions de moins de 300ms. C’est peu mais c’est suffisant pour déstabiliser plus d’un chargeur, et bien sûr, dépasser les petit pico PSUs de 90W que l’on peut trouver si facilement en ligne. Il ne faut en effet pas oublier que la carte-mère et les périphériques branchés sirotent eux-aussi le jus d’alim !&lt;&#x2F;p&gt;
&lt;h2 id=&quot;alimentation&quot;&gt;Alimentation&lt;a class=&quot;zola-anchor&quot; href=&quot;#alimentation&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Pas de PSU dans le boîtier = moins de chaleur à dissiper, mais aussi un bloc secteur à se trimballer ! Sauf si… on mutualise ça avec un bloc secteur pour téléphone. Mais si, vous savez, ces blocs de charge rapide, si gros mais si pratiques. Ils envoient pas mal de puissance dernièrement, pour des recharges en 30min (!) top chrono. C’est souvent grace à des standards qu’ils peuvent fonctionner. Voyons voir s’ils sont assez puissants.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;standards-de-charge-usb-type-c&quot;&gt;Standards de charge USB Type C&lt;a class=&quot;zola-anchor&quot; href=&quot;#standards-de-charge-usb-type-c&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;On a essentiellement QuickCharge de Qualcomm et Power Delivery de l’USB Promoters Group. Ils ont connu plusieurs versions.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;QuickCharge 1.0 allows up to 6V, &lt;strong&gt;up to 2amps&lt;&#x2F;strong&gt;
QuickCharge 2.0 allows 5v, 9v, 12v, and 20v, &lt;strong&gt;up to 3amps&lt;&#x2F;strong&gt;
QuickCharge 3.0 allows 3.6v to 22v, &lt;strong&gt;up to 4,6amps&lt;&#x2F;strong&gt;
QuickCharge 4.0 becomes compatible with USB Power Delivery, &lt;strong&gt;up to 5 amps&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Niveau comptibilité entre standards et téléphones, c’est pas toujours ça, surtout depuis 2015&#x2F;2016 où pas mal de variantes de marques ont émergé, et restent encore très utilisées:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Compatible with&#x2F;based on QC:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;TurboPower (Motorola)&lt;&#x2F;li&gt;
&lt;li&gt;Mi Fast Charging (Xiaomi &#x2F; Redmi)&lt;&#x2F;li&gt;
&lt;li&gt;Adaptive Fast Charging (Samsung)&lt;&#x2F;li&gt;
&lt;li&gt;BoostMaster (Asus)&lt;&#x2F;li&gt;
&lt;li&gt;Dual-Engine Fast Charging (Vivo)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Proprietary:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;VOOC (Oppo)&lt;&#x2F;li&gt;
&lt;li&gt;SuperCharge (Huawei) &amp;lt;– c’est celui de mon Poco X4 Pro 5G 😒&lt;&#x2F;li&gt;
&lt;li&gt;Dash Charge (OnePlus)&lt;&#x2F;li&gt;
&lt;li&gt;Pump Express (MediaTek)&lt;&#x2F;li&gt;
&lt;li&gt;Super FlashCharge (Vivo)&lt;&#x2F;li&gt;
&lt;li&gt;Dart Charge (Realme)&lt;&#x2F;li&gt;
&lt;li&gt;XCHARGE (Infinix)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Il y a une &lt;strong&gt;limitation du standard USB à 5 amps&lt;&#x2F;strong&gt; mais pas de voltage limite. Or les CPUs, même spécifiés à 65W max de TDP, ont tendance à faire des excursions à 1,35x le TDP (35W pour le reste du système + 65 à 65x1,35~=90W) donc 125W. La seule manière de délivrer plus de 100W via USB Type-C est donc d’aller au-delà des 20V, que ce soit en PD ou QC :&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;USB Power Delivery since rev. 1.0 can only deliver &lt;strong&gt;60W at 12V&lt;&#x2F;strong&gt;
USB Power Delivery since rev. 1.0 can only deliver &lt;strong&gt;60W-100W at 20V&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;In May 2021, the USB Promoter Group launched revision 3.1 of the PD specification. Revision 3.1 adds Extended Power Range (EPR) mode which allows higher voltages of 28, 36, and 48V, providing &lt;strong&gt;up to 240W of power (48V at 5A)&lt;&#x2F;strong&gt; &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;USB_hardware#USB_Power_Delivery&quot;&gt;source&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Quick Charge 5 can deliver &lt;strong&gt;more than 100 watts of power&lt;&#x2F;strong&gt; in the same fashion = only through a higher voltage&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Un USB PD à 28V à 5A fournit 140W, suffisants pour notre configuration un peu limite à 20V&#x2F;5A&#x2F;100W. Reste à négocier avec le chargeur ! Mais quel chargeur au juste fournit cette puissance ? Voir l’exemple de l’excellent et performant &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=w10htntCKow&quot;&gt;Framework 180W (sur YouTube)&lt;&#x2F;a&gt; qui fait bien du 28 et 36V ! Compter 100€ quand même.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;distributeur-dc-dc&quot;&gt;Distributeur DC-DC&lt;a class=&quot;zola-anchor&quot; href=&quot;#distributeur-dc-dc&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Communément appelée « Pico PSU » (attention dans vos recherches, PicoPSU est une marque), il s’agit d’une petite carte qui se trouve à l’intérieur de votre système et qui ressemble souvent à un circuit imprimé rectangulaire sur lequel se trouvent des composants électroniques permettant d’obtenir sur le principe d’alimentation à découpage les différentes tensions requises par votre système.&lt;&#x2F;p&gt;
&lt;p&gt;La tâche du distributeur DC-DC est de diviser le courant continu fourni par l’adaptateur en différentes tensions requises par votre système.  Ils ont souvent plusieurs câbles différents avec une variété de connecteurs, un exemple peut être vu ci-dessous :&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;lazer3d.com&#x2F;wp-content&#x2F;uploads&#x2F;2023&#x2F;10&#x2F;Realan-150W-12V-DC-Power-Supply-1.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;On trouve 2 types de PSU DC-DC : Direct Plug et monté sur chassis. Le dernier nécessite plus de place à côté de la carte-mère, on l’évitera donc au possible. Mais il permet de gérer de plus grandes puissances (&amp;gt;200W), parfait pour des GPUs.&lt;&#x2F;p&gt;
&lt;p&gt;Partant sur un modèle de PSU de petite taille alimenté par un bloc secteur finissant d’une manière ou d’une autre, on a un large choix d’alimentations produisant du 12V ou du 19V pour notre Desktop de voyage:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;fr.aliexpress.com&#x2F;item&#x2F;1005003830437385.html?spm=a2g0o.detail.pcDetailTopMoreOtherSeller.1.7efdd6HJd6HJsk&amp;amp;gps-id=pcDetailTopMoreOtherSeller&amp;amp;scm=1007.40050.354490.0&amp;amp;scm_id=1007.40050.354490.0&amp;amp;scm-url=1007.40050.354490.0&amp;amp;pvid=eb881fbf-d3c6-4c16-ab62-6905ac003620&amp;amp;_t=gps-id:pcDetailTopMoreOtherSeller,scm-url:1007.40050.354490.0,pvid:eb881fbf-d3c6-4c16-ab62-6905ac003620,tpp_buckets:668%232846%238109%231935&amp;amp;pdp_ext_f=%7B%22order%22%3A%2222%22%2C%22eval%22%3A%221%22%2C%22sceneId%22%3A%2230050%22%7D&amp;amp;pdp_npi=6%40dis%21EUR%2123.99%2123.99%21%21%2127.11%2127.11%21%40211b816617545026906144826ef278%2112000027294090095%21rec%21FR%21752714805%21XZ%211%210%21&amp;amp;utparam-url=scene%3ApcDetailTopMoreOtherSeller%7Cquery_from%3A&quot;&gt;DB1915A&lt;&#x2F;a&gt; (input 16-24V, 200W) ~23€
&lt;blockquote&gt;
&lt;p&gt;8V amplitude
pas moyen de jouer avec USB PD&#x2F;QC&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;resources.mini-box.com&#x2F;online&#x2F;PWR-PICOPSU-120-WI-25V&#x2F;PWR-PICOPSU-120-WI-25V-manual.pdf&quot;&gt;picoPSU-120 WI 25V&lt;&#x2F;a&gt; (input 12-25V, 120W) ~50€
&lt;blockquote&gt;
&lt;p&gt; &amp;gt;94% Efficiency, 13V amplitude
un peu limite niveau puissance cible (125W en excursion)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;hdplex.com&#x2F;hdplex-200w-dc-atx-power-supply-12v-48v-wide-range-voltage-input.html&quot;&gt;HDPLEX 200W DC-ATX Direct Plug&lt;&#x2F;a&gt; (input 12-48V, 200W) ~80€&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#hdplex&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;
&lt;blockquote&gt;
&lt;p&gt; &amp;gt;94% Efficiency, 36V amplitude (!), 220W Peak
 fourni avec un Φ7.4x5.0mm femelle pour l’input du PC&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;On l’a vu, plus l’entrée supportée est élevée, plus on pourra jouer avec le standard USB PD&#x2F;QC en négociant avec un voltage plus élevé.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;hdplex&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;quasiment tout le temps hors stock ⚠️ je les ai directement contactés par mail et ils ont du stock en EU à ce prix ! 😃&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;relier-les-deux&quot;&gt;Relier les deux&lt;a class=&quot;zola-anchor&quot; href=&quot;#relier-les-deux&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;On distingue l’USB Type C, qui possède une puce E-Mark pour bien négocier la charge, des autres connecteurs plus classiques. Parfois les deux se retrouvent ensemble dans un adaptateur :&lt;&#x2F;p&gt;
&lt;h4 id=&quot;avec-negociation&quot;&gt;Avec négociation&lt;a class=&quot;zola-anchor&quot; href=&quot;#avec-negociation&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;Power Delivery Switch
&lt;blockquote&gt;
&lt;p&gt;What is PD Switch? Well, it’s a cable that forces the AC adapter to deliver 20v (or any other voltage) at all times. You can buy on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;fr.aliexpress.com&#x2F;item&#x2F;1005004980363165.html&quot;&gt;AliExpress for like $10&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;sans-negociation&quot;&gt;Sans négociation&lt;a class=&quot;zola-anchor&quot; href=&quot;#sans-negociation&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Pas de négociation de charge mais ça fournit en général le maximum, sans logique intermédiaire. Les tailles standard les plus courantes pour les prises d’alimentation DC sont 2,1 mm et 2,5 mm, en référence au diamètre intérieur du connecteur. Le diamètre extérieur du connecteur varie généralement entre 5,5 mm et 6,5 mm, selon la conception spécifique et le fabricant.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;lazer3d.com&#x2F;wp-content&#x2F;uploads&#x2F;2023&#x2F;10&#x2F;DC-DC-Power-Jack-Connectors-Male-and-Female.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Coax Φ5.5x2.1mm (standard A slim)&lt;&#x2F;li&gt;
&lt;li&gt;Coax Φ5.5x2.5mm (standard A)&lt;&#x2F;li&gt;
&lt;li&gt;Coax Φ4.5x3.0mm (Dell slim)&lt;&#x2F;li&gt;
&lt;li&gt;Coax Φ7.4x5.0mm (Dell standard)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Barrel jacks&#x2F;Coax connectors are typically only rated for about 11A max
:thinking_face: 11A⎓12V is only 132W
👍 11A⎓19V is 209W&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;solutions&quot;&gt;Solutions&lt;a class=&quot;zola-anchor&quot; href=&quot;#solutions&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Ce n’est pas parce que ce serait bien de mutualiser un chargeur en USB Type C qu’on ne peut pas fonctionner avec un chargeur plus facile à trouver en coaxial. On a ainsi accès à un large panel de bloc alims de laptops, et surtout un large marché de l’occasion. Parfait pour équiper un bureau si on ne veut pas &lt;em&gt;toujours&lt;&#x2F;em&gt; se trimballer un chargeur, même mutualisé. Les “solutions” sont donc en fait des réponses à un problème que je me suis imposé tout seul.&lt;&#x2F;p&gt;
&lt;p&gt;Peu importe la solution choisie, le système peut aisément être alimenté avec un bloc alim de laptop en coaxial, il faut juste que celui-ci soit assez puissant.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;1-utiliser-un-voltage-superieur-28v-pour-atteindre-140w-en-qc-5-0-pd-2-0&quot;&gt;1. utiliser un voltage supérieur (28V) pour atteindre 140W en QC 5.0&#x2F;PD 2.0&lt;a class=&quot;zola-anchor&quot; href=&quot;#1-utiliser-un-voltage-superieur-28v-pour-atteindre-140w-en-qc-5-0-pd-2-0&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Another way to approach this, is to buy 12v picopsu (there are a lot more variants available for 12v) and prepare that voltage by using DC buck converter (20v to 12v) between gan charger and picopsu. That way you will loose around 10%watts available on conversion, but then you can use 28v charger (pd.3.1 140w) instead and actually go beyond 100w limit. (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;sffpc&#x2F;comments&#x2F;11ui82g&#x2F;comment&#x2F;ls8lw93&#x2F;&quot;&gt;source&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Suppose de se balader avec un convertisseur&#x2F;d’avoir une PSU dite “Wide Range” …mais permet théoriquement d’utiliser plus de chargeurs.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;2-utiliser-un-reglage-pour-limiter-la-puissance-tiree&quot;&gt;2. utiliser un réglage pour limiter la puissance tirée&lt;a class=&quot;zola-anchor&quot; href=&quot;#2-utiliser-un-reglage-pour-limiter-la-puissance-tiree&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Au prix d’une réduction de performance de 10% (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;sffpc&#x2F;comments&#x2F;1gdckxj&#x2F;comment&#x2F;lu0oo2v&#x2F;&quot;&gt;source&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;undervolt a bit. Downclock slightly and you’ll get most of the performance for a lower power draw.
As an example, consider the datapoint of -0.1375v: this drops the cinebench score from nearly 5000 down to 4000, and reduces total system power consumption from ~137w to ~110w.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Mais il semble qu’une manière plus intelligente que de sous-volter un CPU existe : le PPT (package power tracking), un réglage BIOS synthétique prenant en compte le couple V&#x2F;Hz et définissant des courbes à adopter pour garder une performance adéquate jusqu’à une limite en Watt. C’est par défaut défini à 88W pour les CPU à 65W de TDP, et 142W pour ceux à 105W de TDP. Le régler permet de réajuster l’ensemble des courbes du couple V&#x2F;Hz du CPU !&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Now consider the datapoint of setting PPT to 48W. This reduces cinebench down to the same ~4000 score, however now system power consumption is ~75w! - so we’re getting the same performance at 35w less system power.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Et pour Intel alors ? On peut prendre un U9 285K (125W) et le faire rentrer par un trou de souris ?&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;…both P-core and E-core frequency is reduced when TDP is crushed down to 65W, leaving a level of performance consistent with, for example, a Ryzen 5 7600X &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.club386.com&#x2F;heres-what-happens-when-you-run-an-intel-core-ultra-9-285k-at-65w&#x2F;&quot;&gt;source&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;La baisse de performance est intéressante sur le papier : un 7600X est 15% plus rapide qu’un 8700G. Mais un U9 285K coûte 2-3x plus cher qu’un 8700G… qui lui-même est 10% moins rapide qu’un 9600X possédant un iGPU moins puissant mais au prix équivalent.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;3-utiliser-un-chargeur-possedant-usb-c-qc-pd-et-coaxial&quot;&gt;3. utiliser un chargeur possédant USB C QC&#x2F;PD et coaxial&lt;a class=&quot;zola-anchor&quot; href=&quot;#3-utiliser-un-chargeur-possedant-usb-c-qc-pd-et-coaxial&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Partant du principe que les chargeurs compatibles sont de toute façon assez rares, et que l’on va devoir en acheter un bien spécifique, autant voir si les chargeurs ne supportent pas d’autres connectiques que le “simple” USB Type-C avec QC&#x2F;PD.&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    
    
    
      &lt;source srcset=&quot;https:&#x2F;&#x2F;slimq.life&#x2F;cdn&#x2F;shop&#x2F;files&#x2F;F150-output.jpg&quot; type=&quot;image&#x2F;jpeg&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;https:&#x2F;&#x2F;slimq.life&#x2F;cdn&#x2F;shop&#x2F;files&#x2F;F150-output.jpg&quot; style=&quot;width: 60%&quot;&#x2F;&gt;
    
    
  &lt;&#x2F;picture&gt;

  
  &lt;figcaption class=&quot;f7 black-40 tc&quot;&gt;Chargeur SlimQ F150&lt;&#x2F;figcaption&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;Un example assez unique est le chargeur &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;slimq.life&#x2F;products&#x2F;150w-usb-c-gan-charger-for-universal&quot;&gt;SlimQ F150&lt;&#x2F;a&gt; (~70€) qui délivre en 20V 150W sur un port DC coaxial Φ5.5x2.5mm assez commun, tout en ayant des ports pour téléphone. Il priorise bien la puissance sur le port DC, et module l’intensité sur les autres ports dans la mesure où l’ensemble ne dépasse pas les 150W nominaux. Des adaptateurs sont disponibles, notamment en Φ7.4x5.0mm.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;synthese-des-solutions&quot;&gt;Synthèse des solutions&lt;a class=&quot;zola-anchor&quot; href=&quot;#synthese-des-solutions&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;cote-secteur&quot;&gt;Côté secteur&lt;a class=&quot;zola-anchor&quot; href=&quot;#cote-secteur&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Le plus simple est de prendre la solution 3 + un adaptateur coaxial male&#x2F;Type C femelle avec une puce E-mark (voir connecteurs ci-avant). Ce dernier permet éventuellement de s’adapter à des situations où le chargeur n’est pas présent, mais le reste du temps la solution 3 fournit un barrel jack suffisant.&lt;&#x2F;p&gt;
&lt;p&gt;D’autant que le barrel jack permet de choisir d’autres chargeurs, plus abordables et standards, en 20V, lorsque la mutualisation avec le chargeur de téléphone n’est pas nécessaire (ex: à la maison).&lt;&#x2F;p&gt;
&lt;h4 id=&quot;cote-psu&quot;&gt;Côté psu&lt;a class=&quot;zola-anchor&quot; href=&quot;#cote-psu&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;L’HDPLEX est le seul&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#seul_psu&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; PSU permettant un large gamme d’entrées (input 12-48V) au-delà de 24V, et l’acheter ouvre la possibilité d’alimentations à la fois plus simples (12V) et plus fortes en type-C (PD 28V&#x2F;5A).&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;seul_psu&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;3&lt;&#x2F;sup&gt;
&lt;p&gt;il y a bien des modèles alternatifs comme ceux de G-Uniq, mais ils sont de diffusion encore plus confidentielle.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;ventirads&quot;&gt;Ventirads&lt;a class=&quot;zola-anchor&quot; href=&quot;#ventirads&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Niveau ventilateurs, on est contraints par la hauteur du boîtier qui, à 6cm de haut, ne laisse plus grand chose pour notre couple ventilateur&#x2F;radiateur. Les petits modèles suivants sont d’ailleurs souvent limités dans leur capacité de refroidissement (logique) et indiquent en général ne supporter que des CPU dont le TDP ne dépasse pas 65W.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jonsbo.com&#x2F;en&#x2F;products&#x2F;HP400.html&quot;&gt;Jonsbo HX400&lt;&#x2F;a&gt; (~22€) 36mm de haut&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;sffpc&#x2F;comments&#x2F;1m4zrzy&#x2F;metalfish_dh380_v4_just_2mm_away_from_being_a_x36&#x2F;&quot;&gt;Metalfish DH380&lt;&#x2F;a&gt; (~23€) 38mm de haut&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.fr&#x2F;Thermalright-AXP120-X67-Refroidisseur-ventilateur-1200000000&#x2F;dp&#x2F;B0BDXKZNK4?th=1&quot;&gt;Thermalright AXP90 X36&lt;&#x2F;a&gt; (~26€) 36mm de haut&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#axp90&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;noctua.at&#x2F;fr&#x2F;nh-l9a-am4&quot;&gt;Noctua L9a&lt;&#x2F;a&gt; (~49,90€) 37mm de haut&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;if you use the am4 backplate, the screws will make [the DH380 and AXP90 X36] taller so it will be better without the plate.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Out of L9a, axp90 x36, and dh380, the dh380 feels and looks the least quality.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;preview.redd.it&#x2F;37mm-coolers-tested-l9a-vs-axp90-x36-vs-hp-400s-for-velka-v0-oqxtqe31n0x91.jpg?width=3337&amp;amp;format=pjpg&amp;amp;auto=webp&amp;amp;s=7d904e539918b63de9925ca777a000cb5eaf7e3e&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Noctua NH-L9a (382 g), Thermalright AXP90-X36 (204 g), JONSBO HP400S (158 g)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;preview.redd.it&#x2F;37mm-coolers-tested-l9a-vs-axp90-x36-vs-hp-400s-for-velka-v0-bhgrxr31n0x91.jpg?width=3711&amp;amp;format=pjpg&amp;amp;auto=webp&amp;amp;s=a7ab851be1ba0747d8ba65e0eb285892181df52e&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The results show that the Thermalright AXP90-X36 has a clear advantage with 1.76% higher scores and 1.74 °C lower temps on average compared to the Noctua NH-L9a. I also tested the AXP90-X36 with two 40x15mm exhaust fans at 40% speed mounted below the cooler (similar to this) and it yielded 2.57% higher scores and 2.10 °C lower temps on average compared to the NH-L9a. So despite being lighter and having less thermal mass than the NH-L9a, the AXP90-X36 performed better likely due to a combination of more heatpipes and optimal vertical fin orientation. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;sffpc&#x2F;comments&#x2F;yhsppo&#x2F;37mm_coolers_tested_l9a_vs_axp90x36_vs_hp400s_for&#x2F;&quot;&gt;source&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;[…] fin orientation affected the cooling performance more than number of heat pipes&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Les deux premières marques sont moins connues, les deux dernières ont bonne réputation. Vu la différence de prix et l’absence de processeur à forte enveloppe (version X à X3D), on peut partir sur l’AXP90 X36 sans risque, surtout vu sa meilleur orientation des dissipateurs à ailettes quand l’ordinateur est positionné à la verticale.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;axp90&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;4&lt;&#x2F;sup&gt;
&lt;p&gt;⚠️ il est possible de swap le ventilateur du AXP90 X36 pour ne garder que son radiateur et lui coller un A9x14 (que j’ai déja ! 😃)&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h1 id=&quot;total&quot;&gt;Total&lt;a class=&quot;zola-anchor&quot; href=&quot;#total&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h1&gt;
&lt;p&gt;Pour 300-400€, on peut aisément changer RAM, MB et CPU pour “rafraîchir” la configuration dans quelques années sans changer de spécifications par ailleurs. Et si on se trouve sur une génération de socket indéboulonnable comme AM4, on peut même espérer n’avoir que le CPU à changer, comme ici :&lt;&#x2F;p&gt;
&lt;table class=&quot;center collapse ba br2 b--black-10 pv2 ph3&quot;&gt;
  &lt;tbody&gt;
    &lt;tr class=&quot;striped--light-gray &quot;&gt;
      &lt;th class=&quot;pv2 ph3 tl f6 fw6 ttu&quot;&gt;Rôle&lt;&#x2F;th&gt;
      &lt;th class=&quot;tr f6 ttu fw6 pv2 ph3&quot;&gt;Référence&lt;&#x2F;th&gt;
      &lt;th class=&quot;tr f6 ttu fw6 pv2 ph3&quot;&gt;Prix&lt;&#x2F;th&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr class=&quot;striped--light-gray &quot;&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;boîtier alu&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;SL1 2.1L rev. 3&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;100€&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr class=&quot;striped--light-gray &quot;&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;cpu&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;R7 5700G&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;100€&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr class=&quot;striped--light-gray &quot;&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;pico psu&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;HDPLEX 200W DC-ATX&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;80€&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr class=&quot;striped--light-gray &quot;&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;bloc fixe&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;Dell 180W HA180PM180&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;30€&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr class=&quot;striped--light-gray &quot;&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;bloc mobile&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;SlimQ F150&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;71,90€&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr class=&quot;striped--light-gray &quot;&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;adaptateurs&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;divers&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;10€&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr class=&quot;striped--light-gray &quot;&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;ventirad&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;AXP90 X36&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;26€&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
    &lt;tr class=&quot;striped--light-gray &quot;&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;TOTAL&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;&lt;&#x2F;td&gt;
      &lt;td class=&quot;pv2 ph3&quot;&gt;417,90€&lt;&#x2F;td&gt;
    &lt;&#x2F;tr&gt;
  &lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;À ce tarif, on peut à peine gratter des laptops équipés de processeurs en version mobile d’il y 3 générations …en occasion …et sans voie d’upgrade. À bon entendeur.&lt;&#x2F;p&gt;
</content:encoded>
            </item>
        
            <item>
                <title>Carnet de dévelopment sur PeerTube, étape 2.2</title>
                <pubDate>Fri, 29 May 2020 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/peertube-carnet-de-dev/</link>
                <guid>https://rigelk.frama.io/blog/blog/peertube-carnet-de-dev/</guid>
                <description>&lt;p&gt;La 2.0 était tout juste passée que j’ai remis le pied à l’étrier du dévelopment de PeerTube. J’avais alors enfin libéré un peu de temps libre, et décidé de m’attaquer à un gros morceau : la page d’une vidéo, a.k.a. la &lt;em&gt;watch page&lt;&#x2F;em&gt;. Vous la connaissez, c’est la page de PeerTube avec le lecteur vidéo et le fil de commentaires. Au menu, boutons plus discrets, subtils petit changements de position des commentaires et de la présentation de leurs auteurs, entre autres choses.&lt;&#x2F;p&gt;
&lt;p&gt;À ce moment, j’avais en tête plusieurs améliorations de l’interface utilisateur, le principal souci selon moi à l’époque (et qui le restera à mes yeux vu l’habitude qu’ont les utilisateurs pour les interfaces material&#x2F;flat à souhait, mais c’est un autre sujet…). En quelques mois, le design a déjà beaucoup changé - mais surtout mes compétences en CSS… - tout en gardant les fondamentaux. Est-ce que PeerTube est toujours &lt;em&gt;moche&lt;&#x2F;em&gt; ? Certainement. Surtout si on le compare à ses concurrents GAFAM. Mais bon, un octet à la fois, comme on dit, et c’est déjà bien assez. On tag la 2.1, on release, et on recommence à charbonner.&lt;&#x2F;p&gt;
&lt;p&gt;Il faut dire que le design d’interface, c’est pas notre truc, même si personnellement j’adore ça. On se forme un peu sur le tas, et forcément, ça prend un peu plus de temps (quelque années…) que prévu. Il y a encore beaucoup à faire, et on avance toujours à l’aveugle. Mais voyez-vous, j’ai l’impression d’avoir passé trop de temps sur l’UI visible de tous quand il reste tant à faire côté pile : les menus d’administration.&lt;&#x2F;p&gt;
&lt;p&gt;C’est la deuxième chose qui m’a occupé ces derniers mois : passer en revue les menus d’administration, et essayer de les “rafraîchir” sans changer tout non plus, vu que juin devrait voir le premier contact du projet PeerTube avec de vrais designers&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; pour critiquer et repenser l’administration.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;le design initial de PeerTube, assuré par Olivier Massain, n’avait réfléchi qu’à la partie visible à tous de l’UI. Toute la partie administration, paramétrage, modération multi-niveaux, etc. n’était pas imaginée.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;passer-du-beau-a-l-informatif&quot;&gt;Passer du beau à l’informatif&lt;a class=&quot;zola-anchor&quot; href=&quot;#passer-du-beau-a-l-informatif&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Ma transition aux menus d’administration ne s’est pas faite sans heurts. Ces menus m’étaient pour la plupart peu familiers, étant un développeur de PeerTube sans faire moi-même beaucoup de tâches d’administration d’instance : il y a en effet peu de contenus à modérer sur les serveurs de Framasoft. Sauf que de serveur d’hébergement à petite échelle, PeerTube est de plus en plus utilisé pour héberger de multiples utilisateurs, parfois inconnus des administrateurs ! Et là, les menus d’administration sont forcément austères.&lt;&#x2F;p&gt;
&lt;p&gt;Mais plus que de beaux menus, les administrateurs ont besoin de menus qui intègrent des explications. On ne naît jamais administrateur d’instance, voyez-vous, et la documentation prend du temps à assimiler sans forcément décrire mot à mot toutes les options.&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;menus_administration.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;menus_administration.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;menus_administration.png&quot; style=&quot;width: 90%&quot;&#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
  &lt;figcaption class=&quot;f7 black-40 tc&quot;&gt;Menu d&amp;#x27;administration, avec des descriptions extensives de section et de fonctionalités&lt;&#x2F;figcaption&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;Un autre souci qui est couramment évoqué - ou du moins que les issues nous font remarquer, est celui des fonctionalités activées à la hâte par les administrateurs, quand bien même leur impact est important. Par exemple, le fait d’activer les inscriptions sans mise en quarantaine des nouveaux utilisateurs, ou encore le fait de suivre automatiquement un catalogue d’instances sans une équipe de modération suffisante et formée.&lt;&#x2F;p&gt;
&lt;p&gt;Là encore, la direction que nous prenons est celle d’une meilleure information des administrateurs vis-à-vis de fonctionalités qui trouvent leur utilité pour certains, mais causent des effets de bords pas toujours bien compris.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rendre-les-cles&quot;&gt;Rendre les clés&lt;a class=&quot;zola-anchor&quot; href=&quot;#rendre-les-cles&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Beaucoup de problèmes inhérents à un monde fédéré relèvent de la &lt;em&gt;diffusion&lt;&#x2F;em&gt; de contenu, mais peu s’occupent de la &lt;em&gt;découverte&lt;&#x2F;em&gt; de contenu. C’est un problème d’autant plus criant pour du contenu à la durée de vie longue comme c’est le cas de PeerTube (par opposition à des systèmes de microblogging qui n’ont la plupart du temps pas besoin d’afficher &lt;em&gt;tout&lt;&#x2F;em&gt; le contenu, seulement le plus récent). Pour résoudre ce problème, il y a plusieurs approches, toutes imparfaites, mais qui sont essentiellement analogues à l’indexation de pages web.&lt;&#x2F;p&gt;
&lt;p&gt;De fait, créer un moteur de recherche est compliqué, et encore plus quand on veut donner aux administrateurs le contrôle de leur moteur de recherche. Actuellement, les instances indexent le contenu local et suivi, mais que ce soit pour découvrir des instances ou découvrir des vidéos en dehors de cet index local, il faut ruser.&lt;&#x2F;p&gt;
&lt;p&gt;Notre technique - héberger une liste d’instances à suivre pour enrichir cet index - est certes basique, mais elle a plusieurs avantages :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;facile à héberger&lt;&#x2F;li&gt;
&lt;li&gt;facile à comprendre&lt;&#x2F;li&gt;
&lt;li&gt;facile à modifier&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;demenagement.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;demenagement.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;demenagement.png&quot; style=&quot;width:70%&quot;&#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
  &lt;figcaption class=&quot;f7 black-40 tc&quot;&gt;Ça ne va pas sur l&amp;#x27;autoroute de la décentralisation, mais ça fait le taf et c&amp;#x27;est pas cher&lt;&#x2F;figcaption&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;Jusque-là, elle consistait en un logiciel à autohéberger : celui qui tourne derrière &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;instances.joinpeertube.org&#x2F;&quot;&gt;instances.joinpeertube.org&lt;&#x2F;a&gt;&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. Mais après un an sans voir d’autre installation de ce logiciel, nous avons décidé de permettre l’ajout&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; du support de fichiers simples listant des instances à suivre. Il ne vous reste plus qu’à mettre une liste d’instances dans un format simple, de l’héberger sur un snippet, gist, paste, ou autre lieu de partage informel, voire de l’éditer collaborativement via un système de fusion tel qu’on en trouve sur les forges logicielles.&lt;&#x2F;p&gt;
&lt;p&gt;Mais à quoi ressemble une telle liste, au juste ?&lt;&#x2F;p&gt;
&lt;div &gt;
    &lt;script src=&quot;https:&amp;#x2F;&amp;#x2F;gist.github.com&amp;#x2F;rigelk&amp;#x2F;0da4ce7ff821e0a16728bc397e600465.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Simple comme bonjour :) Et il suffit alors de coller le lien vers le fichier brut en lieu et place d’index pour suivre ces instances dans les 24h, et rester à jour en cas de modification de ce fichier. Utile pour de la curation collaborative ! J’attends avec impatience la création de petites listes recommandant des instances ! Et qui sait, vous me verrez peut-être en relayer.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;framagit.org&#x2F;framasoft&#x2F;peertube&#x2F;instances-peertube&quot;&gt;https:&#x2F;&#x2F;framagit.org&#x2F;framasoft&#x2F;peertube&#x2F;instances-peertube&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;3&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;3&lt;&#x2F;sup&gt;
&lt;p&gt;cette fonctionalité existait déjà, mais le fichier devait impérativement être servi sur la route &lt;code&gt;&#x2F;api&#x2F;v1&#x2F;instances&#x2F;hosts&lt;&#x2F;code&gt;, ne permettant qu’à des administrateurs rompus aux alias de reverse-proxy de servir une telle liste&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;encore-plus-de-responsabilites&quot;&gt;Encore plus de responsabilités&lt;a class=&quot;zola-anchor&quot; href=&quot;#encore-plus-de-responsabilites&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Vous voyez, rendre les clés de la voiture (la liste d’instances dans mon analogie, suivez un peu!) n’est pas assez, il faut aussi que l’on vous rende les clés de tout ce qui est à venir dans PeerTube. Car oui, si on parle de décentralisation, ce n’est pas toujours parfait, ça se repose sur des points de défaillance unique (des serveurs centraux) pour l’exemple, mais jamais &lt;em&gt;un&lt;&#x2F;em&gt; serveur central dont on ne vous donnerait  pas les clés. Il faut toujours que vous puissiez l’héberger vous-même.&lt;&#x2F;p&gt;
&lt;p&gt;Le site de &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;joinpeertube.org&quot;&gt;joinpeertube.org&lt;&#x2F;a&gt; ? Le code source est &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;framagit.org&#x2F;framasoft&#x2F;peertube&#x2F;joinpeertube&#x2F;&quot;&gt;là&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Le site de &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;instances.joinpeertube.org&#x2F;&quot;&gt;la liste d’instances&lt;&#x2F;a&gt; ? Le code source est &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;framagit.org&#x2F;framasoft&#x2F;peertube&#x2F;instances-peertube&quot;&gt;là&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Et naturellement, si on propose un autre service par facilité, ce n’est pas pour vous l’imposer, c’est pour faciliter son essai pour que vous puissiez mieux choisir par la suite de l’héberger vous-même, ou via un &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;chatons.org&#x2F;&quot;&gt;CHATONS&lt;&#x2F;a&gt; ou structure similaire. En somme, c’est la même chose que ce que Framasoft fait vis-à-vis de tout un tas de logiciels, qu’elle met à disposition tout en invitant ceux qui le peuvent à faire leur part.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;les-cles-du-camion-de-la-recherche-globale&quot;&gt;Les clés du camion de la recherche globale&lt;a class=&quot;zola-anchor&quot; href=&quot;#les-cles-du-camion-de-la-recherche-globale&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Certains auront remarqué l’annonce d’une recherche globale. Elle permet de trouver via la barre de recherche d’une instance PeerTube ayant activé cette fonctionalité des vidéos qui n’appartiennent pas qu’aux instances suivies par cette instance, mais de toute instance connue d’un index faisant tourner ce futur moteur de recherche globale. C’est notre seconde réponse au problème (qui encore une fois n’est pas un problème pour tout le monde, PeerTube pouvant très bien être satisfaisant en n’indexant que quelques communautés d’intérêts) évoqué plus tôt, celui de la découverte de contenu.&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;search.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;search.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;search.png&quot; style=&quot;width: 60%&quot;&#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
  &lt;figcaption class=&quot;f7 black-40 tc&quot;&gt;Mockup préliminaire de recherche globale, qui a justifié l&amp;#x27;ajout d&amp;#x27;un typeahead dans la version 2.1&lt;&#x2F;figcaption&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;Et comme pour la voiture, on vous rendra les clés du camion ! Sauf que cette fois, l’index ne tiendra pas sur une simple liste textuelle, j’en conviens. Il faudra évidemment un déploiement un peu plus conséquent pour indexer chaque jour les nouvelles vidéos d’un ensemble d’instances, dont on a vu qu’il compte désormais plusieurs centaines de milliers de vidéos. C’est une des raisons (que je détaille plus bas) pour laquelles nous ne l’avons pas intégré de facto à chaque instance.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;l’index d’instances et l’index de recherche gloable affectant grandement votre politique éditoriale, il est crucial que les communautés s’emparent et hébergent ces outils&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Ce sera probablement une fonctionalité dont beaucoup ne voudront pas, car elle permet aux utilisateurs de voir au-delà des choix éditoriaux de leur administrateur d’instance, les choix éditoriaux de l’administrateur de la liste suivie par l’indexeur (le fameux camion). Ce sera activable par l’administrateur de l’instance, mais le mieux reste encore que quelques administrateurs d’instances pensent aussi à héberger ce camion pour leur communauté. En fait, nous vous incitons fortement à le faire, car les index se servent des listes préalablement établies pour récolter la liste de vidéos qu’ils doivent indexer - l’index d’instances et l’index de recherche gloable affectant grandement votre politique éditoriale, il est crucial que les communautés s’emparent et hébergent ces outils.&lt;&#x2F;p&gt;
&lt;p&gt;Notre proposition se basant d’ElasticSearch, elle ressemble à &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;silicium14&#x2F;peertube_index&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;silicium14&#x2F;peertube_index&lt;&#x2F;a&gt; ou &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;framagit.org&#x2F;rigelk&#x2F;pndex&quot;&gt;https:&#x2F;&#x2F;framagit.org&#x2F;rigelk&#x2F;pndex&lt;&#x2F;a&gt;, en faisant en sorte de faire au plus proche du stack technologique existant dans PeerTube pour faciliter sa maintenance.
Et pour ceux que notre implémentation ne satisfait pas, sachez que le réimplémenter est &lt;em&gt;relativement&lt;&#x2F;em&gt; simple. Libre à vous d’utiliser YaCy avec votre propre adapteur d’API entre PeerTube et lui. Car oui, le seul prérequis est qu’un tel indexeur respecte l’&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.joinpeertube.org&#x2F;api-rest-reference.html#tag&#x2F;Search&quot;&gt;API de recherche documentée&lt;&#x2F;a&gt; de PeerTube.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;petite-retrospective-sur-la-fonctionalite-de-recherche-globale&quot;&gt;Petite rétrospective sur la fonctionalité de recherche globale&lt;a class=&quot;zola-anchor&quot; href=&quot;#petite-retrospective-sur-la-fonctionalite-de-recherche-globale&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Après tout ce charabia technique n’ayant pour but que de vous dire d’héberger votre propre indexeur, vous pourriez être intéressés par un peu de contexte quant à l’origine du besoin d’une recherche globale par certains. Dans un passé fort lointain, voici les quelques discussions qui me viennent à l’esprit :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;framacolibri.org&#x2F;t&#x2F;ma-video-nest-pas-trouvable-dans-toutes-les-instances&#x2F;3407&quot;&gt;https:&#x2F;&#x2F;framacolibri.org&#x2F;t&#x2F;ma-video-nest-pas-trouvable-dans-toutes-les-instances&#x2F;3407&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Chocobozzz&#x2F;PeerTube&#x2F;issues&#x2F;824&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;Chocobozzz&#x2F;PeerTube&#x2F;issues&#x2F;824&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Naturellement, en plus de ces discussions, il y a eu de nombreux retours qui font état d’une attente de trouver &lt;em&gt;tout&lt;&#x2F;em&gt; le contenu du réseaux PeerTube sur n’importe quelle instance. C’est impossible à satisfaire, bien entendu, mais certains se satisferont d’un entre-deux. C’est à ces personnes que la recherche globale s’adresse - et en aucun cas la recherche globale sous cette forme ne prétend être &lt;em&gt;la&lt;&#x2F;em&gt; réponse au problème de la rercherche de contenu sur PeerTube.&lt;&#x2F;p&gt;
&lt;p&gt;Le choix de recourir à un indexeur externe sous la forme d’un serveur central est certainement étrange, surtout quand on cherche à décentraliser. Cette approche en apparence antinomique du but affiché de décentraliser le streaming vidéo vise pourtant bien à faciliter - ou du moins éviter de rendre plus complexe - le déploiement d’instances PeerTube sur des machines peu puissantes, et donc leur décentralisation : on n’a pas perdu de vue le but de pouvoir installer PeerTube sur peu de ressources, même si l’obligation de transcoder localement les vidéos rend cette promesse bancale pour l’instant.&lt;&#x2F;p&gt;
&lt;p&gt;Forcer l’installation d’outils d’indexation sur chaque instance&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#4&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; réduirait grandement la maintenabilité et, pardonnez du néologisme, l’&lt;em&gt;installabilité&lt;&#x2F;em&gt; de PeerTube. On ne veut pas vous faire de fausses promesses sur de l’installation en un clic&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#5&quot;&gt;5&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, mais on ne veut pas non plus mettre des batons dans vos roues. L’installation via YunoHost est probablement le mieux que l’on puisse faire en terme d’installation rapide en production si vous n’avez pas les compétences pour faire un déploiement de production manuel ou via &lt;code&gt;docker-compose&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;4&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;4&lt;&#x2F;sup&gt;
&lt;p&gt;plusieurs dizaines&#x2F;centaines de millions de vidéos indexées ne se font malheureusement pas aussi facilement sur une base de donnée PostgreSQL… Les deux projets d’indexation cités plus haut nous ont permis de faire des comparaisons de performance en vitesse de réponse, et malheureusement, à moins d’avoir un foudre de guerre, PostgreSQL n’est pas assez rapide (à 2M de vidéos, de l’ordre de 2s&#x2F;req pour une charge de 20 clients, loin du compte) sans passer plus de temps à l’optimiser - du temps que l’on a pas vraiment&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;5&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;5&lt;&#x2F;sup&gt;
&lt;p&gt;un déploiement en un clic par exemple via Heroku depuis le README est vu par certains comme un argument de vente, allant jusqu’à intégrer &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ngrok.com&#x2F;&quot;&gt;ngrok&lt;&#x2F;a&gt; dans leur déploiement ; cela ne vous donne pas un environement adéquat, d’autant plus pour un service fédéré qui requiert un domaine stable&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;de-nouvelles-cles-de-moderations&quot;&gt;De nouvelles clés de modérations&lt;a class=&quot;zola-anchor&quot; href=&quot;#de-nouvelles-cles-de-moderations&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Au cas où je n’aurais pas encore abusé de mon analogie sur les clés, il reste encore plein de choses à faire du côté de l’interface d’administration - et plus particulièrement sur l’interface de modération. Si je vous en parle, c’est évidemment parce que l’on va s’y consacrer dans les mois à venir, mais aussi parce que c’est un &lt;em&gt;morceau d’UX&lt;&#x2F;em&gt; que je n’avais encore jamais abordé dans d’autres projets. De fait, les questions soulevées me sont nouvelles, et passionnantes. Par exemple :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;comment gère-t-on son temps de modération ?&lt;&#x2F;li&gt;
&lt;li&gt;quelles sont les catégories principales de rapports ?&lt;&#x2F;li&gt;
&lt;li&gt;quelles actions sont faites le plus régulièrement pour donner suite à un rapport ?&lt;&#x2F;li&gt;
&lt;li&gt;comment communique l’équipe de modération&lt;&#x2F;li&gt;
&lt;li&gt;comment se transmet-elle le savoir acquis via les précédents rapports ?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Et déjà, vous pouvez voir que l’on va allier de profondes réflexions d’UX dans la feuille de route 2020, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Chocobozzz&#x2F;PeerTube&#x2F;projects&#x2F;5?card_filter_query=label%3A%22component%3A+moderation+%3Agodmode%3A%22&quot;&gt;que l’on a déjà engagé&lt;&#x2F;a&gt;. Liste ultra-non-exhaustive :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;des emails faisant suite aux rapports qui contiennent les détails du rapport et des liens vers des actions&lt;&#x2F;li&gt;
&lt;li&gt;des actions de masse pour le blocage de domaines, la suppression de commentaires, etc.&lt;&#x2F;li&gt;
&lt;li&gt;des statistiques de modération par utilisateur, pointant directement vers leurs rapports&lt;&#x2F;li&gt;
&lt;li&gt;du filtrage par défaut sur les chaînes correspondant aux blocages du compte publiant la vidéo&lt;&#x2F;li&gt;
&lt;li&gt;des informations et statistiques sur la vidéo et les comptes rapporteur&#x2F;rapporté accessibles depuis le table listant les rapports&lt;&#x2F;li&gt;
&lt;li&gt;des morceaux d’API supplémentaires pour les plugins, dont certains ouvrent au filtrage de vidéo à l’upload&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Cela nous a mené, grâce aux retours d’administrateurs d’instances, à nous concentrer sur la notion de signalement, déjà existante mais peu ergonomique. Son rôle est central dans la mémoire d’une équipe de modération, et son suivi permet d’éclairer des décisions ultérieures en lien avec les instances ou chaînes impliquées. Il nous a paru assez naturel de rajouter ces informations dans le détail (en cliquant sur la ligne de la table listant les signalements) d’un signalement :&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;moderation.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;moderation.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;moderation.png&quot; &#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
  &lt;figcaption class=&quot;f7 black-40 tc&quot;&gt;Chaque rapport a une vue étendue inspirée de Mastodon, à l&amp;#x27;accès rapide et qui contiendra bientôt l&amp;#x27;historique d&amp;#x27;un rapport&lt;&#x2F;figcaption&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;Ces informations sont amenées à être complétées d’un fil de discussion entre modérateurs, ainsi que d’un historique des actions menées (pour, par exemple, retracer les actions sur une vidéo signalée effectuées depuis une autre partie de l’interface, ou inversement, créer un rapport lors d’une modération directe pour en garder trace via un &lt;em&gt;log de modération&lt;&#x2F;em&gt;). La même démarche de résumé des informations clés nous a amené à rajouter un panneau d’information à propos d’un utilisateur :&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;user.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;user.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;user.png&quot; style=&quot;width: 60%&quot;&#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
  &lt;figcaption class=&quot;f7 black-40 tc&quot;&gt;Statistiques de modération d&amp;#x27;un utilisateur, où chaque panneau mènera à terme à la liste de contenu concerné&lt;&#x2F;figcaption&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;Ces fonctionalités sont amenées à être largement complétées, et leur interface raffinée voire repensée, mais l’idée est là. C’est probablement la partie qui m’a le plus questionné - on imagine rarement les expériences utilisateur côté administrateur, et elles sont passionnantes. Vous avez envie de vous y frotter, vous êtes meilleur que moi en CSS (facile!) ? Votre aide est encore et toujours la bienvenue sur la forge de PeerTube :)&lt;&#x2F;p&gt;
</description>
                <content:encoded>&lt;p&gt;La 2.0 était tout juste passée que j’ai remis le pied à l’étrier du dévelopment de PeerTube. J’avais alors enfin libéré un peu de temps libre, et décidé de m’attaquer à un gros morceau : la page d’une vidéo, a.k.a. la &lt;em&gt;watch page&lt;&#x2F;em&gt;. Vous la connaissez, c’est la page de PeerTube avec le lecteur vidéo et le fil de commentaires. Au menu, boutons plus discrets, subtils petit changements de position des commentaires et de la présentation de leurs auteurs, entre autres choses.&lt;&#x2F;p&gt;
&lt;p&gt;À ce moment, j’avais en tête plusieurs améliorations de l’interface utilisateur, le principal souci selon moi à l’époque (et qui le restera à mes yeux vu l’habitude qu’ont les utilisateurs pour les interfaces material&#x2F;flat à souhait, mais c’est un autre sujet…). En quelques mois, le design a déjà beaucoup changé - mais surtout mes compétences en CSS… - tout en gardant les fondamentaux. Est-ce que PeerTube est toujours &lt;em&gt;moche&lt;&#x2F;em&gt; ? Certainement. Surtout si on le compare à ses concurrents GAFAM. Mais bon, un octet à la fois, comme on dit, et c’est déjà bien assez. On tag la 2.1, on release, et on recommence à charbonner.&lt;&#x2F;p&gt;
&lt;p&gt;Il faut dire que le design d’interface, c’est pas notre truc, même si personnellement j’adore ça. On se forme un peu sur le tas, et forcément, ça prend un peu plus de temps (quelque années…) que prévu. Il y a encore beaucoup à faire, et on avance toujours à l’aveugle. Mais voyez-vous, j’ai l’impression d’avoir passé trop de temps sur l’UI visible de tous quand il reste tant à faire côté pile : les menus d’administration.&lt;&#x2F;p&gt;
&lt;p&gt;C’est la deuxième chose qui m’a occupé ces derniers mois : passer en revue les menus d’administration, et essayer de les “rafraîchir” sans changer tout non plus, vu que juin devrait voir le premier contact du projet PeerTube avec de vrais designers&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; pour critiquer et repenser l’administration.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;le design initial de PeerTube, assuré par Olivier Massain, n’avait réfléchi qu’à la partie visible à tous de l’UI. Toute la partie administration, paramétrage, modération multi-niveaux, etc. n’était pas imaginée.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;passer-du-beau-a-l-informatif&quot;&gt;Passer du beau à l’informatif&lt;a class=&quot;zola-anchor&quot; href=&quot;#passer-du-beau-a-l-informatif&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Ma transition aux menus d’administration ne s’est pas faite sans heurts. Ces menus m’étaient pour la plupart peu familiers, étant un développeur de PeerTube sans faire moi-même beaucoup de tâches d’administration d’instance : il y a en effet peu de contenus à modérer sur les serveurs de Framasoft. Sauf que de serveur d’hébergement à petite échelle, PeerTube est de plus en plus utilisé pour héberger de multiples utilisateurs, parfois inconnus des administrateurs ! Et là, les menus d’administration sont forcément austères.&lt;&#x2F;p&gt;
&lt;p&gt;Mais plus que de beaux menus, les administrateurs ont besoin de menus qui intègrent des explications. On ne naît jamais administrateur d’instance, voyez-vous, et la documentation prend du temps à assimiler sans forcément décrire mot à mot toutes les options.&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;menus_administration.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;menus_administration.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;menus_administration.png&quot; style=&quot;width: 90%&quot;&#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
  &lt;figcaption class=&quot;f7 black-40 tc&quot;&gt;Menu d&amp;#x27;administration, avec des descriptions extensives de section et de fonctionalités&lt;&#x2F;figcaption&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;Un autre souci qui est couramment évoqué - ou du moins que les issues nous font remarquer, est celui des fonctionalités activées à la hâte par les administrateurs, quand bien même leur impact est important. Par exemple, le fait d’activer les inscriptions sans mise en quarantaine des nouveaux utilisateurs, ou encore le fait de suivre automatiquement un catalogue d’instances sans une équipe de modération suffisante et formée.&lt;&#x2F;p&gt;
&lt;p&gt;Là encore, la direction que nous prenons est celle d’une meilleure information des administrateurs vis-à-vis de fonctionalités qui trouvent leur utilité pour certains, mais causent des effets de bords pas toujours bien compris.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rendre-les-cles&quot;&gt;Rendre les clés&lt;a class=&quot;zola-anchor&quot; href=&quot;#rendre-les-cles&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Beaucoup de problèmes inhérents à un monde fédéré relèvent de la &lt;em&gt;diffusion&lt;&#x2F;em&gt; de contenu, mais peu s’occupent de la &lt;em&gt;découverte&lt;&#x2F;em&gt; de contenu. C’est un problème d’autant plus criant pour du contenu à la durée de vie longue comme c’est le cas de PeerTube (par opposition à des systèmes de microblogging qui n’ont la plupart du temps pas besoin d’afficher &lt;em&gt;tout&lt;&#x2F;em&gt; le contenu, seulement le plus récent). Pour résoudre ce problème, il y a plusieurs approches, toutes imparfaites, mais qui sont essentiellement analogues à l’indexation de pages web.&lt;&#x2F;p&gt;
&lt;p&gt;De fait, créer un moteur de recherche est compliqué, et encore plus quand on veut donner aux administrateurs le contrôle de leur moteur de recherche. Actuellement, les instances indexent le contenu local et suivi, mais que ce soit pour découvrir des instances ou découvrir des vidéos en dehors de cet index local, il faut ruser.&lt;&#x2F;p&gt;
&lt;p&gt;Notre technique - héberger une liste d’instances à suivre pour enrichir cet index - est certes basique, mais elle a plusieurs avantages :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;facile à héberger&lt;&#x2F;li&gt;
&lt;li&gt;facile à comprendre&lt;&#x2F;li&gt;
&lt;li&gt;facile à modifier&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;demenagement.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;demenagement.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;demenagement.png&quot; style=&quot;width:70%&quot;&#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
  &lt;figcaption class=&quot;f7 black-40 tc&quot;&gt;Ça ne va pas sur l&amp;#x27;autoroute de la décentralisation, mais ça fait le taf et c&amp;#x27;est pas cher&lt;&#x2F;figcaption&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;Jusque-là, elle consistait en un logiciel à autohéberger : celui qui tourne derrière &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;instances.joinpeertube.org&#x2F;&quot;&gt;instances.joinpeertube.org&lt;&#x2F;a&gt;&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. Mais après un an sans voir d’autre installation de ce logiciel, nous avons décidé de permettre l’ajout&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; du support de fichiers simples listant des instances à suivre. Il ne vous reste plus qu’à mettre une liste d’instances dans un format simple, de l’héberger sur un snippet, gist, paste, ou autre lieu de partage informel, voire de l’éditer collaborativement via un système de fusion tel qu’on en trouve sur les forges logicielles.&lt;&#x2F;p&gt;
&lt;p&gt;Mais à quoi ressemble une telle liste, au juste ?&lt;&#x2F;p&gt;
&lt;div &gt;
    &lt;script src=&quot;https:&amp;#x2F;&amp;#x2F;gist.github.com&amp;#x2F;rigelk&amp;#x2F;0da4ce7ff821e0a16728bc397e600465.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Simple comme bonjour :) Et il suffit alors de coller le lien vers le fichier brut en lieu et place d’index pour suivre ces instances dans les 24h, et rester à jour en cas de modification de ce fichier. Utile pour de la curation collaborative ! J’attends avec impatience la création de petites listes recommandant des instances ! Et qui sait, vous me verrez peut-être en relayer.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;framagit.org&#x2F;framasoft&#x2F;peertube&#x2F;instances-peertube&quot;&gt;https:&#x2F;&#x2F;framagit.org&#x2F;framasoft&#x2F;peertube&#x2F;instances-peertube&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;3&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;3&lt;&#x2F;sup&gt;
&lt;p&gt;cette fonctionalité existait déjà, mais le fichier devait impérativement être servi sur la route &lt;code&gt;&#x2F;api&#x2F;v1&#x2F;instances&#x2F;hosts&lt;&#x2F;code&gt;, ne permettant qu’à des administrateurs rompus aux alias de reverse-proxy de servir une telle liste&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;encore-plus-de-responsabilites&quot;&gt;Encore plus de responsabilités&lt;a class=&quot;zola-anchor&quot; href=&quot;#encore-plus-de-responsabilites&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Vous voyez, rendre les clés de la voiture (la liste d’instances dans mon analogie, suivez un peu!) n’est pas assez, il faut aussi que l’on vous rende les clés de tout ce qui est à venir dans PeerTube. Car oui, si on parle de décentralisation, ce n’est pas toujours parfait, ça se repose sur des points de défaillance unique (des serveurs centraux) pour l’exemple, mais jamais &lt;em&gt;un&lt;&#x2F;em&gt; serveur central dont on ne vous donnerait  pas les clés. Il faut toujours que vous puissiez l’héberger vous-même.&lt;&#x2F;p&gt;
&lt;p&gt;Le site de &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;joinpeertube.org&quot;&gt;joinpeertube.org&lt;&#x2F;a&gt; ? Le code source est &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;framagit.org&#x2F;framasoft&#x2F;peertube&#x2F;joinpeertube&#x2F;&quot;&gt;là&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Le site de &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;instances.joinpeertube.org&#x2F;&quot;&gt;la liste d’instances&lt;&#x2F;a&gt; ? Le code source est &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;framagit.org&#x2F;framasoft&#x2F;peertube&#x2F;instances-peertube&quot;&gt;là&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Et naturellement, si on propose un autre service par facilité, ce n’est pas pour vous l’imposer, c’est pour faciliter son essai pour que vous puissiez mieux choisir par la suite de l’héberger vous-même, ou via un &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;chatons.org&#x2F;&quot;&gt;CHATONS&lt;&#x2F;a&gt; ou structure similaire. En somme, c’est la même chose que ce que Framasoft fait vis-à-vis de tout un tas de logiciels, qu’elle met à disposition tout en invitant ceux qui le peuvent à faire leur part.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;les-cles-du-camion-de-la-recherche-globale&quot;&gt;Les clés du camion de la recherche globale&lt;a class=&quot;zola-anchor&quot; href=&quot;#les-cles-du-camion-de-la-recherche-globale&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Certains auront remarqué l’annonce d’une recherche globale. Elle permet de trouver via la barre de recherche d’une instance PeerTube ayant activé cette fonctionalité des vidéos qui n’appartiennent pas qu’aux instances suivies par cette instance, mais de toute instance connue d’un index faisant tourner ce futur moteur de recherche globale. C’est notre seconde réponse au problème (qui encore une fois n’est pas un problème pour tout le monde, PeerTube pouvant très bien être satisfaisant en n’indexant que quelques communautés d’intérêts) évoqué plus tôt, celui de la découverte de contenu.&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;search.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;search.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;search.png&quot; style=&quot;width: 60%&quot;&#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
  &lt;figcaption class=&quot;f7 black-40 tc&quot;&gt;Mockup préliminaire de recherche globale, qui a justifié l&amp;#x27;ajout d&amp;#x27;un typeahead dans la version 2.1&lt;&#x2F;figcaption&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;Et comme pour la voiture, on vous rendra les clés du camion ! Sauf que cette fois, l’index ne tiendra pas sur une simple liste textuelle, j’en conviens. Il faudra évidemment un déploiement un peu plus conséquent pour indexer chaque jour les nouvelles vidéos d’un ensemble d’instances, dont on a vu qu’il compte désormais plusieurs centaines de milliers de vidéos. C’est une des raisons (que je détaille plus bas) pour laquelles nous ne l’avons pas intégré de facto à chaque instance.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;l’index d’instances et l’index de recherche gloable affectant grandement votre politique éditoriale, il est crucial que les communautés s’emparent et hébergent ces outils&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Ce sera probablement une fonctionalité dont beaucoup ne voudront pas, car elle permet aux utilisateurs de voir au-delà des choix éditoriaux de leur administrateur d’instance, les choix éditoriaux de l’administrateur de la liste suivie par l’indexeur (le fameux camion). Ce sera activable par l’administrateur de l’instance, mais le mieux reste encore que quelques administrateurs d’instances pensent aussi à héberger ce camion pour leur communauté. En fait, nous vous incitons fortement à le faire, car les index se servent des listes préalablement établies pour récolter la liste de vidéos qu’ils doivent indexer - l’index d’instances et l’index de recherche gloable affectant grandement votre politique éditoriale, il est crucial que les communautés s’emparent et hébergent ces outils.&lt;&#x2F;p&gt;
&lt;p&gt;Notre proposition se basant d’ElasticSearch, elle ressemble à &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;silicium14&#x2F;peertube_index&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;silicium14&#x2F;peertube_index&lt;&#x2F;a&gt; ou &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;framagit.org&#x2F;rigelk&#x2F;pndex&quot;&gt;https:&#x2F;&#x2F;framagit.org&#x2F;rigelk&#x2F;pndex&lt;&#x2F;a&gt;, en faisant en sorte de faire au plus proche du stack technologique existant dans PeerTube pour faciliter sa maintenance.
Et pour ceux que notre implémentation ne satisfait pas, sachez que le réimplémenter est &lt;em&gt;relativement&lt;&#x2F;em&gt; simple. Libre à vous d’utiliser YaCy avec votre propre adapteur d’API entre PeerTube et lui. Car oui, le seul prérequis est qu’un tel indexeur respecte l’&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.joinpeertube.org&#x2F;api-rest-reference.html#tag&#x2F;Search&quot;&gt;API de recherche documentée&lt;&#x2F;a&gt; de PeerTube.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;petite-retrospective-sur-la-fonctionalite-de-recherche-globale&quot;&gt;Petite rétrospective sur la fonctionalité de recherche globale&lt;a class=&quot;zola-anchor&quot; href=&quot;#petite-retrospective-sur-la-fonctionalite-de-recherche-globale&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Après tout ce charabia technique n’ayant pour but que de vous dire d’héberger votre propre indexeur, vous pourriez être intéressés par un peu de contexte quant à l’origine du besoin d’une recherche globale par certains. Dans un passé fort lointain, voici les quelques discussions qui me viennent à l’esprit :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;framacolibri.org&#x2F;t&#x2F;ma-video-nest-pas-trouvable-dans-toutes-les-instances&#x2F;3407&quot;&gt;https:&#x2F;&#x2F;framacolibri.org&#x2F;t&#x2F;ma-video-nest-pas-trouvable-dans-toutes-les-instances&#x2F;3407&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Chocobozzz&#x2F;PeerTube&#x2F;issues&#x2F;824&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;Chocobozzz&#x2F;PeerTube&#x2F;issues&#x2F;824&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Naturellement, en plus de ces discussions, il y a eu de nombreux retours qui font état d’une attente de trouver &lt;em&gt;tout&lt;&#x2F;em&gt; le contenu du réseaux PeerTube sur n’importe quelle instance. C’est impossible à satisfaire, bien entendu, mais certains se satisferont d’un entre-deux. C’est à ces personnes que la recherche globale s’adresse - et en aucun cas la recherche globale sous cette forme ne prétend être &lt;em&gt;la&lt;&#x2F;em&gt; réponse au problème de la rercherche de contenu sur PeerTube.&lt;&#x2F;p&gt;
&lt;p&gt;Le choix de recourir à un indexeur externe sous la forme d’un serveur central est certainement étrange, surtout quand on cherche à décentraliser. Cette approche en apparence antinomique du but affiché de décentraliser le streaming vidéo vise pourtant bien à faciliter - ou du moins éviter de rendre plus complexe - le déploiement d’instances PeerTube sur des machines peu puissantes, et donc leur décentralisation : on n’a pas perdu de vue le but de pouvoir installer PeerTube sur peu de ressources, même si l’obligation de transcoder localement les vidéos rend cette promesse bancale pour l’instant.&lt;&#x2F;p&gt;
&lt;p&gt;Forcer l’installation d’outils d’indexation sur chaque instance&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#4&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; réduirait grandement la maintenabilité et, pardonnez du néologisme, l’&lt;em&gt;installabilité&lt;&#x2F;em&gt; de PeerTube. On ne veut pas vous faire de fausses promesses sur de l’installation en un clic&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#5&quot;&gt;5&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, mais on ne veut pas non plus mettre des batons dans vos roues. L’installation via YunoHost est probablement le mieux que l’on puisse faire en terme d’installation rapide en production si vous n’avez pas les compétences pour faire un déploiement de production manuel ou via &lt;code&gt;docker-compose&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;4&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;4&lt;&#x2F;sup&gt;
&lt;p&gt;plusieurs dizaines&#x2F;centaines de millions de vidéos indexées ne se font malheureusement pas aussi facilement sur une base de donnée PostgreSQL… Les deux projets d’indexation cités plus haut nous ont permis de faire des comparaisons de performance en vitesse de réponse, et malheureusement, à moins d’avoir un foudre de guerre, PostgreSQL n’est pas assez rapide (à 2M de vidéos, de l’ordre de 2s&#x2F;req pour une charge de 20 clients, loin du compte) sans passer plus de temps à l’optimiser - du temps que l’on a pas vraiment&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;5&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;5&lt;&#x2F;sup&gt;
&lt;p&gt;un déploiement en un clic par exemple via Heroku depuis le README est vu par certains comme un argument de vente, allant jusqu’à intégrer &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ngrok.com&#x2F;&quot;&gt;ngrok&lt;&#x2F;a&gt; dans leur déploiement ; cela ne vous donne pas un environement adéquat, d’autant plus pour un service fédéré qui requiert un domaine stable&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;de-nouvelles-cles-de-moderations&quot;&gt;De nouvelles clés de modérations&lt;a class=&quot;zola-anchor&quot; href=&quot;#de-nouvelles-cles-de-moderations&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Au cas où je n’aurais pas encore abusé de mon analogie sur les clés, il reste encore plein de choses à faire du côté de l’interface d’administration - et plus particulièrement sur l’interface de modération. Si je vous en parle, c’est évidemment parce que l’on va s’y consacrer dans les mois à venir, mais aussi parce que c’est un &lt;em&gt;morceau d’UX&lt;&#x2F;em&gt; que je n’avais encore jamais abordé dans d’autres projets. De fait, les questions soulevées me sont nouvelles, et passionnantes. Par exemple :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;comment gère-t-on son temps de modération ?&lt;&#x2F;li&gt;
&lt;li&gt;quelles sont les catégories principales de rapports ?&lt;&#x2F;li&gt;
&lt;li&gt;quelles actions sont faites le plus régulièrement pour donner suite à un rapport ?&lt;&#x2F;li&gt;
&lt;li&gt;comment communique l’équipe de modération&lt;&#x2F;li&gt;
&lt;li&gt;comment se transmet-elle le savoir acquis via les précédents rapports ?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Et déjà, vous pouvez voir que l’on va allier de profondes réflexions d’UX dans la feuille de route 2020, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Chocobozzz&#x2F;PeerTube&#x2F;projects&#x2F;5?card_filter_query=label%3A%22component%3A+moderation+%3Agodmode%3A%22&quot;&gt;que l’on a déjà engagé&lt;&#x2F;a&gt;. Liste ultra-non-exhaustive :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;des emails faisant suite aux rapports qui contiennent les détails du rapport et des liens vers des actions&lt;&#x2F;li&gt;
&lt;li&gt;des actions de masse pour le blocage de domaines, la suppression de commentaires, etc.&lt;&#x2F;li&gt;
&lt;li&gt;des statistiques de modération par utilisateur, pointant directement vers leurs rapports&lt;&#x2F;li&gt;
&lt;li&gt;du filtrage par défaut sur les chaînes correspondant aux blocages du compte publiant la vidéo&lt;&#x2F;li&gt;
&lt;li&gt;des informations et statistiques sur la vidéo et les comptes rapporteur&#x2F;rapporté accessibles depuis le table listant les rapports&lt;&#x2F;li&gt;
&lt;li&gt;des morceaux d’API supplémentaires pour les plugins, dont certains ouvrent au filtrage de vidéo à l’upload&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Cela nous a mené, grâce aux retours d’administrateurs d’instances, à nous concentrer sur la notion de signalement, déjà existante mais peu ergonomique. Son rôle est central dans la mémoire d’une équipe de modération, et son suivi permet d’éclairer des décisions ultérieures en lien avec les instances ou chaînes impliquées. Il nous a paru assez naturel de rajouter ces informations dans le détail (en cliquant sur la ligne de la table listant les signalements) d’un signalement :&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;moderation.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;moderation.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;moderation.png&quot; &#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
  &lt;figcaption class=&quot;f7 black-40 tc&quot;&gt;Chaque rapport a une vue étendue inspirée de Mastodon, à l&amp;#x27;accès rapide et qui contiendra bientôt l&amp;#x27;historique d&amp;#x27;un rapport&lt;&#x2F;figcaption&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;Ces informations sont amenées à être complétées d’un fil de discussion entre modérateurs, ainsi que d’un historique des actions menées (pour, par exemple, retracer les actions sur une vidéo signalée effectuées depuis une autre partie de l’interface, ou inversement, créer un rapport lors d’une modération directe pour en garder trace via un &lt;em&gt;log de modération&lt;&#x2F;em&gt;). La même démarche de résumé des informations clés nous a amené à rajouter un panneau d’information à propos d’un utilisateur :&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;user.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;user.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;user.png&quot; style=&quot;width: 60%&quot;&#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
  &lt;figcaption class=&quot;f7 black-40 tc&quot;&gt;Statistiques de modération d&amp;#x27;un utilisateur, où chaque panneau mènera à terme à la liste de contenu concerné&lt;&#x2F;figcaption&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;Ces fonctionalités sont amenées à être largement complétées, et leur interface raffinée voire repensée, mais l’idée est là. C’est probablement la partie qui m’a le plus questionné - on imagine rarement les expériences utilisateur côté administrateur, et elles sont passionnantes. Vous avez envie de vous y frotter, vous êtes meilleur que moi en CSS (facile!) ? Votre aide est encore et toujours la bienvenue sur la forge de PeerTube :)&lt;&#x2F;p&gt;
</content:encoded>
            </item>
        
            <item>
                <title>WebTorrent, le bon, le brut, l&#x27;abandonné</title>
                <pubDate>Sat, 25 Apr 2020 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/webtorrent-new-horizons/</link>
                <guid>https://rigelk.frama.io/blog/blog/webtorrent-new-horizons/</guid>
                <description>&lt;p&gt;Comment vous parler du web décentralisé en 2020 ? La décennie passée a été riche en petites innovations qui ont changé la donne pour autant de petits acteurs. On a parlé de web 3.0, de DWeb, d’économie distribuée ; j’y reviendrai. Celle-ci venait prendre la relève de celle de la décennie passée et son partage frénétique de fichiers, elle-même s’inspirant de celle passée alors où les espoirs de décentralisation d’un Internet naissant venaient s’échouer sur des coûts que la simplicité seule de la centralisation ne suffisait plus à financer. Restait alors un vide, que les idéaux et les usages mettront encore longtemps avant de s’élargir à tous les pans de la société.&lt;&#x2F;p&gt;
&lt;p&gt;Mais pourquoi cette quête de décentralisation ? Certains s’offusquent que l’on critique la centralisation de leur solution technologique, et préfèrent nous enjoindre de ne regarder que la carotte qu’ils nous tendent, ce service qu’ils « offrent ». Personne n’est dupe ; on dit même que « si c’est gratuit, c’est vous le produit », non ? La sagesse collective est tétanisée devant la technologie, et oublie le principe de précaution qu’elle appliquerait autrement : ne pas faire aveuglément confiance aux inconnus, ne pas se mettre à nu en public, etc. Car oui, sur Internet, tout est affaire de confiance aveugle. Vous ne savez pas qui fait tourner le serveur, qui fait le profit pour le payer. Et du « client », le navigateur est bien plus souvent le bétail que l’on tond sur l’autel de la monétisation de la vie privée.&lt;&#x2F;p&gt;
&lt;p&gt;Le web distribué veut rebattre les cartes. Pas de serveur central, et donc pas de besoin d’en payer, tout simplement. Si serveur il y a, il est de petite échelle pour que les coûts restent absorbables par un individu, et n’est certainement pas le seul serveur fournissant le service.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;heritier&quot;&gt;Héritier de BitTorrent&lt;a class=&quot;zola-anchor&quot; href=&quot;#heritier&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Si les préoccupations précédentes sont aujourd’hui au cœur des communautés libertaires d’Internet, les années 2000 voyaient ces technologies sous un angle plus utilitaire, cherchant à répondre à la massification des usages et plus particulièrement à la diffusion de fichiers, dont le transfert représentait un défi important : sur un serveur unique, plus un fichier est demandé, moins il est accessible ; si chaque client devient serveur après avoir fini de télécharger le fichier, la tendance précédente est inversée et la qualité de service améliorée.&lt;&#x2F;p&gt;
&lt;p&gt;BitTorrent partit de ce constat et proposa dès 2002 un logiciel qui deux décennies plus tard reste le standard de partage de fichiers distribué. Il a été conçu pour limiter l’usage d’un serveur à sa plus simple expression (un tracker ou un nœud DHT), et si la découverte de contenu reste un problème qu’il ne résout pas, il a permis à des communautés de partage de naître et prospérer. S’affranchissant d’un censeur, il peut ignorer les contrôles couramment placés sur les plateformes centralisées où le contenu doit respecter le droit d’auteur.&lt;&#x2F;p&gt;
&lt;p&gt;BitTorrent est cependant une technologie qui n’a pas suivi la migration des usages d’Internet vers le web, et WebTorrent vient changer cela. Il permet de faire de chaque navigateur un client BitTorrent en puissance. Ce serait probablement passé inaperçu en la présence préalable d’un protocole de diffusion de fichier efficace de navigateur à navigateur, mais aucun n’existait alors qui soit réellement efficace en 2013. Les usages sont alors multiples, permettant de partager des vidéos sans avoir à installer un client dédié, et de pouvoir utiliser un simple navigateur quelle que soit la platforme : ordinateur, tablette, portable, télévision, voiture (sic), etc.&lt;&#x2F;p&gt;
&lt;p&gt;Un des objectifs de WebTorrent est de maintenir la compatibilité avec le &lt;em&gt;protocole&lt;&#x2F;em&gt; BitTorrent, mais pas forcément avec les &lt;em&gt;transports&lt;&#x2F;em&gt; traditionnellement utilisés par ses clients. De fait, WebTorrent utilise WebRTC comme transport, là où les clients classiques utilisent TCP, μTCP ou UDP.&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: false }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;webtrump.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;webtrump.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;webtrump.png&quot; style=&quot;min-width: 300px; width: 30vw&quot;&#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
&lt;&#x2F;div&gt;
&lt;p&gt;En résulte un double-réseau de pairs qui ne peuvent communiquer entre eux à moins de supporter un protocole de chaque groupe, ce que les navigateurs ne permettent pas. En effet WebTorrent est tributaire des APIs des navigateurs - c’est un problème que ces derniers tendent à vouloir résoudre par l’installation d’extensions, même si leur API d’extension ne permet pas encore autant de fonctionalités.&lt;&#x2F;p&gt;
&lt;p&gt;Le fait que WebTorrent utilise le protocole BitTorrent circonscrit aussi ses applications à du téléchargement ou du &lt;em&gt;streaming simple&lt;&#x2F;em&gt;, quand l’intérêt principal de WebTorrent est de permettre l’usage et la diffusion concomitantes de ressources : la technique de diffusion limite largement certains usages, plus dynamiques, qui se sont répandus récemment pour répondre à des cas d’usages particuliers : streaming &lt;em&gt;en direct&lt;&#x2F;em&gt;, accès aléatoire ou partiel. D’autres limitations sont propres à l’implémentation de WebTorrent, comme sa capacité à limiter le débit ou le partage en cas d’usage mobile.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tributaire-de-webrtc&quot;&gt;Tributaire de WebRTC et son écosystème&lt;a class=&quot;zola-anchor&quot; href=&quot;#tributaire-de-webrtc&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Si WebTorrent a eu un tel succès, c’est grâce à une technologie sous-jacente, WebRTC, et son support dans la plupart des navigateurs. WebRTC est la « colle » qui permet la connection entre navigateurs quand HTTP ne permet historiquement aux navigateurs que les connections sortantes, vers un serveur. WebRTC permet aux navigateurs de se décentraliser. Mais WebRTC est complexe, trop complexe pour certains, et ses implémentations hors d’un navigateurs sont rares.&lt;&#x2F;p&gt;
&lt;p&gt;Autrement dit, les clients BitTorrent classiques n’ont toujours pas ajouté de support pour WebRTC et donc WebTorrent 7 ans plus tard. Pire, à cause de cette dépendence à WebRTC les utilitaires et bibilothèques dépendent pour la plupart d’un navigateur pour utiliser WebTorrent, limitant grandement leur nombre et les languages avec lesquel·le·s les utiliser.&lt;&#x2F;p&gt;
&lt;p&gt;En comparaison, Dat comme IPFS ont fait un bien meilleur travail (mais aussi bien mieux financé) de fond avec deux implémentations de référence : une côté navigateur, une côté côté système. De fait, leur écosystème pourtant naissant est riche d’intégrations dans divers languages. Cela n’en fait pas un meilleur candidat pour autant, IPFS n’étant pas épargné par des problèmes similaires de performance et d’adéquation pour le streaming.&lt;&#x2F;p&gt;
&lt;p&gt;Une mention honorable revient à &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rawrtc&#x2F;rawrtc&quot;&gt;rawrtc&lt;&#x2F;a&gt;, qui a lutté pour intégrer WebRTC dans plusieurs clients BitTorrent de bureau avec une implémentation native indépendante de celle de Chrome.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pourquoi-streaming&quot;&gt;Pourquoi parler de streaming ?&lt;a class=&quot;zola-anchor&quot; href=&quot;#pourquoi-streaming&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Je ne suis pas neutre, je participe au dévelopement d’une application de streaming : &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;joinpeertube.org&quot;&gt;PeerTube&lt;&#x2F;a&gt;. Tous les problèmes évoqués, nous les avons rencontrés, et plus encore. Quand il s’agit de streaming différé (pas un &lt;em&gt;live&lt;&#x2F;em&gt;), la vidéo est stockée sous forme d’un fichier unique avec BitTorrent. Et lorsqu’un client charge cette vidéo, il est courant de vouloir aller à un timecode précis, voire de sauter à différentes parties de la vidéo. Tout cela suppose de savoir à quels blocs de la vidéo correspondent un timestamp donné, et cela suppose d’avoir connaissance d’une métadonnée stockée au début du fichier, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.adobe.com&#x2F;devnet&#x2F;video&#x2F;articles&#x2F;mp4_movie_atom.html&quot;&gt;l’en-tête MOOV&lt;&#x2F;a&gt;. Avec BitTorrent, l’en-tête ne sera pas plus téléchargé en priorité qu’une autre &lt;em&gt;chunk&lt;&#x2F;em&gt; du fichier.&lt;&#x2F;p&gt;
&lt;p&gt;Certains clients BitTorrent facilient ce téléchargement en forçant la priorité sur les premiers &lt;em&gt;chunks&lt;&#x2F;em&gt;, mais WebTorrent ne l’expose pas, et les bibliothèques&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; permettant de lire un stream video depuis WebTorrent ne sont pas plus riches non plus. Le problème de richesse de l’écosystème autour de WebTorrent se rappelle douloureusement à nous dans ce cas.&lt;&#x2F;p&gt;
&lt;p&gt;Cela ne paraît pas grand chose, mais c’est cet en-tête qui permet de faire la correspondance entre un bloc de la vidéo et un timestamp. Sans cela, on est condamné à faire une approximation de la position du chunk dans le &lt;em&gt;stream&lt;&#x2F;em&gt;. C’est en général innefficace et cela se voit, en particulier sur les longues vidéos, et les petites vidéos où le timestamp est arrondi.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;webtorrent&#x2F;webtorrent&#x2F;issues&#x2F;1097&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;webtorrent&#x2F;webtorrent&#x2F;issues&#x2F;1097&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;quel-espoir-pour-webtorrent&quot;&gt;Quel espoir pour WebTorrent ?&lt;a class=&quot;zola-anchor&quot; href=&quot;#quel-espoir-pour-webtorrent&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Avec deux boulets au pied mais aussi deux technologies majeures et couramment utilisées, WebTorrent n’est pas prêt de quitter le paysage du web dans un futur proche. Mais des questions se posent quant à son évolution, étant donné que son dévelopeur principal n’est plus actif (à se disperser avec près de 200 paquets sur npm, on peut comprendre…) ; les co-mainteneurs n’assurant plus qu’une maintenance de réparation.&lt;&#x2F;p&gt;
&lt;p&gt;Quoiqu’il en soit, son objectif de compatibilité avec BitTorrent est à la fois un tremplin pour sa popularité et un blocage certain pour la compatibilité avec des applications temps-réel, où l’immutabilité de ses données &lt;em&gt;metainfo&lt;&#x2F;em&gt; l’empêche de couvrir l’ajout dynamique de &lt;em&gt;chunks&lt;&#x2F;em&gt; lors d’un &lt;em&gt;live&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;WebRTC est moins problématique sur le long terme alors que de nouvelles implémentations hors du navigateurs émergeront - gageons alors que cet écosystème profitera à WebTorrent.&lt;&#x2F;p&gt;
</description>
                <content:encoded>&lt;p&gt;Comment vous parler du web décentralisé en 2020 ? La décennie passée a été riche en petites innovations qui ont changé la donne pour autant de petits acteurs. On a parlé de web 3.0, de DWeb, d’économie distribuée ; j’y reviendrai. Celle-ci venait prendre la relève de celle de la décennie passée et son partage frénétique de fichiers, elle-même s’inspirant de celle passée alors où les espoirs de décentralisation d’un Internet naissant venaient s’échouer sur des coûts que la simplicité seule de la centralisation ne suffisait plus à financer. Restait alors un vide, que les idéaux et les usages mettront encore longtemps avant de s’élargir à tous les pans de la société.&lt;&#x2F;p&gt;
&lt;p&gt;Mais pourquoi cette quête de décentralisation ? Certains s’offusquent que l’on critique la centralisation de leur solution technologique, et préfèrent nous enjoindre de ne regarder que la carotte qu’ils nous tendent, ce service qu’ils « offrent ». Personne n’est dupe ; on dit même que « si c’est gratuit, c’est vous le produit », non ? La sagesse collective est tétanisée devant la technologie, et oublie le principe de précaution qu’elle appliquerait autrement : ne pas faire aveuglément confiance aux inconnus, ne pas se mettre à nu en public, etc. Car oui, sur Internet, tout est affaire de confiance aveugle. Vous ne savez pas qui fait tourner le serveur, qui fait le profit pour le payer. Et du « client », le navigateur est bien plus souvent le bétail que l’on tond sur l’autel de la monétisation de la vie privée.&lt;&#x2F;p&gt;
&lt;p&gt;Le web distribué veut rebattre les cartes. Pas de serveur central, et donc pas de besoin d’en payer, tout simplement. Si serveur il y a, il est de petite échelle pour que les coûts restent absorbables par un individu, et n’est certainement pas le seul serveur fournissant le service.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;heritier&quot;&gt;Héritier de BitTorrent&lt;a class=&quot;zola-anchor&quot; href=&quot;#heritier&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Si les préoccupations précédentes sont aujourd’hui au cœur des communautés libertaires d’Internet, les années 2000 voyaient ces technologies sous un angle plus utilitaire, cherchant à répondre à la massification des usages et plus particulièrement à la diffusion de fichiers, dont le transfert représentait un défi important : sur un serveur unique, plus un fichier est demandé, moins il est accessible ; si chaque client devient serveur après avoir fini de télécharger le fichier, la tendance précédente est inversée et la qualité de service améliorée.&lt;&#x2F;p&gt;
&lt;p&gt;BitTorrent partit de ce constat et proposa dès 2002 un logiciel qui deux décennies plus tard reste le standard de partage de fichiers distribué. Il a été conçu pour limiter l’usage d’un serveur à sa plus simple expression (un tracker ou un nœud DHT), et si la découverte de contenu reste un problème qu’il ne résout pas, il a permis à des communautés de partage de naître et prospérer. S’affranchissant d’un censeur, il peut ignorer les contrôles couramment placés sur les plateformes centralisées où le contenu doit respecter le droit d’auteur.&lt;&#x2F;p&gt;
&lt;p&gt;BitTorrent est cependant une technologie qui n’a pas suivi la migration des usages d’Internet vers le web, et WebTorrent vient changer cela. Il permet de faire de chaque navigateur un client BitTorrent en puissance. Ce serait probablement passé inaperçu en la présence préalable d’un protocole de diffusion de fichier efficace de navigateur à navigateur, mais aucun n’existait alors qui soit réellement efficace en 2013. Les usages sont alors multiples, permettant de partager des vidéos sans avoir à installer un client dédié, et de pouvoir utiliser un simple navigateur quelle que soit la platforme : ordinateur, tablette, portable, télévision, voiture (sic), etc.&lt;&#x2F;p&gt;
&lt;p&gt;Un des objectifs de WebTorrent est de maintenir la compatibilité avec le &lt;em&gt;protocole&lt;&#x2F;em&gt; BitTorrent, mais pas forcément avec les &lt;em&gt;transports&lt;&#x2F;em&gt; traditionnellement utilisés par ses clients. De fait, WebTorrent utilise WebRTC comme transport, là où les clients classiques utilisent TCP, μTCP ou UDP.&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: false }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;webtrump.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;webtrump.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;webtrump.png&quot; style=&quot;min-width: 300px; width: 30vw&quot;&#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
&lt;&#x2F;div&gt;
&lt;p&gt;En résulte un double-réseau de pairs qui ne peuvent communiquer entre eux à moins de supporter un protocole de chaque groupe, ce que les navigateurs ne permettent pas. En effet WebTorrent est tributaire des APIs des navigateurs - c’est un problème que ces derniers tendent à vouloir résoudre par l’installation d’extensions, même si leur API d’extension ne permet pas encore autant de fonctionalités.&lt;&#x2F;p&gt;
&lt;p&gt;Le fait que WebTorrent utilise le protocole BitTorrent circonscrit aussi ses applications à du téléchargement ou du &lt;em&gt;streaming simple&lt;&#x2F;em&gt;, quand l’intérêt principal de WebTorrent est de permettre l’usage et la diffusion concomitantes de ressources : la technique de diffusion limite largement certains usages, plus dynamiques, qui se sont répandus récemment pour répondre à des cas d’usages particuliers : streaming &lt;em&gt;en direct&lt;&#x2F;em&gt;, accès aléatoire ou partiel. D’autres limitations sont propres à l’implémentation de WebTorrent, comme sa capacité à limiter le débit ou le partage en cas d’usage mobile.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tributaire-de-webrtc&quot;&gt;Tributaire de WebRTC et son écosystème&lt;a class=&quot;zola-anchor&quot; href=&quot;#tributaire-de-webrtc&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Si WebTorrent a eu un tel succès, c’est grâce à une technologie sous-jacente, WebRTC, et son support dans la plupart des navigateurs. WebRTC est la « colle » qui permet la connection entre navigateurs quand HTTP ne permet historiquement aux navigateurs que les connections sortantes, vers un serveur. WebRTC permet aux navigateurs de se décentraliser. Mais WebRTC est complexe, trop complexe pour certains, et ses implémentations hors d’un navigateurs sont rares.&lt;&#x2F;p&gt;
&lt;p&gt;Autrement dit, les clients BitTorrent classiques n’ont toujours pas ajouté de support pour WebRTC et donc WebTorrent 7 ans plus tard. Pire, à cause de cette dépendence à WebRTC les utilitaires et bibilothèques dépendent pour la plupart d’un navigateur pour utiliser WebTorrent, limitant grandement leur nombre et les languages avec lesquel·le·s les utiliser.&lt;&#x2F;p&gt;
&lt;p&gt;En comparaison, Dat comme IPFS ont fait un bien meilleur travail (mais aussi bien mieux financé) de fond avec deux implémentations de référence : une côté navigateur, une côté côté système. De fait, leur écosystème pourtant naissant est riche d’intégrations dans divers languages. Cela n’en fait pas un meilleur candidat pour autant, IPFS n’étant pas épargné par des problèmes similaires de performance et d’adéquation pour le streaming.&lt;&#x2F;p&gt;
&lt;p&gt;Une mention honorable revient à &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rawrtc&#x2F;rawrtc&quot;&gt;rawrtc&lt;&#x2F;a&gt;, qui a lutté pour intégrer WebRTC dans plusieurs clients BitTorrent de bureau avec une implémentation native indépendante de celle de Chrome.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pourquoi-streaming&quot;&gt;Pourquoi parler de streaming ?&lt;a class=&quot;zola-anchor&quot; href=&quot;#pourquoi-streaming&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Je ne suis pas neutre, je participe au dévelopement d’une application de streaming : &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;joinpeertube.org&quot;&gt;PeerTube&lt;&#x2F;a&gt;. Tous les problèmes évoqués, nous les avons rencontrés, et plus encore. Quand il s’agit de streaming différé (pas un &lt;em&gt;live&lt;&#x2F;em&gt;), la vidéo est stockée sous forme d’un fichier unique avec BitTorrent. Et lorsqu’un client charge cette vidéo, il est courant de vouloir aller à un timecode précis, voire de sauter à différentes parties de la vidéo. Tout cela suppose de savoir à quels blocs de la vidéo correspondent un timestamp donné, et cela suppose d’avoir connaissance d’une métadonnée stockée au début du fichier, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.adobe.com&#x2F;devnet&#x2F;video&#x2F;articles&#x2F;mp4_movie_atom.html&quot;&gt;l’en-tête MOOV&lt;&#x2F;a&gt;. Avec BitTorrent, l’en-tête ne sera pas plus téléchargé en priorité qu’une autre &lt;em&gt;chunk&lt;&#x2F;em&gt; du fichier.&lt;&#x2F;p&gt;
&lt;p&gt;Certains clients BitTorrent facilient ce téléchargement en forçant la priorité sur les premiers &lt;em&gt;chunks&lt;&#x2F;em&gt;, mais WebTorrent ne l’expose pas, et les bibliothèques&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; permettant de lire un stream video depuis WebTorrent ne sont pas plus riches non plus. Le problème de richesse de l’écosystème autour de WebTorrent se rappelle douloureusement à nous dans ce cas.&lt;&#x2F;p&gt;
&lt;p&gt;Cela ne paraît pas grand chose, mais c’est cet en-tête qui permet de faire la correspondance entre un bloc de la vidéo et un timestamp. Sans cela, on est condamné à faire une approximation de la position du chunk dans le &lt;em&gt;stream&lt;&#x2F;em&gt;. C’est en général innefficace et cela se voit, en particulier sur les longues vidéos, et les petites vidéos où le timestamp est arrondi.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;webtorrent&#x2F;webtorrent&#x2F;issues&#x2F;1097&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;webtorrent&#x2F;webtorrent&#x2F;issues&#x2F;1097&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;quel-espoir-pour-webtorrent&quot;&gt;Quel espoir pour WebTorrent ?&lt;a class=&quot;zola-anchor&quot; href=&quot;#quel-espoir-pour-webtorrent&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Avec deux boulets au pied mais aussi deux technologies majeures et couramment utilisées, WebTorrent n’est pas prêt de quitter le paysage du web dans un futur proche. Mais des questions se posent quant à son évolution, étant donné que son dévelopeur principal n’est plus actif (à se disperser avec près de 200 paquets sur npm, on peut comprendre…) ; les co-mainteneurs n’assurant plus qu’une maintenance de réparation.&lt;&#x2F;p&gt;
&lt;p&gt;Quoiqu’il en soit, son objectif de compatibilité avec BitTorrent est à la fois un tremplin pour sa popularité et un blocage certain pour la compatibilité avec des applications temps-réel, où l’immutabilité de ses données &lt;em&gt;metainfo&lt;&#x2F;em&gt; l’empêche de couvrir l’ajout dynamique de &lt;em&gt;chunks&lt;&#x2F;em&gt; lors d’un &lt;em&gt;live&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;WebRTC est moins problématique sur le long terme alors que de nouvelles implémentations hors du navigateurs émergeront - gageons alors que cet écosystème profitera à WebTorrent.&lt;&#x2F;p&gt;
</content:encoded>
            </item>
        
            <item>
                <title>Taking the gate</title>
                <pubDate>Fri, 06 Apr 2018 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/taking-the-gate/</link>
                <guid>https://rigelk.frama.io/blog/blog/taking-the-gate/</guid>
                <description>&lt;p&gt;Taking the gate is no small feat. It’s the drawbridge to the fort. It’s the symbol of power and the first thing the traveler sees from the outside. It’s the separation between savage and civilized worlds. Unfortunately the portcullis are closed to us.&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;draw_bridge.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;draw_bridge.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;draw_bridge.png&quot; &#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;em&gt;engraving of a medieval drawbridge, William &amp;amp; Robert Chambers Encyclopaedia - A Dictionary of Universal Knowledge for the People (Philadelphia, PA: J. B. Lippincott &amp;amp; Co., 1881)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Fast forward to our times, the gateway to our homes has long been left out of sight. We don’t really know what to do with it and for better or worse it &lt;em&gt;just works&lt;&#x2F;em&gt;™. It’s often a simple enough device that just does routing and modem tasks. Period. Most people plug it and forget about its existence until a guests needs wireless access, only to discover that &lt;em&gt;ah, a hex string is complicated. What?! I could change it?&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Yet it’s certainly one of the most valueable piece of hardware you might have. It is the public-facing device of your home, and it certainly also protects it with NAT and firewall. All of that, transparently. Wow. If it were not for this protection, we would all need to learn how to defend ourself against attackers that could directly access our machines from the Internet.&lt;&#x2F;p&gt;
&lt;p&gt;It’s also the last nail in the coffin of the nineteen-seventies, when the Internet was a small decentralized collective of computers. Computers could communicate directly with each other to communicate, exchange small services, and there were no gates. It was arguably another era, where security was not much the same concern. Then came back the gates. Users wanted the security of the gate, and it certainly did protect them. They could see the web but the web could not see them. The old Internet lost something back then, since all machines could not be reached anymore. Some of them remained, open trading posts - public servers -, providing goods and services to the travelers adventuring past their gates.&lt;&#x2F;p&gt;
&lt;p&gt;Now users are left with gates no one hardly ever slides up, and trading posts spying on them. There are safe heavens. Servers and services that guarantee your privacy. There are also inns and houses you can rent to stay private, but it comes at a cost.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;self-hosting&quot;&gt;The lie of self-hosting&lt;a class=&quot;zola-anchor&quot; href=&quot;#self-hosting&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Be it on servers you rent from hosting providers or on a local machine, there are many solutions to self-host. But in the end you always need a machine to stay online most of the time, with enough storage and modern services. It can become tricky to setup, as seemingly low entry barriers are already beyond the few clicks required to open an account in a centralized service. In the end, we have to agree there will never be a single way to self-host.&lt;&#x2F;p&gt;
&lt;p&gt;But is self-hosting any good? The question deserves an answer. Yes, it provides the best alternative in terms of data privacy and modularity. You can litterally install any service you want as long as you have the code and the time to do the installation and maintenance. But these are hard tasks. Even with the help of modern turnkey solutions, your machines can suffer from outage and hardware failure, and then you must know how to restore backups, if any.&lt;&#x2F;p&gt;
&lt;p&gt;Really self-hosting isn’t easy. Technology isn’t easy. Let that sink in. We have hidden the complexity of technology behind shiny flat design interfaces, and suprisingly, it worked. User interfaces decide which service will win the heart of users, independently of its features or respect of the user. It’s quite logical when you don’t understand how the service works. But nice interfaces are something lacking in the free software world. Worse, their integration in the overall user experience is still a second class citizen. That subject alone deserves its own dedicated post.&lt;&#x2F;p&gt;
&lt;p&gt;All in all, self-hosted alternatives have not failed us but the users that need it most: the rest of the population, still gated and taken hostage at trading posts. We need to give them more possibilities, and removing the gates is certainly an interesting one. Not an easy one, but we’ll come to that later. But even as hard as it can be, it relieves of an obstacle that has forced us to design convoluted programs to circumvent them, making programs that ultimately are out of reach of the average user.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fort-or-road&quot;&gt;Not in the fort nor on the road&lt;a class=&quot;zola-anchor&quot; href=&quot;#fort-or-road&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;By now it should be obvious that if we can’t really solve the question of &lt;em&gt;how&lt;&#x2F;em&gt; that simply, we could help solve the &lt;em&gt;where&lt;&#x2F;em&gt;. Plenty of solutions exist to set up a decent software suite and even deal with automated backups. It won’t have everything and I certainly don’t recommend to put all you services on it, because you know, &lt;em&gt;mail is hard&lt;&#x2F;em&gt;. Anyway, that leaves us a good margin to do an already reasonable bunch of services on our machine.&lt;&#x2F;p&gt;
&lt;p&gt;That is, if we have a machine.&lt;&#x2F;p&gt;
&lt;p&gt;The average user has their laptop or desktop computer. Or both. But they certainly don’t want to dedicate it to a NAS purpose. That’s “wasting a computer”, right? And renting one at a hosting provider is money, so it’s something out of reach, right?&lt;&#x2F;p&gt;
&lt;p&gt;That’s where the router becomes a nice target. It’s litterally the only device that everyone has running night and day. It’s a low-end, low-power device. Oh yes, you can’t put a lot of services on it, but its potential to regain privacy is no less interesting, since by default all devices that connect to it will benefit from settings such as DNS, ad blocking or VPN features. A DNS blackhole for ads? done. A DNS server that forwards requests over TLS? easy, the setup is done once for every device on the LAN. A VPN linking together your LAN with those of your parents&#x2F;friends? check.&lt;&#x2F;p&gt;
&lt;p&gt;These network services, provided LAN-wide, are more interesting that what even your average NAS provides. It allows to bind networks together, provide home automation control, intrusion detection and properly configured, it can &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pi-hole.net&#x2F;2017&#x2F;02&#x2F;22&#x2F;what-really-happens-on-your-network-find-out-with-pi-hole&#x2F;&quot;&gt;tame spying devices&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We need to open the gate.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gate-to-agora&quot;&gt;From gate to agora&lt;a class=&quot;zola-anchor&quot; href=&quot;#gate-to-agora&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Of course I’m simplifying &lt;em&gt;a lot&lt;&#x2F;em&gt;. You don’t get to configure things that easily on your router. First, chances are your router is not running an open source OS, lest you break&#x2F;brick it you see. Then there’s the actual configuration. Say your run OpenWRT&#x2F;LEDE. Configuration is not straightforward and even web interfaces don’t provide simple configuration steps to achieve what I’ve presented. A gap certainly needs to be filled to transform the gates into something that brings value and services to the user ; into something that connects the user to others instead of blocking interaction.&lt;&#x2F;p&gt;
&lt;p&gt;Opening the gate to a kind of communication closer to the user’s needs and the real collaborative Internet we thought to build is litterally a one step process: get root access. Usually if the router is running an open source software, you already have access with your admin password. Once in possession of the router credentials, sky’s the limit… for sysadmins. Of course I don’t expect even tech-savvy users to know how to configure properly so many aspects of a router. Instead we should commission experts to do the configuration for us. For instance knowledgeable friends, CHATONS or associative ISPs, etc.&lt;&#x2F;p&gt;
&lt;p&gt;In a world where boxes are ever more tightly bound to services provided by giant ISPs that don’t provide Internet access only anymore, we have to adapt and think ahead of them. They already provide VoIP and TVoIP services in triple-play offers. That’s of course out of the scope of what an ISP should offer, but that doesn’t mean we shouldn’t care about them either. It’s added value to their customers, and a deterrent to move away from their offers, especially considering their price which is often more competitive. Providing extra features at the router level, we not only catch up with big telcos, we also provide the direct embodiement of what open networks allow.&lt;&#x2F;p&gt;
&lt;p&gt;Plenty of technologies could feel right at home in a router. A networked hard disk connected over USB? It’s usually only available to your LAN, but what if you have a configured SFTP access from the outside? What if you have a configured VPN that allows you to access your LAN wherever you are? What if you have a configured binding of two LAN over a VPN? You would never need remote storage again.&lt;&#x2F;p&gt;
&lt;p&gt;There is the need for a tool that allows easy sharing of these credentials. A tool that would allow such remote access with trusted third parties. A tool that would allow delegation of configuration tasks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;brick-and-mortar&quot;&gt;The brick and mortar of the agora&lt;a class=&quot;zola-anchor&quot; href=&quot;#brick-and-mortar&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Configuration tasks are tedious, even to the experienced user. Hopefully we don’t need to remember every single task - that would be error-prone - and can rely on community-contributed scripts such as ansible playbooks&#x2F;roles to configure tasks and do the necessary checks before changing anything. LXC containers coming to the rescue, we can prevent the added programs from interfering with the essential features of your router.&lt;&#x2F;p&gt;
&lt;p&gt;We need to provide the building blocks for the agora. It’s the next stage to build Internet communities and create more interest in both self-hosting and associative ISPs.&lt;&#x2F;p&gt;
</description>
                <content:encoded>&lt;p&gt;Taking the gate is no small feat. It’s the drawbridge to the fort. It’s the symbol of power and the first thing the traveler sees from the outside. It’s the separation between savage and civilized worlds. Unfortunately the portcullis are closed to us.&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;draw_bridge.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;draw_bridge.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;draw_bridge.png&quot; &#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;em&gt;engraving of a medieval drawbridge, William &amp;amp; Robert Chambers Encyclopaedia - A Dictionary of Universal Knowledge for the People (Philadelphia, PA: J. B. Lippincott &amp;amp; Co., 1881)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Fast forward to our times, the gateway to our homes has long been left out of sight. We don’t really know what to do with it and for better or worse it &lt;em&gt;just works&lt;&#x2F;em&gt;™. It’s often a simple enough device that just does routing and modem tasks. Period. Most people plug it and forget about its existence until a guests needs wireless access, only to discover that &lt;em&gt;ah, a hex string is complicated. What?! I could change it?&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Yet it’s certainly one of the most valueable piece of hardware you might have. It is the public-facing device of your home, and it certainly also protects it with NAT and firewall. All of that, transparently. Wow. If it were not for this protection, we would all need to learn how to defend ourself against attackers that could directly access our machines from the Internet.&lt;&#x2F;p&gt;
&lt;p&gt;It’s also the last nail in the coffin of the nineteen-seventies, when the Internet was a small decentralized collective of computers. Computers could communicate directly with each other to communicate, exchange small services, and there were no gates. It was arguably another era, where security was not much the same concern. Then came back the gates. Users wanted the security of the gate, and it certainly did protect them. They could see the web but the web could not see them. The old Internet lost something back then, since all machines could not be reached anymore. Some of them remained, open trading posts - public servers -, providing goods and services to the travelers adventuring past their gates.&lt;&#x2F;p&gt;
&lt;p&gt;Now users are left with gates no one hardly ever slides up, and trading posts spying on them. There are safe heavens. Servers and services that guarantee your privacy. There are also inns and houses you can rent to stay private, but it comes at a cost.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;self-hosting&quot;&gt;The lie of self-hosting&lt;a class=&quot;zola-anchor&quot; href=&quot;#self-hosting&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Be it on servers you rent from hosting providers or on a local machine, there are many solutions to self-host. But in the end you always need a machine to stay online most of the time, with enough storage and modern services. It can become tricky to setup, as seemingly low entry barriers are already beyond the few clicks required to open an account in a centralized service. In the end, we have to agree there will never be a single way to self-host.&lt;&#x2F;p&gt;
&lt;p&gt;But is self-hosting any good? The question deserves an answer. Yes, it provides the best alternative in terms of data privacy and modularity. You can litterally install any service you want as long as you have the code and the time to do the installation and maintenance. But these are hard tasks. Even with the help of modern turnkey solutions, your machines can suffer from outage and hardware failure, and then you must know how to restore backups, if any.&lt;&#x2F;p&gt;
&lt;p&gt;Really self-hosting isn’t easy. Technology isn’t easy. Let that sink in. We have hidden the complexity of technology behind shiny flat design interfaces, and suprisingly, it worked. User interfaces decide which service will win the heart of users, independently of its features or respect of the user. It’s quite logical when you don’t understand how the service works. But nice interfaces are something lacking in the free software world. Worse, their integration in the overall user experience is still a second class citizen. That subject alone deserves its own dedicated post.&lt;&#x2F;p&gt;
&lt;p&gt;All in all, self-hosted alternatives have not failed us but the users that need it most: the rest of the population, still gated and taken hostage at trading posts. We need to give them more possibilities, and removing the gates is certainly an interesting one. Not an easy one, but we’ll come to that later. But even as hard as it can be, it relieves of an obstacle that has forced us to design convoluted programs to circumvent them, making programs that ultimately are out of reach of the average user.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fort-or-road&quot;&gt;Not in the fort nor on the road&lt;a class=&quot;zola-anchor&quot; href=&quot;#fort-or-road&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;By now it should be obvious that if we can’t really solve the question of &lt;em&gt;how&lt;&#x2F;em&gt; that simply, we could help solve the &lt;em&gt;where&lt;&#x2F;em&gt;. Plenty of solutions exist to set up a decent software suite and even deal with automated backups. It won’t have everything and I certainly don’t recommend to put all you services on it, because you know, &lt;em&gt;mail is hard&lt;&#x2F;em&gt;. Anyway, that leaves us a good margin to do an already reasonable bunch of services on our machine.&lt;&#x2F;p&gt;
&lt;p&gt;That is, if we have a machine.&lt;&#x2F;p&gt;
&lt;p&gt;The average user has their laptop or desktop computer. Or both. But they certainly don’t want to dedicate it to a NAS purpose. That’s “wasting a computer”, right? And renting one at a hosting provider is money, so it’s something out of reach, right?&lt;&#x2F;p&gt;
&lt;p&gt;That’s where the router becomes a nice target. It’s litterally the only device that everyone has running night and day. It’s a low-end, low-power device. Oh yes, you can’t put a lot of services on it, but its potential to regain privacy is no less interesting, since by default all devices that connect to it will benefit from settings such as DNS, ad blocking or VPN features. A DNS blackhole for ads? done. A DNS server that forwards requests over TLS? easy, the setup is done once for every device on the LAN. A VPN linking together your LAN with those of your parents&#x2F;friends? check.&lt;&#x2F;p&gt;
&lt;p&gt;These network services, provided LAN-wide, are more interesting that what even your average NAS provides. It allows to bind networks together, provide home automation control, intrusion detection and properly configured, it can &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pi-hole.net&#x2F;2017&#x2F;02&#x2F;22&#x2F;what-really-happens-on-your-network-find-out-with-pi-hole&#x2F;&quot;&gt;tame spying devices&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We need to open the gate.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gate-to-agora&quot;&gt;From gate to agora&lt;a class=&quot;zola-anchor&quot; href=&quot;#gate-to-agora&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Of course I’m simplifying &lt;em&gt;a lot&lt;&#x2F;em&gt;. You don’t get to configure things that easily on your router. First, chances are your router is not running an open source OS, lest you break&#x2F;brick it you see. Then there’s the actual configuration. Say your run OpenWRT&#x2F;LEDE. Configuration is not straightforward and even web interfaces don’t provide simple configuration steps to achieve what I’ve presented. A gap certainly needs to be filled to transform the gates into something that brings value and services to the user ; into something that connects the user to others instead of blocking interaction.&lt;&#x2F;p&gt;
&lt;p&gt;Opening the gate to a kind of communication closer to the user’s needs and the real collaborative Internet we thought to build is litterally a one step process: get root access. Usually if the router is running an open source software, you already have access with your admin password. Once in possession of the router credentials, sky’s the limit… for sysadmins. Of course I don’t expect even tech-savvy users to know how to configure properly so many aspects of a router. Instead we should commission experts to do the configuration for us. For instance knowledgeable friends, CHATONS or associative ISPs, etc.&lt;&#x2F;p&gt;
&lt;p&gt;In a world where boxes are ever more tightly bound to services provided by giant ISPs that don’t provide Internet access only anymore, we have to adapt and think ahead of them. They already provide VoIP and TVoIP services in triple-play offers. That’s of course out of the scope of what an ISP should offer, but that doesn’t mean we shouldn’t care about them either. It’s added value to their customers, and a deterrent to move away from their offers, especially considering their price which is often more competitive. Providing extra features at the router level, we not only catch up with big telcos, we also provide the direct embodiement of what open networks allow.&lt;&#x2F;p&gt;
&lt;p&gt;Plenty of technologies could feel right at home in a router. A networked hard disk connected over USB? It’s usually only available to your LAN, but what if you have a configured SFTP access from the outside? What if you have a configured VPN that allows you to access your LAN wherever you are? What if you have a configured binding of two LAN over a VPN? You would never need remote storage again.&lt;&#x2F;p&gt;
&lt;p&gt;There is the need for a tool that allows easy sharing of these credentials. A tool that would allow such remote access with trusted third parties. A tool that would allow delegation of configuration tasks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;brick-and-mortar&quot;&gt;The brick and mortar of the agora&lt;a class=&quot;zola-anchor&quot; href=&quot;#brick-and-mortar&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Configuration tasks are tedious, even to the experienced user. Hopefully we don’t need to remember every single task - that would be error-prone - and can rely on community-contributed scripts such as ansible playbooks&#x2F;roles to configure tasks and do the necessary checks before changing anything. LXC containers coming to the rescue, we can prevent the added programs from interfering with the essential features of your router.&lt;&#x2F;p&gt;
&lt;p&gt;We need to provide the building blocks for the agora. It’s the next stage to build Internet communities and create more interest in both self-hosting and associative ISPs.&lt;&#x2F;p&gt;
</content:encoded>
            </item>
        
            <item>
                <title>SRLB: a better load balancer than Google&#x27;s MagLev for Linux</title>
                <pubDate>Fri, 22 Dec 2017 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/better-maglev-for-linux/</link>
                <guid>https://rigelk.frama.io/blog/blog/better-maglev-for-linux/</guid>
                <description>&lt;p&gt;SRLB is the effort to bring load-balancing to Segment Routing with IPv6 (SRv6).&lt;&#x2F;p&gt;
&lt;p&gt;Now, why SRv6 in particular and not just regular, IPv4 based Segment Routing? Well, that is because the 128 bits given by the IPv6 address space are so bit we can not only store more addresses but also include other data in it, like addresses to functions for instance.&lt;&#x2F;p&gt;
&lt;p&gt;In the case of SRv6, we call the address to executing machine the &lt;em&gt;Locator&lt;&#x2F;em&gt;, while the function executed is addressed in a &lt;em&gt;Function&lt;&#x2F;em&gt; field.&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;network_programming.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;network_programming.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;network_programming.png&quot; &#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
&lt;&#x2F;div&gt;
&lt;p&gt;Once we have function addressed on the network, the advantage of Segment Routing becomes obvious: we can force data to go through certain segments, hence go through certain functions in chain. Much like in a computer program, network programming suddenly becomes a thing.&lt;&#x2F;p&gt;
&lt;p&gt;Service Function Chaining scenario is now supported by IPv6 Segment Routing. We can consider a Service Chain as an ordered set of Virtual Network Functions (VNFs) and each VNF is represented by its IPv6 address. We assume that VNFs are hosted in “NFV nodes”.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;netgroup.github.io&#x2F;SRv6-net-prog&#x2F;&quot;&gt;&lt;em&gt;srnext&lt;&#x2F;em&gt; module&lt;&#x2F;a&gt; is used in a Linux NFV node in order to support legacy VNFs (i.e. “SR-unaware” VNFs). It was written in march 2017 by the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;netgroup&quot;&gt;netgroup&lt;&#x2F;a&gt;. However it doesn’t support a load-balancing feature similar to Google MagLev.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Maglev is Google’s network load balancer. It is a large distributed software system that runs on commodity Linux servers. Unlike traditional hardware network load balancers, it does not require a specialized physical rack deployment, and its capacity can be easily adjusted by adding or removing servers.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The main issue is that a MagLev machine then matches the packets to their corresponding services and spreads them evenly to the service endpoints. In other words, the machine has to be aware of all service replicas and establish which is busy and which has an acceptable load. It is mostly inefficient since in practice the machine cannot send simultaneous request to all service nodes so as not to flood with requests the services as the number of machines increase.&lt;&#x2F;p&gt;
&lt;p&gt;SRLB leverages Segment Routing features to allow a busy node to forward the request to another node itself. Statistically this proves enough after one hop in most cases&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. Add that to SR policies load-balanced on a weighted basis among the SID lists associated with the selected path of the SR Policy, and you get SFC to function better off commodity Linux servers.&lt;&#x2F;p&gt;
&lt;p&gt;Contrary to MagLev, 6LB requires agents on the NFV endpoints. The agent consists in an out-of-tree module that registers pre and post forwarding functions to craft proper SRv6 packets based on a load estimate of the queried application. If the application is busy, it forwards the packet to the next node chosen beforehand by the load balancer.&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;srlbsa_overview.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;srlbsa_overview.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;srlbsa_overview.png&quot; style=&quot;width: 70%&quot;&#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
&lt;&#x2F;div&gt;&lt;h2 id=&quot;module-architecture&quot;&gt;Module architecture&lt;a class=&quot;zola-anchor&quot; href=&quot;#module-architecture&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;The module registers:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;a pre-routing function&lt;&#x2F;li&gt;
&lt;li&gt;a shared memory segment&lt;&#x2F;li&gt;
&lt;li&gt;a post-routing function&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;Mitzenmacher, M., “The power of two choices in randomized load balancing”, IEEE Transactions on parallel and Distributed Systems, vol. 12, no 10, p. 1094-1104, 2001&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</description>
                <content:encoded>&lt;p&gt;SRLB is the effort to bring load-balancing to Segment Routing with IPv6 (SRv6).&lt;&#x2F;p&gt;
&lt;p&gt;Now, why SRv6 in particular and not just regular, IPv4 based Segment Routing? Well, that is because the 128 bits given by the IPv6 address space are so bit we can not only store more addresses but also include other data in it, like addresses to functions for instance.&lt;&#x2F;p&gt;
&lt;p&gt;In the case of SRv6, we call the address to executing machine the &lt;em&gt;Locator&lt;&#x2F;em&gt;, while the function executed is addressed in a &lt;em&gt;Function&lt;&#x2F;em&gt; field.&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;network_programming.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;network_programming.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;network_programming.png&quot; &#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
&lt;&#x2F;div&gt;
&lt;p&gt;Once we have function addressed on the network, the advantage of Segment Routing becomes obvious: we can force data to go through certain segments, hence go through certain functions in chain. Much like in a computer program, network programming suddenly becomes a thing.&lt;&#x2F;p&gt;
&lt;p&gt;Service Function Chaining scenario is now supported by IPv6 Segment Routing. We can consider a Service Chain as an ordered set of Virtual Network Functions (VNFs) and each VNF is represented by its IPv6 address. We assume that VNFs are hosted in “NFV nodes”.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;netgroup.github.io&#x2F;SRv6-net-prog&#x2F;&quot;&gt;&lt;em&gt;srnext&lt;&#x2F;em&gt; module&lt;&#x2F;a&gt; is used in a Linux NFV node in order to support legacy VNFs (i.e. “SR-unaware” VNFs). It was written in march 2017 by the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;netgroup&quot;&gt;netgroup&lt;&#x2F;a&gt;. However it doesn’t support a load-balancing feature similar to Google MagLev.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Maglev is Google’s network load balancer. It is a large distributed software system that runs on commodity Linux servers. Unlike traditional hardware network load balancers, it does not require a specialized physical rack deployment, and its capacity can be easily adjusted by adding or removing servers.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The main issue is that a MagLev machine then matches the packets to their corresponding services and spreads them evenly to the service endpoints. In other words, the machine has to be aware of all service replicas and establish which is busy and which has an acceptable load. It is mostly inefficient since in practice the machine cannot send simultaneous request to all service nodes so as not to flood with requests the services as the number of machines increase.&lt;&#x2F;p&gt;
&lt;p&gt;SRLB leverages Segment Routing features to allow a busy node to forward the request to another node itself. Statistically this proves enough after one hop in most cases&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. Add that to SR policies load-balanced on a weighted basis among the SID lists associated with the selected path of the SR Policy, and you get SFC to function better off commodity Linux servers.&lt;&#x2F;p&gt;
&lt;p&gt;Contrary to MagLev, 6LB requires agents on the NFV endpoints. The agent consists in an out-of-tree module that registers pre and post forwarding functions to craft proper SRv6 packets based on a load estimate of the queried application. If the application is busy, it forwards the packet to the next node chosen beforehand by the load balancer.&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;srlbsa_overview.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;srlbsa_overview.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;srlbsa_overview.png&quot; style=&quot;width: 70%&quot;&#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
&lt;&#x2F;div&gt;&lt;h2 id=&quot;module-architecture&quot;&gt;Module architecture&lt;a class=&quot;zola-anchor&quot; href=&quot;#module-architecture&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;The module registers:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;a pre-routing function&lt;&#x2F;li&gt;
&lt;li&gt;a shared memory segment&lt;&#x2F;li&gt;
&lt;li&gt;a post-routing function&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;Mitzenmacher, M., “The power of two choices in randomized load balancing”, IEEE Transactions on parallel and Distributed Systems, vol. 12, no 10, p. 1094-1104, 2001&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content:encoded>
            </item>
        
            <item>
                <title>Somebody is WRONG about the Internet</title>
                <pubDate>Thu, 16 Nov 2017 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/somebody-is-wrong-on-the-internet/</link>
                <guid>https://rigelk.frama.io/blog/blog/somebody-is-wrong-on-the-internet/</guid>
                <description>&lt;p&gt;I know this blog is mainly about technical stuff and this isn’t really a technical topic, but a recent event forced me to realise this is a topic I cannot avoid. Somebody is indeed wrong about the Internet.&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;duty_calls.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;duty_calls.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;duty_calls.png&quot; &#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
&lt;&#x2F;div&gt;
&lt;p&gt;More specifically, it’s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.henriverdier.com&#x2F;2017&#x2F;12&#x2F;la-neutralitte-dinternet-bien-public.html?showComment=1514457284012#c3410664237112268487&quot;&gt;this comment&lt;&#x2F;a&gt; that sprung my interest (who said ire?). With net neutrality becoming yet again a hot topic (it’s gonna be repealed, remember…), and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.wired.com&#x2F;story&#x2F;bots-form-letters-humans-fcc-net-neutrality-comments&#x2F;&quot;&gt;bots being used to promote its repeal&lt;&#x2F;a&gt;, a pattern emerges in the opposition to net neutrality lead by ISPs.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;uncertainty-and-doubt&quot;&gt;Uncertainty and Doubt&lt;a class=&quot;zola-anchor&quot; href=&quot;#uncertainty-and-doubt&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Bots and human promoters alike spread the same message, however wrong their argumentation might be. The correctness of the arguments nor the facts they are based on matter anymore. It’s all about being seen, even on small blogs like the one I linked at above. When one comes to read the comments and sees a discording voice, one thinks their is still much to be debated and no clear answer has still emerged. Much like headlines that tell more than their article’s content, they often bias the reader. I’m not advocating for censorship of discording voices, but calling for a more constructed discussion, based on facts and understanding of one’s motive and arguments.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;debate-is-our-friend&quot;&gt;Debate is our friend&lt;a class=&quot;zola-anchor&quot; href=&quot;#debate-is-our-friend&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;They masquerade as commentors but don’t actually feed the debate. By argumenting more and providing clear outlooks of their failing arguments (or lack thereof), we provide an anchor for readers.&lt;&#x2F;p&gt;
&lt;p&gt;Debate is also a nice way to construct your own future material to post. In terms of impact, an article is always more important than a comment. Hence this post.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-is-he-wrong&quot;&gt;Why is he wrong?&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-is-he-wrong&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Nothing personal intended, his comment is just a good summary of ideas that have woefully spread a lot about net neutrality, yet are wrong in every sense. Beware, I’m gonna quote the shit out of my answers.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;companies-have-created-internet&quot;&gt;“Companies have created Internet”&lt;a class=&quot;zola-anchor&quot; href=&quot;#companies-have-created-internet&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Nope.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The history of the Internet begins with the development of electronic computers in the 1950s. Initial concepts of wide area networking originated in several computer science laboratories in the United States, United Kingdom, and France. The US Department of Defense awarded contracts as early as the 1960s, including for the development of the ARPANET project, directed by Robert Taylor and managed by Lawrence Roberts. The first message was sent over the ARPANET in 1969 from computer science Professor Leonard Kleinrock’s laboratory at University of California, Los Angeles (UCLA) to the second network node at Stanford Research Institute (SRI). Donald Davies first demonstrated packet switching in 1967 at the National Physics Laboratory (NPL) in the UK.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Public funding, public research institiutes. But what about TCP&#x2F;IP?&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Internet protocol suite (TCP&#x2F;IP) was developed by Robert E. Kahn and Vint Cerf in the 1970s and became the standard networking protocol on the ARPANET, incorporating concepts from the French CYCLADES project directed by Louis Pouzin. In the early 1980s the NSF funded and finally provided interconnectivity in 1986 with the NSFNET project.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Still public. What about the &lt;em&gt;web&lt;&#x2F;em&gt;?&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;In the 1980s, research at CERN in Switzerland by British computer scientist Tim Berners-Lee resulted in the World Wide Web, linking hypertext documents into an information system, accessible from any node on the network.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Puuuuuublic.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Commercial Internet service providers (ISPs) began to emerge in the very late 1980s. Limited private connections to parts of the Internet by officially commercial entities emerged in several American cities by late 1989 and 1990, and the NSFNET was decommissioned in 1995, removing the last restrictions on the use of the Internet to carry commercial traffic.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;It feels like the ISPs are late to the party. Some would say they are mere laggards.&lt;&#x2F;p&gt;
&lt;p&gt;But maybe you are talking about the network cables? If that is the case, then know that the actual infrastructure was mainly relying on copper connections already dedicated to telephone networks. The connection to the last mile?&lt;&#x2F;p&gt;
&lt;p&gt;Much of that network was built by the state, and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;video.vice.com&#x2F;en_us&#x2F;video&#x2F;motherboard-dear-future-people-building-their-own-internet-detroit&#x2F;59cebd5795073d0905939aeb&quot;&gt;private ISPs don’t always deliver, even in big cities&lt;&#x2F;a&gt;. Again it’s very logical. You only build where you can make profit. Nothing wrong with that. It’s not being anti-companies and anti-state to chose one or the other to build the last-mile network, but the ultimate goal of all this fuss is to have a better network for the masses, not choose based on your political spectrum.&lt;&#x2F;p&gt;
&lt;p&gt;Questions yet to be answered:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;What is the compared cost of 95% coverage in (insert desired bandwidth) for public&#x2F;private deployment.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;net-neutrality-has-never-existed&quot;&gt;“Net Neutrality has never existed”&lt;a class=&quot;zola-anchor&quot; href=&quot;#net-neutrality-has-never-existed&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;iframe src=&#x27;https:&#x2F;&#x2F;cdn.knightlab.com&#x2F;libs&#x2F;timeline&#x2F;latest&#x2F;embed&#x2F;index.html?source=0AgG4fGMfRNdHdDNqak5kV01FTlVZMGFfSDc4SmlvMmc&amp;font=Bevan-PotanoSans&amp;maptype=toner&amp;lang=en&amp;height=650&#x27; width=&#x27;100%&#x27; height=&#x27;650&#x27; frameborder=&#x27;0&#x27;&gt;&lt;&#x2F;iframe&gt;
&lt;p&gt;And even if it has never been lawfully enforced, it still is something important as more and more of our learning, social and political opportunities require it. (more on that below)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;internet-is-broken&quot;&gt;“Internet is broken”&lt;a class=&quot;zola-anchor&quot; href=&quot;#internet-is-broken&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;I know, I know. Internet is broken because our usages have changed and our craving for more videos, more series, more streaming, more torrent and more (insert blame on the user) is killing it.&lt;&#x2F;p&gt;
&lt;p&gt;It is true we use the Internet differently from a few years back, and it will certainly continue to change. Strangely, the blame is always directed towards the user and not the ones that maintain the network. More strange even is the lack of blame for refusing to develop technologies that would have helped adapt. For instance, a lot has been done towards distributed content delivery (BitTorrent and others before), both academically and in public research privately funded. There is interest, but no ISP has been pushing for such technologies. They see the infrastructure as a mere convenience and don’t aim at really improving how it works upstream.&lt;&#x2F;p&gt;
&lt;p&gt;A corollary is the fact some use disproportionately the network compared to others: the main culprits are GAFAMs and globally a business model based on technologies that require client-server applications (central video servers like YouTube), but the point is often used to justify tiered services (you pay per site or pack of sites&#x2F;protocols you want to access). A quick fix would be to use modern technologies (decentralized content delivery, dynamic caching in the network), but even though I’m a strong beliver in solving problems with technology I also trust politics in the use of networks to be able to reach a more precise goal (yes, politics are everywhere, just look at all the deciding boards that govern the standards and the resources of the Internet like addresses and domain names!).&lt;&#x2F;p&gt;
&lt;p&gt;But okay, why not. Let’s assume this is the only way to fix the Internet. Even then, with Internet access like for insurances and social security, you don’t want to make people pay only for what they need because metering the internet is a constantly changing medium (understand, waaaay more than any other) and it is very difficult to meter its usage. Even in peering agreements they meter only the used bandwidth and not the sites visited or the protocols used, because it would be a mess to keep track of ever changing addresses and workarounds. There is no optimisation possible, no invisible hand that will make things converge.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;not-everyone-needs-all-internet&quot;&gt;“Not everyone needs all Internet”&lt;a class=&quot;zola-anchor&quot; href=&quot;#not-everyone-needs-all-internet&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Of course I don’t connect to the entire Internet at once. But what do you need? What do I need? How do you rate the cost of each need? If I invent a new protocol to connect to those sites on the network, how do you rate it? What if I use a VPN?&lt;&#x2F;p&gt;
&lt;p&gt;Is all of that metering really getting to make everyone have a better service? A fairer service?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;some-people-need-a-faster-more-reliable-internet-line&quot;&gt;“Some people need a faster&#x2F;more reliable Internet line…”&lt;a class=&quot;zola-anchor&quot; href=&quot;#some-people-need-a-faster-more-reliable-internet-line&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;And they already pay for it. That’s why we deploy in priority FTTH or redundant copper wires to companies and buildings that need this extra service.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;and-for-that-we-need-to-slow-other-people&quot;&gt;“…and for that we need to slow other people”&lt;a class=&quot;zola-anchor&quot; href=&quot;#and-for-that-we-need-to-slow-other-people&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Don’t fall into this. Link saturation because of home users is not a thing.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;and-look-at-iot-we-need-to-finance-that-fancy-tech&quot;&gt;“…and look at IoT: we need to finance that fancy tech”&lt;a class=&quot;zola-anchor&quot; href=&quot;#and-look-at-iot-we-need-to-finance-that-fancy-tech&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;IoT is mainly a company need financed by corporate clients. Even home users are paying in a way, as 5G eNBs (the base stations) are already supporting most IoT use cases in their specification, and we are gonna pay for them the same way we are paying for the network right now.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;and-reliability-for-chirurigical-operations-in-mobility&quot;&gt;“…and reliability for chirurigical operations in mobility”&lt;a class=&quot;zola-anchor&quot; href=&quot;#and-reliability-for-chirurigical-operations-in-mobility&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Don’t laugh, I’ve already heard a lot of people from Orange say that as a future need that requires heavy investment. It is even told in class to our future network engineers.&lt;&#x2F;p&gt;
&lt;p&gt;Look, there is no need for such things right now or even in ten years. If you take this argument seriously as I do and try to imagine, you can imagine doctors doing consultations remotely from their office (then it is a fiber connection with QoS) or at the very limit a chirurgical operation via 4G (fixed allocation of RBs already exist and are even used for home connections via 3G&#x2F;4G) even though the delay will only become reasonable with 5G (&amp;lt;5ms instead of &amp;lt;100ms in 4G). But then 5G will already be financed by home users, so, you know, QED.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;poor-people-don-t-need-the-luxury-of-all-internet-and-could-pay-less-with-specific-offers&quot;&gt;“Poor people don’t need the luxury of all Internet, and could pay less with specific offers”&lt;a class=&quot;zola-anchor&quot; href=&quot;#poor-people-don-t-need-the-luxury-of-all-internet-and-could-pay-less-with-specific-offers&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;If you want poor people to pay less for internet, you should be looking at political measures to lower the cost altogether or pay them internet access. Either way, you’re trying to implement social services the wrong way by giving a pay per use that is difficult (impossible?) to define: what’s a luxurious usage of Internet? Even more difficult to define: what is the Internet poor people need and how is it using less the network than rich people.&lt;&#x2F;p&gt;
&lt;p&gt;Actually, poor people need the Internet more than rich people. They might use the network more. Why? Maybe because their only way to learn is via MOOCs, videos or online debates. Maybe because it’s their only way to access an otherwise unafordable higher education. Call them lazy not to go to classes or work to pay their school, learning on the Internet is always gonna require multiple sources and formats to adapt each and everyone. It’s also part of the problem with traditional education mediums: having one professor giving &lt;em&gt;his&lt;&#x2F;em&gt; knowledge is a one-way process that is outdated and potentially unefficient. It also calls to a hierarchy that is not needed when one learns on the Internet. On the Internet there are resources and you go fetch them and absord them. You are your own teacher. This comes with disadvantages too. It’s more time-consuming to look for something and summarize for proper assimilation, but when you’re poor, you sometimes don’t have the choice and Internet is your only resource. So you browse a lot of information on various sites, look at videos, just to try to grasp what a rich would have learned in a classes or two at school.&lt;&#x2F;p&gt;
&lt;p&gt;There is a huge social difference, and while I don’t think of Internet as an equalizer by any means, it certainly can increase the social gap caused by wealth gaps.&lt;&#x2F;p&gt;
</description>
                <content:encoded>&lt;p&gt;I know this blog is mainly about technical stuff and this isn’t really a technical topic, but a recent event forced me to realise this is a topic I cannot avoid. Somebody is indeed wrong about the Internet.&lt;&#x2F;p&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;duty_calls.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
      &lt;source srcset=&quot;duty_calls.png&quot; type=&quot;image&#x2F;png&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;duty_calls.png&quot; &#x2F;&gt;
    
    
    
  &lt;&#x2F;picture&gt;

  
&lt;&#x2F;div&gt;
&lt;p&gt;More specifically, it’s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.henriverdier.com&#x2F;2017&#x2F;12&#x2F;la-neutralitte-dinternet-bien-public.html?showComment=1514457284012#c3410664237112268487&quot;&gt;this comment&lt;&#x2F;a&gt; that sprung my interest (who said ire?). With net neutrality becoming yet again a hot topic (it’s gonna be repealed, remember…), and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.wired.com&#x2F;story&#x2F;bots-form-letters-humans-fcc-net-neutrality-comments&#x2F;&quot;&gt;bots being used to promote its repeal&lt;&#x2F;a&gt;, a pattern emerges in the opposition to net neutrality lead by ISPs.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;uncertainty-and-doubt&quot;&gt;Uncertainty and Doubt&lt;a class=&quot;zola-anchor&quot; href=&quot;#uncertainty-and-doubt&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Bots and human promoters alike spread the same message, however wrong their argumentation might be. The correctness of the arguments nor the facts they are based on matter anymore. It’s all about being seen, even on small blogs like the one I linked at above. When one comes to read the comments and sees a discording voice, one thinks their is still much to be debated and no clear answer has still emerged. Much like headlines that tell more than their article’s content, they often bias the reader. I’m not advocating for censorship of discording voices, but calling for a more constructed discussion, based on facts and understanding of one’s motive and arguments.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;debate-is-our-friend&quot;&gt;Debate is our friend&lt;a class=&quot;zola-anchor&quot; href=&quot;#debate-is-our-friend&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;They masquerade as commentors but don’t actually feed the debate. By argumenting more and providing clear outlooks of their failing arguments (or lack thereof), we provide an anchor for readers.&lt;&#x2F;p&gt;
&lt;p&gt;Debate is also a nice way to construct your own future material to post. In terms of impact, an article is always more important than a comment. Hence this post.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-is-he-wrong&quot;&gt;Why is he wrong?&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-is-he-wrong&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Nothing personal intended, his comment is just a good summary of ideas that have woefully spread a lot about net neutrality, yet are wrong in every sense. Beware, I’m gonna quote the shit out of my answers.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;companies-have-created-internet&quot;&gt;“Companies have created Internet”&lt;a class=&quot;zola-anchor&quot; href=&quot;#companies-have-created-internet&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Nope.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The history of the Internet begins with the development of electronic computers in the 1950s. Initial concepts of wide area networking originated in several computer science laboratories in the United States, United Kingdom, and France. The US Department of Defense awarded contracts as early as the 1960s, including for the development of the ARPANET project, directed by Robert Taylor and managed by Lawrence Roberts. The first message was sent over the ARPANET in 1969 from computer science Professor Leonard Kleinrock’s laboratory at University of California, Los Angeles (UCLA) to the second network node at Stanford Research Institute (SRI). Donald Davies first demonstrated packet switching in 1967 at the National Physics Laboratory (NPL) in the UK.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Public funding, public research institiutes. But what about TCP&#x2F;IP?&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Internet protocol suite (TCP&#x2F;IP) was developed by Robert E. Kahn and Vint Cerf in the 1970s and became the standard networking protocol on the ARPANET, incorporating concepts from the French CYCLADES project directed by Louis Pouzin. In the early 1980s the NSF funded and finally provided interconnectivity in 1986 with the NSFNET project.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Still public. What about the &lt;em&gt;web&lt;&#x2F;em&gt;?&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;In the 1980s, research at CERN in Switzerland by British computer scientist Tim Berners-Lee resulted in the World Wide Web, linking hypertext documents into an information system, accessible from any node on the network.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Puuuuuublic.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Commercial Internet service providers (ISPs) began to emerge in the very late 1980s. Limited private connections to parts of the Internet by officially commercial entities emerged in several American cities by late 1989 and 1990, and the NSFNET was decommissioned in 1995, removing the last restrictions on the use of the Internet to carry commercial traffic.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;It feels like the ISPs are late to the party. Some would say they are mere laggards.&lt;&#x2F;p&gt;
&lt;p&gt;But maybe you are talking about the network cables? If that is the case, then know that the actual infrastructure was mainly relying on copper connections already dedicated to telephone networks. The connection to the last mile?&lt;&#x2F;p&gt;
&lt;p&gt;Much of that network was built by the state, and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;video.vice.com&#x2F;en_us&#x2F;video&#x2F;motherboard-dear-future-people-building-their-own-internet-detroit&#x2F;59cebd5795073d0905939aeb&quot;&gt;private ISPs don’t always deliver, even in big cities&lt;&#x2F;a&gt;. Again it’s very logical. You only build where you can make profit. Nothing wrong with that. It’s not being anti-companies and anti-state to chose one or the other to build the last-mile network, but the ultimate goal of all this fuss is to have a better network for the masses, not choose based on your political spectrum.&lt;&#x2F;p&gt;
&lt;p&gt;Questions yet to be answered:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;What is the compared cost of 95% coverage in (insert desired bandwidth) for public&#x2F;private deployment.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;net-neutrality-has-never-existed&quot;&gt;“Net Neutrality has never existed”&lt;a class=&quot;zola-anchor&quot; href=&quot;#net-neutrality-has-never-existed&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;iframe src=&#x27;https:&#x2F;&#x2F;cdn.knightlab.com&#x2F;libs&#x2F;timeline&#x2F;latest&#x2F;embed&#x2F;index.html?source=0AgG4fGMfRNdHdDNqak5kV01FTlVZMGFfSDc4SmlvMmc&amp;font=Bevan-PotanoSans&amp;maptype=toner&amp;lang=en&amp;height=650&#x27; width=&#x27;100%&#x27; height=&#x27;650&#x27; frameborder=&#x27;0&#x27;&gt;&lt;&#x2F;iframe&gt;
&lt;p&gt;And even if it has never been lawfully enforced, it still is something important as more and more of our learning, social and political opportunities require it. (more on that below)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;internet-is-broken&quot;&gt;“Internet is broken”&lt;a class=&quot;zola-anchor&quot; href=&quot;#internet-is-broken&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;I know, I know. Internet is broken because our usages have changed and our craving for more videos, more series, more streaming, more torrent and more (insert blame on the user) is killing it.&lt;&#x2F;p&gt;
&lt;p&gt;It is true we use the Internet differently from a few years back, and it will certainly continue to change. Strangely, the blame is always directed towards the user and not the ones that maintain the network. More strange even is the lack of blame for refusing to develop technologies that would have helped adapt. For instance, a lot has been done towards distributed content delivery (BitTorrent and others before), both academically and in public research privately funded. There is interest, but no ISP has been pushing for such technologies. They see the infrastructure as a mere convenience and don’t aim at really improving how it works upstream.&lt;&#x2F;p&gt;
&lt;p&gt;A corollary is the fact some use disproportionately the network compared to others: the main culprits are GAFAMs and globally a business model based on technologies that require client-server applications (central video servers like YouTube), but the point is often used to justify tiered services (you pay per site or pack of sites&#x2F;protocols you want to access). A quick fix would be to use modern technologies (decentralized content delivery, dynamic caching in the network), but even though I’m a strong beliver in solving problems with technology I also trust politics in the use of networks to be able to reach a more precise goal (yes, politics are everywhere, just look at all the deciding boards that govern the standards and the resources of the Internet like addresses and domain names!).&lt;&#x2F;p&gt;
&lt;p&gt;But okay, why not. Let’s assume this is the only way to fix the Internet. Even then, with Internet access like for insurances and social security, you don’t want to make people pay only for what they need because metering the internet is a constantly changing medium (understand, waaaay more than any other) and it is very difficult to meter its usage. Even in peering agreements they meter only the used bandwidth and not the sites visited or the protocols used, because it would be a mess to keep track of ever changing addresses and workarounds. There is no optimisation possible, no invisible hand that will make things converge.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;not-everyone-needs-all-internet&quot;&gt;“Not everyone needs all Internet”&lt;a class=&quot;zola-anchor&quot; href=&quot;#not-everyone-needs-all-internet&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Of course I don’t connect to the entire Internet at once. But what do you need? What do I need? How do you rate the cost of each need? If I invent a new protocol to connect to those sites on the network, how do you rate it? What if I use a VPN?&lt;&#x2F;p&gt;
&lt;p&gt;Is all of that metering really getting to make everyone have a better service? A fairer service?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;some-people-need-a-faster-more-reliable-internet-line&quot;&gt;“Some people need a faster&#x2F;more reliable Internet line…”&lt;a class=&quot;zola-anchor&quot; href=&quot;#some-people-need-a-faster-more-reliable-internet-line&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;And they already pay for it. That’s why we deploy in priority FTTH or redundant copper wires to companies and buildings that need this extra service.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;and-for-that-we-need-to-slow-other-people&quot;&gt;“…and for that we need to slow other people”&lt;a class=&quot;zola-anchor&quot; href=&quot;#and-for-that-we-need-to-slow-other-people&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Don’t fall into this. Link saturation because of home users is not a thing.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;and-look-at-iot-we-need-to-finance-that-fancy-tech&quot;&gt;“…and look at IoT: we need to finance that fancy tech”&lt;a class=&quot;zola-anchor&quot; href=&quot;#and-look-at-iot-we-need-to-finance-that-fancy-tech&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;IoT is mainly a company need financed by corporate clients. Even home users are paying in a way, as 5G eNBs (the base stations) are already supporting most IoT use cases in their specification, and we are gonna pay for them the same way we are paying for the network right now.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;and-reliability-for-chirurigical-operations-in-mobility&quot;&gt;“…and reliability for chirurigical operations in mobility”&lt;a class=&quot;zola-anchor&quot; href=&quot;#and-reliability-for-chirurigical-operations-in-mobility&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Don’t laugh, I’ve already heard a lot of people from Orange say that as a future need that requires heavy investment. It is even told in class to our future network engineers.&lt;&#x2F;p&gt;
&lt;p&gt;Look, there is no need for such things right now or even in ten years. If you take this argument seriously as I do and try to imagine, you can imagine doctors doing consultations remotely from their office (then it is a fiber connection with QoS) or at the very limit a chirurgical operation via 4G (fixed allocation of RBs already exist and are even used for home connections via 3G&#x2F;4G) even though the delay will only become reasonable with 5G (&amp;lt;5ms instead of &amp;lt;100ms in 4G). But then 5G will already be financed by home users, so, you know, QED.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;poor-people-don-t-need-the-luxury-of-all-internet-and-could-pay-less-with-specific-offers&quot;&gt;“Poor people don’t need the luxury of all Internet, and could pay less with specific offers”&lt;a class=&quot;zola-anchor&quot; href=&quot;#poor-people-don-t-need-the-luxury-of-all-internet-and-could-pay-less-with-specific-offers&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;If you want poor people to pay less for internet, you should be looking at political measures to lower the cost altogether or pay them internet access. Either way, you’re trying to implement social services the wrong way by giving a pay per use that is difficult (impossible?) to define: what’s a luxurious usage of Internet? Even more difficult to define: what is the Internet poor people need and how is it using less the network than rich people.&lt;&#x2F;p&gt;
&lt;p&gt;Actually, poor people need the Internet more than rich people. They might use the network more. Why? Maybe because their only way to learn is via MOOCs, videos or online debates. Maybe because it’s their only way to access an otherwise unafordable higher education. Call them lazy not to go to classes or work to pay their school, learning on the Internet is always gonna require multiple sources and formats to adapt each and everyone. It’s also part of the problem with traditional education mediums: having one professor giving &lt;em&gt;his&lt;&#x2F;em&gt; knowledge is a one-way process that is outdated and potentially unefficient. It also calls to a hierarchy that is not needed when one learns on the Internet. On the Internet there are resources and you go fetch them and absord them. You are your own teacher. This comes with disadvantages too. It’s more time-consuming to look for something and summarize for proper assimilation, but when you’re poor, you sometimes don’t have the choice and Internet is your only resource. So you browse a lot of information on various sites, look at videos, just to try to grasp what a rich would have learned in a classes or two at school.&lt;&#x2F;p&gt;
&lt;p&gt;There is a huge social difference, and while I don’t think of Internet as an equalizer by any means, it certainly can increase the social gap caused by wealth gaps.&lt;&#x2F;p&gt;
</content:encoded>
            </item>
        
            <item>
                <title>Going further with my server and securing docker</title>
                <pubDate>Wed, 15 Nov 2017 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/going-further-securing-docker/</link>
                <guid>https://rigelk.frama.io/blog/blog/going-further-securing-docker/</guid>
                <description>&lt;p&gt;You might want to jump to the part dedicated to securing docker, the first part being only a review of my VPS’s new setup.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;standing-after-the-crash&quot;&gt;Standing after the crash&lt;a class=&quot;zola-anchor&quot; href=&quot;#standing-after-the-crash&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Previous rebuilds of my VPS were due to misconfigurations of my ssh servers, errors that can be easily avoided. I learned to do application back-ups. But when the disk of my server crashed last month, I had enough of rebuilding everything by hand and decided to store my configuration and automate it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;stateful-configuration-with-ansible&quot;&gt;Stateful configuration with Ansible&lt;a class=&quot;zola-anchor&quot; href=&quot;#stateful-configuration-with-ansible&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Having to place each configuration file, install each app by hand in a terminal to my VPS is a long and cubbersome task. Ansible helped a lot by automating everything in the sanest manner: it handles the ssh connection to potentially many servers and guarantees tasks gets executed with stateful results. It forces me to write tasks dedicated to copy the configuration files, tasks dedicated to command lines I would otherwise do manually, but it does so in an organised manner and provides state information. This way you can lanuch all the tasks in one ansible command and be sure your server is ready.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yaml&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-yaml &quot;&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;span&gt;---
&lt;&#x2F;span&gt;&lt;span&gt;- &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;hosts&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;nebuleuse &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# a group of computers I want to target with the tasks below
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;roles&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;role&lt;&#x2F;span&gt;&lt;span&gt;: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;geerlingguy.security&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;role&lt;&#x2F;span&gt;&lt;span&gt;: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;rigelk.minimal-packages&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;role&lt;&#x2F;span&gt;&lt;span&gt;: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;rigelk.create-new-user&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;role&lt;&#x2F;span&gt;&lt;span&gt;: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;rigelk.vimrc&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;role&lt;&#x2F;span&gt;&lt;span&gt;: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;mikegleasonjr.firewall&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;role&lt;&#x2F;span&gt;&lt;span&gt;: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;rigelk.docker&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;role&lt;&#x2F;span&gt;&lt;span&gt;: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;franklinkim.docker-compose&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;role&lt;&#x2F;span&gt;&lt;span&gt;: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;rigelk.compose&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The last task, &lt;code&gt;rigelk.compose&lt;&#x2F;code&gt; spawns a simple command (I don’t use the Ansible module to keep it easily modifyable for now): &lt;code&gt;docker-compose up -d&lt;&#x2F;code&gt;. It launches containers for most of the apps I use on my container. Of course it is a shortcut compared to installing everything bare metal (even through Ansible).&lt;&#x2F;p&gt;
&lt;p&gt;But it also gives a way to keep track of configuration in an ordered mannen. Plus, multiple roles have already been written by the community around Ansible-Galaxy. It doesn’t solve every problem but it sure gives a basis to solve yours.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;docker-compose-for-now&quot;&gt;Docker-compose for now&lt;a class=&quot;zola-anchor&quot; href=&quot;#docker-compose-for-now&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;For now. There seems to be &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;veggiemonk&#x2F;awesome-docker&quot;&gt;quite a number of ways&lt;&#x2F;a&gt; to launch docker containers at scale. Docker-compose is the one for local scale (local orchestration), and since I only have one target server for now, &lt;code&gt;docker-compose&lt;&#x2F;code&gt;, version 2 is enough for my use. Version 3 seems to be the official way to scale to other machines, but the again I can look at more sophisticated tools like Rancher or Mesos+Kubernetes.&lt;&#x2F;p&gt;
&lt;p&gt;The big advantage of &lt;code&gt;docker-compose&lt;&#x2F;code&gt; is the possibility to launch multiple services at once, in a manner that interconnects well. It has the big advantage of containers to be set apart from interering with the system, with the addition of possible links between containers.&lt;&#x2F;p&gt;
&lt;p&gt;Here I show an excerpt of an application behind a reverse proxy that handles certificate generation and TLS security settings in one place. It is especially important since you cannot start by rewriting maintaining each and every container to support both certificate generation and follow the latest cipher suites preferences. With one reverse-proxy handling that (here the docker-aware traefik), I manage the security parameters in one place (sepecifically, in the traefik.toml file).&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yml&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-yml &quot;&gt;&lt;code class=&quot;language-yml&quot; data-lang=&quot;yml&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;version&lt;&#x2F;span&gt;&lt;span&gt;: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;services&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;proxy&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;image&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ports&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;80:80&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;443:443&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;8080:8080&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;volumes&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;docker&#x2F;traefik&#x2F;traefik.toml:&#x2F;etc&#x2F;traefik&#x2F;traefik.toml&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;docker&#x2F;traefik&#x2F;acme:&#x2F;etc&#x2F;traefik&#x2F;acme&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;var&#x2F;run&#x2F;docker.sock:&#x2F;var&#x2F;run&#x2F;docker.sock
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;restart&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;unless-stopped
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;labels&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik.frontend.rule=Host:a.example.net&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik.port=8080&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik.backend=traefik&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik.frontend.entryPoints=http,https&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;networks&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik-portainer
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;portainer&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;image&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;portainer&#x2F;portainer
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;volumes&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;var&#x2F;run&#x2F;docker.sock:&#x2F;var&#x2F;run&#x2F;docker.sock&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;restart&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;unless-stopped
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;labels&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik.frontend.rule=Host:b.example.net&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik.port=9000&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik.backend=portainer&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik.frontend.entryPoints=http,https&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;networks&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik-portainer
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;security-measures-for-the-shipyard&quot;&gt;Security measures for the shipyard&lt;a class=&quot;zola-anchor&quot; href=&quot;#security-measures-for-the-shipyard&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;With the above containers technology (Docker), applications are compartimented and set appart from each other, but would they be compromised they often suffer from inferior conception of the docker images: processes that run root inside the container most of the time. Then a compromised docker image can both write on mounted volumes and use its network access, or try to escape containerization and compromise the docker service itself. Resulting counter-measures:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;(long term) rewrite images so that they use non-root processes&lt;&#x2F;li&gt;
&lt;li&gt;(short term) run the docker service as an unpriviledged user&lt;&#x2F;li&gt;
&lt;li&gt;(short term) run the docker images in separate networks (with &lt;code&gt;docker network create&lt;&#x2F;code&gt;) that you only share between applications of the same stack&lt;&#x2F;li&gt;
&lt;li&gt;(long term) run the docker images with tailored AppArmor profiles (to protect mounted volumes)&lt;&#x2F;li&gt;
&lt;li&gt;(long term) run the docker images with tailored seccomp profiles (to protect system calls)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;a-network-for-each-software-stack&quot;&gt;A network for each software stack&lt;a class=&quot;zola-anchor&quot; href=&quot;#a-network-for-each-software-stack&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;That’s probably the easiest one. You just need to create one per minimal working set of containers that need each other. They do not require to be contiguous, and can perfectly cross, as shown in the docker documentation:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;going-further-securing-docker&#x2F;working.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Bear in mind that there are two ways to declare networks in the v2+ docker-compose file:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yml&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-yml &quot;&gt;&lt;code class=&quot;language-yml&quot; data-lang=&quot;yml&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;networks&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;frontend&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Use a custom driver
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;driver&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;custom-driver-1
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;yml&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-yml &quot;&gt;&lt;code class=&quot;language-yml&quot; data-lang=&quot;yml&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;networks&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;default&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;external&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;my-pre-existing-network
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The former generates the network if it doesn’t exist, and the latter only connects to pre-existing networks.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;apparmor-seccomp-security&quot;&gt;AppArmor&#x2F;SecComp security&lt;a class=&quot;zola-anchor&quot; href=&quot;#apparmor-seccomp-security&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Both AppArmor and SecComp require to be loaded at boot by your kernel. It means that if you likely will have to reboot. So beware to interrupt services for maintenance, and pre-emptively check on a local VM. But we always do that before pushing to production, right?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;AppArmor&lt;&#x2F;em&gt; profiles can be somehow dreadful to write and understand. Hopefully there exists multiple projects that aim at simplifying the way to write them. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jessfraz&#x2F;bane&quot;&gt;Bane&lt;&#x2F;a&gt; is one such project, which generates AppArmor profiles based on simple templates that you can manually write and test with its application with proper feedback.&lt;&#x2F;p&gt;
</description>
                <content:encoded>&lt;p&gt;You might want to jump to the part dedicated to securing docker, the first part being only a review of my VPS’s new setup.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;standing-after-the-crash&quot;&gt;Standing after the crash&lt;a class=&quot;zola-anchor&quot; href=&quot;#standing-after-the-crash&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Previous rebuilds of my VPS were due to misconfigurations of my ssh servers, errors that can be easily avoided. I learned to do application back-ups. But when the disk of my server crashed last month, I had enough of rebuilding everything by hand and decided to store my configuration and automate it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;stateful-configuration-with-ansible&quot;&gt;Stateful configuration with Ansible&lt;a class=&quot;zola-anchor&quot; href=&quot;#stateful-configuration-with-ansible&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Having to place each configuration file, install each app by hand in a terminal to my VPS is a long and cubbersome task. Ansible helped a lot by automating everything in the sanest manner: it handles the ssh connection to potentially many servers and guarantees tasks gets executed with stateful results. It forces me to write tasks dedicated to copy the configuration files, tasks dedicated to command lines I would otherwise do manually, but it does so in an organised manner and provides state information. This way you can lanuch all the tasks in one ansible command and be sure your server is ready.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yaml&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-yaml &quot;&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;span&gt;---
&lt;&#x2F;span&gt;&lt;span&gt;- &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;hosts&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;nebuleuse &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# a group of computers I want to target with the tasks below
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;roles&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;role&lt;&#x2F;span&gt;&lt;span&gt;: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;geerlingguy.security&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;role&lt;&#x2F;span&gt;&lt;span&gt;: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;rigelk.minimal-packages&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;role&lt;&#x2F;span&gt;&lt;span&gt;: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;rigelk.create-new-user&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;role&lt;&#x2F;span&gt;&lt;span&gt;: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;rigelk.vimrc&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;role&lt;&#x2F;span&gt;&lt;span&gt;: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;mikegleasonjr.firewall&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;role&lt;&#x2F;span&gt;&lt;span&gt;: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;rigelk.docker&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;role&lt;&#x2F;span&gt;&lt;span&gt;: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;franklinkim.docker-compose&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;role&lt;&#x2F;span&gt;&lt;span&gt;: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;rigelk.compose&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The last task, &lt;code&gt;rigelk.compose&lt;&#x2F;code&gt; spawns a simple command (I don’t use the Ansible module to keep it easily modifyable for now): &lt;code&gt;docker-compose up -d&lt;&#x2F;code&gt;. It launches containers for most of the apps I use on my container. Of course it is a shortcut compared to installing everything bare metal (even through Ansible).&lt;&#x2F;p&gt;
&lt;p&gt;But it also gives a way to keep track of configuration in an ordered mannen. Plus, multiple roles have already been written by the community around Ansible-Galaxy. It doesn’t solve every problem but it sure gives a basis to solve yours.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;docker-compose-for-now&quot;&gt;Docker-compose for now&lt;a class=&quot;zola-anchor&quot; href=&quot;#docker-compose-for-now&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;For now. There seems to be &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;veggiemonk&#x2F;awesome-docker&quot;&gt;quite a number of ways&lt;&#x2F;a&gt; to launch docker containers at scale. Docker-compose is the one for local scale (local orchestration), and since I only have one target server for now, &lt;code&gt;docker-compose&lt;&#x2F;code&gt;, version 2 is enough for my use. Version 3 seems to be the official way to scale to other machines, but the again I can look at more sophisticated tools like Rancher or Mesos+Kubernetes.&lt;&#x2F;p&gt;
&lt;p&gt;The big advantage of &lt;code&gt;docker-compose&lt;&#x2F;code&gt; is the possibility to launch multiple services at once, in a manner that interconnects well. It has the big advantage of containers to be set apart from interering with the system, with the addition of possible links between containers.&lt;&#x2F;p&gt;
&lt;p&gt;Here I show an excerpt of an application behind a reverse proxy that handles certificate generation and TLS security settings in one place. It is especially important since you cannot start by rewriting maintaining each and every container to support both certificate generation and follow the latest cipher suites preferences. With one reverse-proxy handling that (here the docker-aware traefik), I manage the security parameters in one place (sepecifically, in the traefik.toml file).&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yml&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-yml &quot;&gt;&lt;code class=&quot;language-yml&quot; data-lang=&quot;yml&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;version&lt;&#x2F;span&gt;&lt;span&gt;: &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;services&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;proxy&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;image&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ports&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;80:80&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;443:443&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;8080:8080&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;volumes&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;docker&#x2F;traefik&#x2F;traefik.toml:&#x2F;etc&#x2F;traefik&#x2F;traefik.toml&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;docker&#x2F;traefik&#x2F;acme:&#x2F;etc&#x2F;traefik&#x2F;acme&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;var&#x2F;run&#x2F;docker.sock:&#x2F;var&#x2F;run&#x2F;docker.sock
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;restart&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;unless-stopped
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;labels&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik.frontend.rule=Host:a.example.net&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik.port=8080&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik.backend=traefik&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik.frontend.entryPoints=http,https&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;networks&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik-portainer
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;portainer&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;image&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;portainer&#x2F;portainer
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;volumes&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;var&#x2F;run&#x2F;docker.sock:&#x2F;var&#x2F;run&#x2F;docker.sock&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;restart&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;unless-stopped
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;labels&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik.frontend.rule=Host:b.example.net&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik.port=9000&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik.backend=portainer&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;      - &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik.frontend.entryPoints=http,https&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;networks&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;traefik-portainer
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;security-measures-for-the-shipyard&quot;&gt;Security measures for the shipyard&lt;a class=&quot;zola-anchor&quot; href=&quot;#security-measures-for-the-shipyard&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;With the above containers technology (Docker), applications are compartimented and set appart from each other, but would they be compromised they often suffer from inferior conception of the docker images: processes that run root inside the container most of the time. Then a compromised docker image can both write on mounted volumes and use its network access, or try to escape containerization and compromise the docker service itself. Resulting counter-measures:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;(long term) rewrite images so that they use non-root processes&lt;&#x2F;li&gt;
&lt;li&gt;(short term) run the docker service as an unpriviledged user&lt;&#x2F;li&gt;
&lt;li&gt;(short term) run the docker images in separate networks (with &lt;code&gt;docker network create&lt;&#x2F;code&gt;) that you only share between applications of the same stack&lt;&#x2F;li&gt;
&lt;li&gt;(long term) run the docker images with tailored AppArmor profiles (to protect mounted volumes)&lt;&#x2F;li&gt;
&lt;li&gt;(long term) run the docker images with tailored seccomp profiles (to protect system calls)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;a-network-for-each-software-stack&quot;&gt;A network for each software stack&lt;a class=&quot;zola-anchor&quot; href=&quot;#a-network-for-each-software-stack&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;That’s probably the easiest one. You just need to create one per minimal working set of containers that need each other. They do not require to be contiguous, and can perfectly cross, as shown in the docker documentation:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;going-further-securing-docker&#x2F;working.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Bear in mind that there are two ways to declare networks in the v2+ docker-compose file:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yml&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-yml &quot;&gt;&lt;code class=&quot;language-yml&quot; data-lang=&quot;yml&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;networks&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;frontend&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Use a custom driver
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;driver&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;custom-driver-1
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;yml&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-yml &quot;&gt;&lt;code class=&quot;language-yml&quot; data-lang=&quot;yml&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;networks&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;default&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;external&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;my-pre-existing-network
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The former generates the network if it doesn’t exist, and the latter only connects to pre-existing networks.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;apparmor-seccomp-security&quot;&gt;AppArmor&#x2F;SecComp security&lt;a class=&quot;zola-anchor&quot; href=&quot;#apparmor-seccomp-security&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Both AppArmor and SecComp require to be loaded at boot by your kernel. It means that if you likely will have to reboot. So beware to interrupt services for maintenance, and pre-emptively check on a local VM. But we always do that before pushing to production, right?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;AppArmor&lt;&#x2F;em&gt; profiles can be somehow dreadful to write and understand. Hopefully there exists multiple projects that aim at simplifying the way to write them. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jessfraz&#x2F;bane&quot;&gt;Bane&lt;&#x2F;a&gt; is one such project, which generates AppArmor profiles based on simple templates that you can manually write and test with its application with proper feedback.&lt;&#x2F;p&gt;
</content:encoded>
            </item>
        
            <item>
                <title>Optimizing a Grav installation</title>
                <pubDate>Thu, 31 Aug 2017 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/optimizing-a-grav-installation/</link>
                <guid>https://rigelk.frama.io/blog/blog/optimizing-a-grav-installation/</guid>
                <description>&lt;p&gt;This following stands as my correction&#x2F;update of the awesome article written by &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;olevik.me&#x2F;writing&#x2F;code&#x2F;optimizing-a-grav-installation&quot;&gt;Ole Vik&lt;&#x2F;a&gt;. Kudos to him! I have mainly replaced code snippets and added instructions for Brunch, as some code wasn’t working (like the UnCSS wget prerequisite).&lt;&#x2F;p&gt;
&lt;p&gt;When the term “Web 2.0” became popular after 2004, the focus was largely on design, usability, and new media. In the past few years, however, web development has focused a lot on more on speed and performance, as well as delivery of media across varied devices.&lt;&#x2F;p&gt;
&lt;p&gt;This is largely because websites have become &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.websiteoptimization.com&#x2F;speed&#x2F;tweak&#x2F;average-web-page&#x2F;&quot;&gt;much heavier&lt;&#x2F;a&gt; since the 1990s, as websites have adopted new media and devices – including interactive elements, streaming video, audio, live data, and all else that we’re used to seeing on modern sites and apps these days. Images &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20170822010816&#x2F;http:&#x2F;&#x2F;www.webperformancetoday.com&#x2F;2013&#x2F;06&#x2F;05&#x2F;web-page-growth-2010-2013&#x2F;&quot;&gt;make up the bulk of this&lt;&#x2F;a&gt;, and thus deserve special consideration. In this post I will outline some strategies for optimizing assets in a theme in Grav, and illustrate what results they bring. If you are only interested in the results, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gtmetrix.com&#x2F;reports&#x2F;olevik.me&#x2F;v7KYmpIn&quot;&gt;look here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;preamble&quot;&gt;Preamble&lt;a class=&quot;zola-anchor&quot; href=&quot;#preamble&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;I’ve been using the static-site generator Jekyll for my personal website since 2016, previously WordPress and shortly Grav, but in 2017 I wanted to return to Grav. The reason for this was mainly the Liquid templating-engine that Jekyll uses, which requires a lot of workarounds for fairly basic tasks. Before I started with Jekyll I considered the plethora of static generators available, and have continuously evaluated them since. At the time this was the simpler choice. It also has the largest community of developers and resources online.&lt;&#x2F;p&gt;
&lt;p&gt;When re-evaluating the available options in 2017, I wanted a framework rather than bootstrapping the build-process together myself, and the only real static-site generator alternative to Jekyll was &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.metalsmith.io&#x2F;&quot;&gt;Metalsmith&lt;&#x2F;a&gt; in terms of maturity. However, the setup was unnecessarily complex yet limited, in that rather than simply handling Markdown-content and templating with a decent language like Twig, Nunjucks, or Jinja, a lot of declarations was necessary to accommodate the build-process I’ve used with Jekyll.&lt;&#x2F;p&gt;
&lt;p&gt;This build-process is based on using Gulp for optimizing assets and handles everything surrounding the site, thus relying on compiling content into templates. This was relatively easy with Jekyll, wherein the build is run with the simple execution of a command, and I wanted to maintain this simplicity going forward.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;automating-workflows&quot;&gt;Automating Workflows&lt;a class=&quot;zola-anchor&quot; href=&quot;#automating-workflows&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;I run &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;gulpjs.com&#x2F;&quot;&gt;Gulp&lt;&#x2F;a&gt; as a task-runner with Node. It builds asset in the nicest way possible. The build-process can be defined by these main steps in the gulpfile.js:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Build stylesheets using SCSS&lt;&#x2F;li&gt;
&lt;li&gt;&lt;del&gt;Build a static copy of the site using Wget&lt;&#x2F;del&gt; Serve the site with a local PHP7 spawnable server&lt;&#x2F;li&gt;
&lt;li&gt;Clean the CSS using UnCSS over the previous server&lt;&#x2F;li&gt;
&lt;li&gt;Minify the CSS&lt;&#x2F;li&gt;
&lt;li&gt;Losslessly minify images&lt;&#x2F;li&gt;
&lt;li&gt;Use Grav’s Asset Manager for pipelining or inlining JS&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Grav’s Asset Manager replaces most of Gulp traditional tasks in a useful way, making your Gulp workflow pretty simple: no copying, merging, moving, naming and versioning of assets is needed anymore on the Gulp side. Grav could of course also concatenate CSS-files, but Sass already handles that quite well.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;compiling-sass-scss&quot;&gt;Compiling Sass&#x2F;SCSS&lt;a class=&quot;zola-anchor&quot; href=&quot;#compiling-sass-scss&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;The stylesheets are &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;thesassway.com&#x2F;beginner&#x2F;how-to-structure-a-sass-project&quot;&gt;structured&lt;&#x2F;a&gt; with one principal file, which everything else compiles from; &lt;code&gt;app.scss&lt;&#x2F;code&gt;. Vendor-libraries are handled with &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;yarnpkg.com&#x2F;&quot;&gt;Yarn&lt;&#x2F;a&gt; (a better npm).&lt;&#x2F;p&gt;
&lt;p&gt;Things to note in regards to Sass is the most recent alpha-version of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;v4-alpha.getbootstrap.com&#x2F;&quot;&gt;Bootstrap V4&lt;&#x2F;a&gt;, as well as &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;compass-style.org&#x2F;&quot;&gt;Compass&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoboucas&#x2F;include-media&quot;&gt;include-media&lt;&#x2F;a&gt;, and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.modularscale.com&#x2F;&quot;&gt;Modular Scale&lt;&#x2F;a&gt;. These are all excellent libraries for simplifying the structure and styling of CSS, by using cross-browser standards and elegant helper-functions. The Gulp-libraries are for compiling the Sass and minifying assets. Notably, Autoprefixer for excellent cross-browser compatible CSS-declarations, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cssnano.co&#x2F;&quot;&gt;CSSNano&lt;&#x2F;a&gt; for &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;goalsmashers.github.io&#x2F;css-minification-benchmark&#x2F;&quot;&gt;optimal&lt;&#x2F;a&gt;-minification, and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;giakki&#x2F;uncss&quot;&gt;UnCSS&lt;&#x2F;a&gt; for aggressive CSS-removal.&lt;&#x2F;p&gt;
&lt;p&gt;Where possible I avoid superfluous HTTP requests, for example when including images. If the image is fairly small, I &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;varvy.com&#x2F;pagespeed&#x2F;base64-images.html&quot;&gt;base64-encode&lt;&#x2F;a&gt; it to obtain a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;css-tricks.com&#x2F;data-uris&#x2F;&quot;&gt;data-URI&lt;&#x2F;a&gt; that can be placed directly in the CSS.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;cleaning-the-css&quot;&gt;Cleaning the CSS&lt;a class=&quot;zola-anchor&quot; href=&quot;#cleaning-the-css&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;UnCSS is particularly important here. This tool examines all used CSS-selectors from a set of files and &lt;strong&gt;removes all selectors not in use&lt;&#x2F;strong&gt;. You might think this sounds error-prone and unnecessary, but used intelligently it’s the most efficient reduction of a CSS-file possible. The reason for this is two-fold: Only explicitly needed selectors are kept and when something is left out, you can tell UnCSS to ignore a selector to keep it in. This is necessary for certain onclick-effects and the like. Since Grav compiles dynamic PHP-files with its cache, I use UnCSS’s ability to look up a local service url and point it to the previously launched php server:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;Javascript&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-Javascript &quot;&gt;&lt;code class=&quot;language-Javascript&quot; data-lang=&quot;Javascript&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;gulp&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;task&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;sass&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;var &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;plugins &lt;&#x2F;span&gt;&lt;span&gt;= [
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;autoprefixer&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;)({
&lt;&#x2F;span&gt;&lt;span&gt;        browsers: [&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;last 2 versions&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;,&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;gt; 2%&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;]
&lt;&#x2F;span&gt;&lt;span&gt;      }),
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;uncss&lt;&#x2F;span&gt;&lt;span&gt;({
&lt;&#x2F;span&gt;&lt;span&gt;        html: [&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;http:&#x2F;&#x2F;127.0.0.1:8001&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;,&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;http:&#x2F;&#x2F;127.0.0.1:8001&#x2F;contact&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;],
&lt;&#x2F;span&gt;&lt;span&gt;        ignore: [&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;.hide&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;,&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;.dropdown&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;,&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;.kubeanimated&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;,&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;slideDown&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;]
&lt;&#x2F;span&gt;&lt;span&gt;      })
&lt;&#x2F;span&gt;&lt;span&gt;    ];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;gulp&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;src&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;css&#x2F;master.scss&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;)
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;pipe&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sass&lt;&#x2F;span&gt;&lt;span&gt;())
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;pipe&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;postcss&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;plugins&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt; 		.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;pipe&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;minify&lt;&#x2F;span&gt;&lt;span&gt;())
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;pipe&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rename&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;master.css&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;))
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;pipe&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;gulp&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;dest&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;css&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;));
&lt;&#x2F;span&gt;&lt;span&gt;});
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The problem with UnCSS is to ensure that needed selectors are not removed, pages must be tested and UnCSS’s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;giakki&#x2F;uncss&quot;&gt;ignore-parameter&lt;&#x2F;a&gt; optimized. I’d use &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;visualregressiontesting.com&#x2F;&quot;&gt;Visual Regression Testing&lt;&#x2F;a&gt; if the site was large or complex enough to warrant it.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;asset-manager&quot;&gt;Asset Manager&lt;a class=&quot;zola-anchor&quot; href=&quot;#asset-manager&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;To avoid render-blocking CSS I use &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;filamentgroup&#x2F;loadCSS&quot;&gt;loadCSS&lt;&#x2F;a&gt;, which loads these assets only after HTML in the DOM has finished rendering. Simply put, it applies an onload-attribute for &lt;code&gt;&amp;lt;link&amp;gt;&lt;&#x2F;code&gt;-tags that enables the stylesheet. The loadCSS-library is basically a polyfill for this behavior, which in this case enables deferred loading of &lt;code&gt;app.css&lt;&#x2F;code&gt;. In Twig, I have implemented it this way:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;{% do assets.addJs(&amp;#39;theme:&#x2F;&#x2F;js&#x2F;loadCSS.min.js&amp;#39;, {&amp;#39;loading&amp;#39;: &amp;#39;inline&amp;#39;, &amp;#39;group&amp;#39;: &amp;#39;critical&amp;#39;}) %}
&lt;&#x2F;span&gt;&lt;span&gt;{% do assets.addJs(&amp;#39;theme:&#x2F;&#x2F;js&#x2F;cssrelpreload.min.js&amp;#39;, {&amp;#39;loading&amp;#39;: &amp;#39;inline&amp;#39;, &amp;#39;group&amp;#39;: &amp;#39;critical&amp;#39;}) %}
&lt;&#x2F;span&gt;&lt;span&gt;{{ assets.js(&amp;#39;critical&amp;#39;) }}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;{% block stylesheets %}
&lt;&#x2F;span&gt;&lt;span&gt;  {% do assets.addCSS(&amp;#39;theme:&#x2F;&#x2F;css&#x2F;app.css&amp;#39;, {&amp;#39;group&amp;#39;:&amp;#39;preload&amp;#39;}) %}
&lt;&#x2F;span&gt;&lt;span&gt;  &amp;lt;noscript&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;{{ url(&amp;#39;theme:&#x2F;&#x2F;css&#x2F;app.css&amp;#39;) }}&amp;quot;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &amp;lt;&#x2F;noscript&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;{% endblock %}
&lt;&#x2F;span&gt;&lt;span&gt;{{ assets.css(&amp;#39;preload&amp;#39;, {&amp;#39;rel&amp;#39;: &amp;#39;preload&amp;#39;, &amp;#39;as&amp;#39;: &amp;#39;style&amp;#39;, &amp;#39;onload&amp;#39;: &amp;quot;this.rel=&amp;#39;stylesheet&amp;#39;&amp;quot;}) }}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Specifically, the “critical” JS-group inlines loadCSS before all else in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;&#x2F;code&gt;-tag. Next, the main stylesheet and fonts are loaded in a deferred-manner. Note that both of these stylesheets are single files, which reduces HTTP requests. I also include the standard &lt;code&gt;&amp;lt;noscript&amp;gt;&lt;&#x2F;code&gt;-tag to accommodate outdated browsers, or where JS is disabled. Before closing the &lt;code&gt;&amp;lt;body&amp;gt;&lt;&#x2F;code&gt;-tag I am including &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;highlightjs.org&#x2F;&quot;&gt;highlight.js&lt;&#x2F;a&gt; for code-highlighting:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;{% block scripts_end %}
&lt;&#x2F;span&gt;&lt;span&gt;  {% if page.header.highlight.enabled %}
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;lt;script 
&lt;&#x2F;span&gt;&lt;span&gt;      type=&amp;quot;text&#x2F;javascript&amp;quot; 
&lt;&#x2F;span&gt;&lt;span&gt;      defer 
&lt;&#x2F;span&gt;&lt;span&gt;      src=&amp;quot;{{ url(&amp;#39;theme:&#x2F;&#x2F;js&#x2F;highlight.pack.js&amp;#39;) }}&amp;quot; 
&lt;&#x2F;span&gt;&lt;span&gt;      onload=&amp;quot;hljs.initHighlightingOnLoad();&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;gt;&amp;lt;&#x2F;script&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;  {% endif %}
&lt;&#x2F;span&gt;&lt;span&gt;  {% if page.header.highlight.lines %}
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;lt;script 
&lt;&#x2F;span&gt;&lt;span&gt;      type=&amp;quot;text&#x2F;javascript&amp;quot; 
&lt;&#x2F;span&gt;&lt;span&gt;      defer 
&lt;&#x2F;span&gt;&lt;span&gt;      src=&amp;quot;{{ url(&amp;#39;theme:&#x2F;&#x2F;js&#x2F;highlightjs-line-numbers.min.js&amp;#39;) }}&amp;quot; 
&lt;&#x2F;span&gt;&lt;span&gt;      onload=&amp;quot;hljs.initLineNumbersOnLoad();&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;gt;&amp;lt;&#x2F;script&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;  {% endif %}
&lt;&#x2F;span&gt;&lt;span&gt;{% endblock %}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The same strategy is applied here: Defer loading the asset, and instantiate it onload.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;optimizing-the-server&quot;&gt;Optimizing the server&lt;a class=&quot;zola-anchor&quot; href=&quot;#optimizing-the-server&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;I use PHP 7 for both development and production as it performs significantly &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.zend.com&#x2F;en&#x2F;resources&#x2F;php7_infographic&quot;&gt;better&lt;&#x2F;a&gt; than previous versions. The server I host on also supports Gzip-compression, and I set &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;varvy.com&#x2F;pagespeed&#x2F;leverage-browser-caching.html&quot;&gt;Expires-headers&lt;&#x2F;a&gt; to avoid having the browser load files unnecessarily.&lt;&#x2F;p&gt;
&lt;p&gt;You may want a host machine pretty much the same system as a $10&#x2F;month VPS – and these technicalities &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;learn.getgrav.org&#x2F;advanced&#x2F;performance-and-caching&quot;&gt;do matter&lt;&#x2F;a&gt; for Grav. My host uses LiteSpeed which is &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.litespeedtech.com&#x2F;benchmarks&#x2F;php-hello-world&quot;&gt;faster&lt;&#x2F;a&gt; than Nginx or Apache, and I proxy the site through CloudFlare for free HTTPS – which also provides &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;blog.httpwatch.com&#x2F;2015&#x2F;01&#x2F;16&#x2F;a-simple-performance-comparison-of-https-spdy-and-http2&#x2F;&quot;&gt;the speed&lt;&#x2F;a&gt; of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.cloudflare.com&#x2F;website-optimization&#x2F;http2&#x2F;what-is-http2&#x2F;&quot;&gt;HTTP&#x2F;2&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;results&quot;&gt;Results&lt;a class=&quot;zola-anchor&quot; href=&quot;#results&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;As should now be clear, I’ve chased down the some of the most significant factors for the speed of the website. To evaluate the worth of all this optimization, I tested it against “&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;olevik.me&#x2F;writing&#x2F;workflows&#x2F;a-grav-development-workflow&quot;&gt;A Grav Development Workflow&lt;&#x2F;a&gt;”, which contains 1,567 words, two images, and a GitHub-Gist. The test yielded &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gtmetrix.com&#x2F;reports&#x2F;olevik.me&#x2F;v7KYmpIn&quot;&gt;exceptional results&lt;&#x2F;a&gt;: 100% PageSpeed score, 94% YSlow score, 0.9s time to fully load from the UK, and 89.1KB total page size. The site is already minimalistic, but as are the resources it needs to load.&lt;&#x2F;p&gt;
&lt;p&gt;The few exceptions from full scores come from minuscule differences in optimization between the test and my setup: 1-96 bytes of HTML and JS minification, a query string on &lt;code&gt;app.css&lt;&#x2F;code&gt; used to enable cache-busting, 219 bytes of optimization and lack of far-future Expiration-headers on external CSS by GitHub and Google Fonts, as well as a lack of CDN on these external assets. The remainder is from having three stylesheets, and cookies enabled on the site.&lt;&#x2F;p&gt;
&lt;p&gt;Even pages with much lower results than this should obviously ignore such details. There is no value in chasing down optimizations which won’t yield even a KB-reduction in page-weight, nor self-hosting external resource that are already optimized and hosted on CDN’s with better global distribution. With HTTP&#x2F;2, the amount of HTTP requests does not make much of a difference, certainly not enough to warrant inlining large assets.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;comparison-with-a-static-site&quot;&gt;Comparison with a static site&lt;a class=&quot;zola-anchor&quot; href=&quot;#comparison-with-a-static-site&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Since I previously used Jekyll to generate the site, it is a natural candidate for comparison with Grav. From an empty browser-cache, with a hard reload to ensure assets are all reloaded, both Grav and Jekyll clock in at less than a second in initial load time and less than half a second subsequent load with browser-cache enabled. This is from my local Chrome-browser on the live server. A more structured comparison using &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.webpagetest.org&#x2F;&quot;&gt;WebPageTest&lt;&#x2F;a&gt;, running 9 tests measuring initial and cached load times from Dulles, Virginia with Chrome, reveals:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;optimizing-a-grav-installation&#x2F;comparison.svg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;grav-vs-jekyll&quot;&gt;Grav vs Jekyll&lt;a class=&quot;zola-anchor&quot; href=&quot;#grav-vs-jekyll&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;As seen, the static site Jekyll generates is faster in both cases when compared to Grav. Some of this will result from additional plugins running with Grav, but most of the difference will be made up from Grav actually being a dynamic system. Both versions clock in at less than 1.4s with an active browser-cache, which are very good results.&lt;&#x2F;p&gt;
&lt;p&gt;It is important to note, though, that the organizational structure of Grav is much better than with Jekyll. Content (pages), view (theme), logic (plugins), models and controllers (Grav) are clearly separated, and as mentioned Twig is a much more powerful and flexible templating-language than Liquid. Structuring and optimizing the Jekyll-site required a lot of workarounds and more time than doing the same with Grav, even when adding in new and improved elements.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;zola-anchor&quot; href=&quot;#conclusion&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Because I develop with Grav I would of course recommend it, but I would also note that compared to most other Content Management Systems it performs much better. From the examination in this post two things should be clear: A dynamic system can perform on line with a statically generated site, and using a task-runner like Gulp&#x2F;Brunch (actually I recommand Brunch) for theme-development can easily yield excellent results in regards to best-practices in web-development.&lt;&#x2F;p&gt;
&lt;p&gt;As outlined, the whole setup has a much clearer structure and separation of concerns, and with modern systems and optimization near-ideal results can be achieved.&lt;&#x2F;p&gt;
</description>
                <content:encoded>&lt;p&gt;This following stands as my correction&#x2F;update of the awesome article written by &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;olevik.me&#x2F;writing&#x2F;code&#x2F;optimizing-a-grav-installation&quot;&gt;Ole Vik&lt;&#x2F;a&gt;. Kudos to him! I have mainly replaced code snippets and added instructions for Brunch, as some code wasn’t working (like the UnCSS wget prerequisite).&lt;&#x2F;p&gt;
&lt;p&gt;When the term “Web 2.0” became popular after 2004, the focus was largely on design, usability, and new media. In the past few years, however, web development has focused a lot on more on speed and performance, as well as delivery of media across varied devices.&lt;&#x2F;p&gt;
&lt;p&gt;This is largely because websites have become &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.websiteoptimization.com&#x2F;speed&#x2F;tweak&#x2F;average-web-page&#x2F;&quot;&gt;much heavier&lt;&#x2F;a&gt; since the 1990s, as websites have adopted new media and devices – including interactive elements, streaming video, audio, live data, and all else that we’re used to seeing on modern sites and apps these days. Images &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20170822010816&#x2F;http:&#x2F;&#x2F;www.webperformancetoday.com&#x2F;2013&#x2F;06&#x2F;05&#x2F;web-page-growth-2010-2013&#x2F;&quot;&gt;make up the bulk of this&lt;&#x2F;a&gt;, and thus deserve special consideration. In this post I will outline some strategies for optimizing assets in a theme in Grav, and illustrate what results they bring. If you are only interested in the results, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gtmetrix.com&#x2F;reports&#x2F;olevik.me&#x2F;v7KYmpIn&quot;&gt;look here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;preamble&quot;&gt;Preamble&lt;a class=&quot;zola-anchor&quot; href=&quot;#preamble&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;I’ve been using the static-site generator Jekyll for my personal website since 2016, previously WordPress and shortly Grav, but in 2017 I wanted to return to Grav. The reason for this was mainly the Liquid templating-engine that Jekyll uses, which requires a lot of workarounds for fairly basic tasks. Before I started with Jekyll I considered the plethora of static generators available, and have continuously evaluated them since. At the time this was the simpler choice. It also has the largest community of developers and resources online.&lt;&#x2F;p&gt;
&lt;p&gt;When re-evaluating the available options in 2017, I wanted a framework rather than bootstrapping the build-process together myself, and the only real static-site generator alternative to Jekyll was &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.metalsmith.io&#x2F;&quot;&gt;Metalsmith&lt;&#x2F;a&gt; in terms of maturity. However, the setup was unnecessarily complex yet limited, in that rather than simply handling Markdown-content and templating with a decent language like Twig, Nunjucks, or Jinja, a lot of declarations was necessary to accommodate the build-process I’ve used with Jekyll.&lt;&#x2F;p&gt;
&lt;p&gt;This build-process is based on using Gulp for optimizing assets and handles everything surrounding the site, thus relying on compiling content into templates. This was relatively easy with Jekyll, wherein the build is run with the simple execution of a command, and I wanted to maintain this simplicity going forward.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;automating-workflows&quot;&gt;Automating Workflows&lt;a class=&quot;zola-anchor&quot; href=&quot;#automating-workflows&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;I run &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;gulpjs.com&#x2F;&quot;&gt;Gulp&lt;&#x2F;a&gt; as a task-runner with Node. It builds asset in the nicest way possible. The build-process can be defined by these main steps in the gulpfile.js:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Build stylesheets using SCSS&lt;&#x2F;li&gt;
&lt;li&gt;&lt;del&gt;Build a static copy of the site using Wget&lt;&#x2F;del&gt; Serve the site with a local PHP7 spawnable server&lt;&#x2F;li&gt;
&lt;li&gt;Clean the CSS using UnCSS over the previous server&lt;&#x2F;li&gt;
&lt;li&gt;Minify the CSS&lt;&#x2F;li&gt;
&lt;li&gt;Losslessly minify images&lt;&#x2F;li&gt;
&lt;li&gt;Use Grav’s Asset Manager for pipelining or inlining JS&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Grav’s Asset Manager replaces most of Gulp traditional tasks in a useful way, making your Gulp workflow pretty simple: no copying, merging, moving, naming and versioning of assets is needed anymore on the Gulp side. Grav could of course also concatenate CSS-files, but Sass already handles that quite well.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;compiling-sass-scss&quot;&gt;Compiling Sass&#x2F;SCSS&lt;a class=&quot;zola-anchor&quot; href=&quot;#compiling-sass-scss&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;The stylesheets are &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;thesassway.com&#x2F;beginner&#x2F;how-to-structure-a-sass-project&quot;&gt;structured&lt;&#x2F;a&gt; with one principal file, which everything else compiles from; &lt;code&gt;app.scss&lt;&#x2F;code&gt;. Vendor-libraries are handled with &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;yarnpkg.com&#x2F;&quot;&gt;Yarn&lt;&#x2F;a&gt; (a better npm).&lt;&#x2F;p&gt;
&lt;p&gt;Things to note in regards to Sass is the most recent alpha-version of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;v4-alpha.getbootstrap.com&#x2F;&quot;&gt;Bootstrap V4&lt;&#x2F;a&gt;, as well as &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;compass-style.org&#x2F;&quot;&gt;Compass&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;eduardoboucas&#x2F;include-media&quot;&gt;include-media&lt;&#x2F;a&gt;, and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.modularscale.com&#x2F;&quot;&gt;Modular Scale&lt;&#x2F;a&gt;. These are all excellent libraries for simplifying the structure and styling of CSS, by using cross-browser standards and elegant helper-functions. The Gulp-libraries are for compiling the Sass and minifying assets. Notably, Autoprefixer for excellent cross-browser compatible CSS-declarations, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;cssnano.co&#x2F;&quot;&gt;CSSNano&lt;&#x2F;a&gt; for &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;goalsmashers.github.io&#x2F;css-minification-benchmark&#x2F;&quot;&gt;optimal&lt;&#x2F;a&gt;-minification, and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;giakki&#x2F;uncss&quot;&gt;UnCSS&lt;&#x2F;a&gt; for aggressive CSS-removal.&lt;&#x2F;p&gt;
&lt;p&gt;Where possible I avoid superfluous HTTP requests, for example when including images. If the image is fairly small, I &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;varvy.com&#x2F;pagespeed&#x2F;base64-images.html&quot;&gt;base64-encode&lt;&#x2F;a&gt; it to obtain a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;css-tricks.com&#x2F;data-uris&#x2F;&quot;&gt;data-URI&lt;&#x2F;a&gt; that can be placed directly in the CSS.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;cleaning-the-css&quot;&gt;Cleaning the CSS&lt;a class=&quot;zola-anchor&quot; href=&quot;#cleaning-the-css&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;UnCSS is particularly important here. This tool examines all used CSS-selectors from a set of files and &lt;strong&gt;removes all selectors not in use&lt;&#x2F;strong&gt;. You might think this sounds error-prone and unnecessary, but used intelligently it’s the most efficient reduction of a CSS-file possible. The reason for this is two-fold: Only explicitly needed selectors are kept and when something is left out, you can tell UnCSS to ignore a selector to keep it in. This is necessary for certain onclick-effects and the like. Since Grav compiles dynamic PHP-files with its cache, I use UnCSS’s ability to look up a local service url and point it to the previously launched php server:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;Javascript&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-Javascript &quot;&gt;&lt;code class=&quot;language-Javascript&quot; data-lang=&quot;Javascript&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;gulp&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;task&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;sass&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;function&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;var &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;plugins &lt;&#x2F;span&gt;&lt;span&gt;= [
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;autoprefixer&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;)({
&lt;&#x2F;span&gt;&lt;span&gt;        browsers: [&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;last 2 versions&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;,&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;gt; 2%&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;]
&lt;&#x2F;span&gt;&lt;span&gt;      }),
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;uncss&lt;&#x2F;span&gt;&lt;span&gt;({
&lt;&#x2F;span&gt;&lt;span&gt;        html: [&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;http:&#x2F;&#x2F;127.0.0.1:8001&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;,&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;http:&#x2F;&#x2F;127.0.0.1:8001&#x2F;contact&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;],
&lt;&#x2F;span&gt;&lt;span&gt;        ignore: [&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;.hide&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;,&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;.dropdown&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;,&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;.kubeanimated&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;,&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;slideDown&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;]
&lt;&#x2F;span&gt;&lt;span&gt;      })
&lt;&#x2F;span&gt;&lt;span&gt;    ];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;gulp&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;src&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;css&#x2F;master.scss&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;)
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;pipe&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sass&lt;&#x2F;span&gt;&lt;span&gt;())
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;pipe&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;postcss&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;plugins&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt; 		.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;pipe&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;minify&lt;&#x2F;span&gt;&lt;span&gt;())
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;pipe&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rename&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;master.css&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;))
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;pipe&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;gulp&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;dest&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;css&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;));
&lt;&#x2F;span&gt;&lt;span&gt;});
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The problem with UnCSS is to ensure that needed selectors are not removed, pages must be tested and UnCSS’s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;giakki&#x2F;uncss&quot;&gt;ignore-parameter&lt;&#x2F;a&gt; optimized. I’d use &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;visualregressiontesting.com&#x2F;&quot;&gt;Visual Regression Testing&lt;&#x2F;a&gt; if the site was large or complex enough to warrant it.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;asset-manager&quot;&gt;Asset Manager&lt;a class=&quot;zola-anchor&quot; href=&quot;#asset-manager&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;To avoid render-blocking CSS I use &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;filamentgroup&#x2F;loadCSS&quot;&gt;loadCSS&lt;&#x2F;a&gt;, which loads these assets only after HTML in the DOM has finished rendering. Simply put, it applies an onload-attribute for &lt;code&gt;&amp;lt;link&amp;gt;&lt;&#x2F;code&gt;-tags that enables the stylesheet. The loadCSS-library is basically a polyfill for this behavior, which in this case enables deferred loading of &lt;code&gt;app.css&lt;&#x2F;code&gt;. In Twig, I have implemented it this way:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;{% do assets.addJs(&amp;#39;theme:&#x2F;&#x2F;js&#x2F;loadCSS.min.js&amp;#39;, {&amp;#39;loading&amp;#39;: &amp;#39;inline&amp;#39;, &amp;#39;group&amp;#39;: &amp;#39;critical&amp;#39;}) %}
&lt;&#x2F;span&gt;&lt;span&gt;{% do assets.addJs(&amp;#39;theme:&#x2F;&#x2F;js&#x2F;cssrelpreload.min.js&amp;#39;, {&amp;#39;loading&amp;#39;: &amp;#39;inline&amp;#39;, &amp;#39;group&amp;#39;: &amp;#39;critical&amp;#39;}) %}
&lt;&#x2F;span&gt;&lt;span&gt;{{ assets.js(&amp;#39;critical&amp;#39;) }}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;{% block stylesheets %}
&lt;&#x2F;span&gt;&lt;span&gt;  {% do assets.addCSS(&amp;#39;theme:&#x2F;&#x2F;css&#x2F;app.css&amp;#39;, {&amp;#39;group&amp;#39;:&amp;#39;preload&amp;#39;}) %}
&lt;&#x2F;span&gt;&lt;span&gt;  &amp;lt;noscript&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;{{ url(&amp;#39;theme:&#x2F;&#x2F;css&#x2F;app.css&amp;#39;) }}&amp;quot;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &amp;lt;&#x2F;noscript&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;{% endblock %}
&lt;&#x2F;span&gt;&lt;span&gt;{{ assets.css(&amp;#39;preload&amp;#39;, {&amp;#39;rel&amp;#39;: &amp;#39;preload&amp;#39;, &amp;#39;as&amp;#39;: &amp;#39;style&amp;#39;, &amp;#39;onload&amp;#39;: &amp;quot;this.rel=&amp;#39;stylesheet&amp;#39;&amp;quot;}) }}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Specifically, the “critical” JS-group inlines loadCSS before all else in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;&#x2F;code&gt;-tag. Next, the main stylesheet and fonts are loaded in a deferred-manner. Note that both of these stylesheets are single files, which reduces HTTP requests. I also include the standard &lt;code&gt;&amp;lt;noscript&amp;gt;&lt;&#x2F;code&gt;-tag to accommodate outdated browsers, or where JS is disabled. Before closing the &lt;code&gt;&amp;lt;body&amp;gt;&lt;&#x2F;code&gt;-tag I am including &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;highlightjs.org&#x2F;&quot;&gt;highlight.js&lt;&#x2F;a&gt; for code-highlighting:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;{% block scripts_end %}
&lt;&#x2F;span&gt;&lt;span&gt;  {% if page.header.highlight.enabled %}
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;lt;script 
&lt;&#x2F;span&gt;&lt;span&gt;      type=&amp;quot;text&#x2F;javascript&amp;quot; 
&lt;&#x2F;span&gt;&lt;span&gt;      defer 
&lt;&#x2F;span&gt;&lt;span&gt;      src=&amp;quot;{{ url(&amp;#39;theme:&#x2F;&#x2F;js&#x2F;highlight.pack.js&amp;#39;) }}&amp;quot; 
&lt;&#x2F;span&gt;&lt;span&gt;      onload=&amp;quot;hljs.initHighlightingOnLoad();&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;gt;&amp;lt;&#x2F;script&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;  {% endif %}
&lt;&#x2F;span&gt;&lt;span&gt;  {% if page.header.highlight.lines %}
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;lt;script 
&lt;&#x2F;span&gt;&lt;span&gt;      type=&amp;quot;text&#x2F;javascript&amp;quot; 
&lt;&#x2F;span&gt;&lt;span&gt;      defer 
&lt;&#x2F;span&gt;&lt;span&gt;      src=&amp;quot;{{ url(&amp;#39;theme:&#x2F;&#x2F;js&#x2F;highlightjs-line-numbers.min.js&amp;#39;) }}&amp;quot; 
&lt;&#x2F;span&gt;&lt;span&gt;      onload=&amp;quot;hljs.initLineNumbersOnLoad();&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;gt;&amp;lt;&#x2F;script&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;  {% endif %}
&lt;&#x2F;span&gt;&lt;span&gt;{% endblock %}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The same strategy is applied here: Defer loading the asset, and instantiate it onload.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;optimizing-the-server&quot;&gt;Optimizing the server&lt;a class=&quot;zola-anchor&quot; href=&quot;#optimizing-the-server&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;I use PHP 7 for both development and production as it performs significantly &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.zend.com&#x2F;en&#x2F;resources&#x2F;php7_infographic&quot;&gt;better&lt;&#x2F;a&gt; than previous versions. The server I host on also supports Gzip-compression, and I set &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;varvy.com&#x2F;pagespeed&#x2F;leverage-browser-caching.html&quot;&gt;Expires-headers&lt;&#x2F;a&gt; to avoid having the browser load files unnecessarily.&lt;&#x2F;p&gt;
&lt;p&gt;You may want a host machine pretty much the same system as a $10&#x2F;month VPS – and these technicalities &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;learn.getgrav.org&#x2F;advanced&#x2F;performance-and-caching&quot;&gt;do matter&lt;&#x2F;a&gt; for Grav. My host uses LiteSpeed which is &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.litespeedtech.com&#x2F;benchmarks&#x2F;php-hello-world&quot;&gt;faster&lt;&#x2F;a&gt; than Nginx or Apache, and I proxy the site through CloudFlare for free HTTPS – which also provides &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;blog.httpwatch.com&#x2F;2015&#x2F;01&#x2F;16&#x2F;a-simple-performance-comparison-of-https-spdy-and-http2&#x2F;&quot;&gt;the speed&lt;&#x2F;a&gt; of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.cloudflare.com&#x2F;website-optimization&#x2F;http2&#x2F;what-is-http2&#x2F;&quot;&gt;HTTP&#x2F;2&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;results&quot;&gt;Results&lt;a class=&quot;zola-anchor&quot; href=&quot;#results&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;As should now be clear, I’ve chased down the some of the most significant factors for the speed of the website. To evaluate the worth of all this optimization, I tested it against “&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;olevik.me&#x2F;writing&#x2F;workflows&#x2F;a-grav-development-workflow&quot;&gt;A Grav Development Workflow&lt;&#x2F;a&gt;”, which contains 1,567 words, two images, and a GitHub-Gist. The test yielded &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gtmetrix.com&#x2F;reports&#x2F;olevik.me&#x2F;v7KYmpIn&quot;&gt;exceptional results&lt;&#x2F;a&gt;: 100% PageSpeed score, 94% YSlow score, 0.9s time to fully load from the UK, and 89.1KB total page size. The site is already minimalistic, but as are the resources it needs to load.&lt;&#x2F;p&gt;
&lt;p&gt;The few exceptions from full scores come from minuscule differences in optimization between the test and my setup: 1-96 bytes of HTML and JS minification, a query string on &lt;code&gt;app.css&lt;&#x2F;code&gt; used to enable cache-busting, 219 bytes of optimization and lack of far-future Expiration-headers on external CSS by GitHub and Google Fonts, as well as a lack of CDN on these external assets. The remainder is from having three stylesheets, and cookies enabled on the site.&lt;&#x2F;p&gt;
&lt;p&gt;Even pages with much lower results than this should obviously ignore such details. There is no value in chasing down optimizations which won’t yield even a KB-reduction in page-weight, nor self-hosting external resource that are already optimized and hosted on CDN’s with better global distribution. With HTTP&#x2F;2, the amount of HTTP requests does not make much of a difference, certainly not enough to warrant inlining large assets.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;comparison-with-a-static-site&quot;&gt;Comparison with a static site&lt;a class=&quot;zola-anchor&quot; href=&quot;#comparison-with-a-static-site&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Since I previously used Jekyll to generate the site, it is a natural candidate for comparison with Grav. From an empty browser-cache, with a hard reload to ensure assets are all reloaded, both Grav and Jekyll clock in at less than a second in initial load time and less than half a second subsequent load with browser-cache enabled. This is from my local Chrome-browser on the live server. A more structured comparison using &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.webpagetest.org&#x2F;&quot;&gt;WebPageTest&lt;&#x2F;a&gt;, running 9 tests measuring initial and cached load times from Dulles, Virginia with Chrome, reveals:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;optimizing-a-grav-installation&#x2F;comparison.svg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;grav-vs-jekyll&quot;&gt;Grav vs Jekyll&lt;a class=&quot;zola-anchor&quot; href=&quot;#grav-vs-jekyll&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;As seen, the static site Jekyll generates is faster in both cases when compared to Grav. Some of this will result from additional plugins running with Grav, but most of the difference will be made up from Grav actually being a dynamic system. Both versions clock in at less than 1.4s with an active browser-cache, which are very good results.&lt;&#x2F;p&gt;
&lt;p&gt;It is important to note, though, that the organizational structure of Grav is much better than with Jekyll. Content (pages), view (theme), logic (plugins), models and controllers (Grav) are clearly separated, and as mentioned Twig is a much more powerful and flexible templating-language than Liquid. Structuring and optimizing the Jekyll-site required a lot of workarounds and more time than doing the same with Grav, even when adding in new and improved elements.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;zola-anchor&quot; href=&quot;#conclusion&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Because I develop with Grav I would of course recommend it, but I would also note that compared to most other Content Management Systems it performs much better. From the examination in this post two things should be clear: A dynamic system can perform on line with a statically generated site, and using a task-runner like Gulp&#x2F;Brunch (actually I recommand Brunch) for theme-development can easily yield excellent results in regards to best-practices in web-development.&lt;&#x2F;p&gt;
&lt;p&gt;As outlined, the whole setup has a much clearer structure and separation of concerns, and with modern systems and optimization near-ideal results can be achieved.&lt;&#x2F;p&gt;
</content:encoded>
            </item>
        
            <item>
                <title>Draft notes #2</title>
                <pubDate>Mon, 28 Aug 2017 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/draft-notes-2/</link>
                <guid>https://rigelk.frama.io/blog/blog/draft-notes-2/</guid>
                <description>&lt;p&gt;This week’s focus was mainly on getting the blog to comply with PageSpeed Insights’s recommandation, and globally getting a finer understanding on best practices for serving this blog to you with my small VPS.&lt;&#x2F;p&gt;
&lt;p&gt;It so appears that &lt;em&gt;compressing assets is of utmost importance&lt;&#x2F;em&gt;, and while I already knew that through my previous experiences using gulp and other JS-based compilation tools, I also assumed nothing similar existed in the PHP world.
I have been using a Ghost blog previously, and making both Ghost and Wordpress themes for my previous blogs using npm tools. I’ve also done some SPAs for my work, which of course were sites running entirely on the client side with little to no server interaction. That plus the whole trend of using JS everywhere lead me to think you couldn’t do it in two clicks in PHP.&lt;&#x2F;p&gt;
&lt;p&gt;Oh boy I was wrong.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;compressing-assets&quot;&gt;Compressing assets&lt;a class=&quot;zola-anchor&quot; href=&quot;#compressing-assets&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Shrinking, compressing assets is what pipelines are for. Think of it as a meat grinder for Javascript, CSS files, and even more. They help solve optimization problems in website delivery:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;removing blanks, using shorter variable names, etc… compressing what can be compressed make your assets load faster. That’s the naive solution to speed up your website.&lt;&#x2F;li&gt;
&lt;li&gt;merging files when it makes sense, so that the client doesn’t have to spawn a new HTTP connection (or new stream in HTTP&#x2F;2, even if that’s less costly) for each file but one.&lt;&#x2F;li&gt;
&lt;li&gt;versioning files to bypass cache when a new set of files are generated.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;But often, these are done in JS, or are left aside, like that of async loading of assets in the right order for optimal page load.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;grav-s-fabulously-simple-asset-manager&quot;&gt;Grav’s fabulously simple Asset Manager&lt;a class=&quot;zola-anchor&quot; href=&quot;#grav-s-fabulously-simple-asset-manager&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;It does everything at once! Thanks to its Twig support, it’s as easy as putting the following snippet in your your Grav site:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;  {% block javascripts %}
&lt;&#x2F;span&gt;&lt;span&gt;    {% do assets.addJs(&amp;#39;jquery&amp;#39;,{&amp;#39;priority&amp;#39;:110,&amp;#39;pipeline&amp;#39;:true}) %}
&lt;&#x2F;span&gt;&lt;span&gt;    {% do assets.addJs(&amp;#39;theme:&#x2F;&#x2F;js&#x2F;kube.min.js&amp;#39;,{&amp;#39;pipeline&amp;#39;:true,&amp;#39;group&amp;#39;:&amp;#39;head-async&amp;#39;}) %}
&lt;&#x2F;span&gt;&lt;span&gt;  {% endblock %}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  {{ assets.js(&amp;#39;head-async&amp;#39;,{&amp;#39;loading&amp;#39;:&amp;#39;async&amp;#39;}) }}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  {% block stylesheets %}
&lt;&#x2F;span&gt;&lt;span&gt;    {% do assets.addCss(&amp;#39;theme:&#x2F;&#x2F;css&#x2F;kube.min.css&amp;#39;) %}
&lt;&#x2F;span&gt;&lt;span&gt;    {% do assets.addCss(&amp;#39;theme:&#x2F;&#x2F;css&#x2F;custom.min.css&amp;#39;) %}
&lt;&#x2F;span&gt;&lt;span&gt;  {% endblock %}
&lt;&#x2F;span&gt;&lt;span&gt;  {{ assets.css() }}
&lt;&#x2F;span&gt;&lt;span&gt;  
&lt;&#x2F;span&gt;&lt;span&gt;  ... &amp;lt;!--- after the footer ---&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;  
&lt;&#x2F;span&gt;&lt;span&gt;  {{ assets.js(&amp;#39;head&amp;#39;,{&amp;#39;loading&amp;#39;:&amp;#39;sync&amp;#39;}) }}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And at the end you get two ordered asset files (picture depicts a different version with synchronized JS assets):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;draft-notes-2&#x2F;2017-08-28-034459_796x155_scrot.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;but-why-not-that-shiny-javascript&quot;&gt;But why not that shiny Javascript?&lt;a class=&quot;zola-anchor&quot; href=&quot;#but-why-not-that-shiny-javascript&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Grav - the blogging system I use - being a PHP-based CMS, processes of course everything server-side. A Javascript-based CMS would probably put the load of computing on the client. While it can be useful if you &lt;em&gt;need&lt;&#x2F;em&gt; an ultra-scalable application with thousand of clients for a minimal server load, bear in mind that most of the time:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;usually, that means more files to send to the client (unpractical in unreliable&#x2F;+slow mobile network settings)&lt;&#x2F;li&gt;
&lt;li&gt;at best, that means the device will have to compute more (slowing even more light devices as phones)&lt;&#x2F;li&gt;
&lt;li&gt;at worst, that means more bugs, as Javascript is a cursed language.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;vade-retro-ecmascript&quot;&gt;Vade retro, ECMAScript&lt;a class=&quot;zola-anchor&quot; href=&quot;#vade-retro-ecmascript&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;cdn-images-1.medium.com&#x2F;max&#x2F;800&#x2F;1*Kd0UGiDvgooFooCy28rs8Q.jpeg&quot; alt=&quot;Book size for JS&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Oh yeah, I now try to limit my use of Javascript. Why? Let’s recap with &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;hackernoon.com&#x2F;the-javascript-phenomenon-is-a-mass-psychosis-57adebb09359&quot;&gt;something I read on Medium&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;I ran a software business for a couple of years. It got bought and right now Im developing the very product I used to sell. My former employees put AngularJs and Node.js in there. I remember my conversation 3 years ago with my best engineer : he said that javascript was taking over everything. I thought “Wow. They managed to fix that horrible language”&lt;&#x2F;p&gt;
&lt;p&gt;Well, no. And it’s worse, because at least before, we were screwing up small things with JS, it was a toy. The thing is, there is a mass psychosis about JS and it’s like everybody is pretending that it isn’t awful. And then, as if this wasn’t bad enough, someone had the brilliant idea of putting this thing in the backend. Nodejs is costing millions per year to naive companies who are adopting it. You were wondering who they are: they are startups and small companies.&lt;&#x2F;p&gt;
&lt;p&gt;Mind you, these engineers are smart, but they’re weak against crowd thinking.&lt;&#x2F;p&gt;
&lt;p&gt;At my new company, everyone was pretending that JS was alright. I got tired and spoke up. Turns out, deep down they all hated JS, it was just crowd thinking. Now they all hate JS. And we’re waiting impatiently for Web Assembly.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;One of the most amazing and distressing things about JavaScript is that it can actually fail silently at runtime due to syntactical errors! Another thing is “callback hell” which promises can mitigate but are otherwise not a perfect solution. The most notorious of JavaScript’s faults is probably in its weak typing (not to be confused with dynamic typing) which manifests in the profusion of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=2pL28CcEijU&quot;&gt;WATs and WTFs&lt;&#x2F;a&gt; that make JavaScript the butt of so many industry jokes.&lt;&#x2F;p&gt;
&lt;div &gt;
    &lt;iframe
        src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;2pL28CcEijU&quot;
        webkitallowfullscreen
        mozallowfullscreen
        allowfullscreen&gt;
    &lt;&#x2F;iframe&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;The language is so bad that the use of a linter (such as JSLint or ESLint) is practically mandated for all JavaScript programmers. This, despite the fact that ECMAScript has undergone many, many improvements in recent years culminating in ES6. Apparently, the ECMA TC39 committee is unable to completely eliminate all of JavaScript’s most egregious faults.&lt;&#x2F;p&gt;
&lt;p&gt;The thing is, it’s broken, but it’s been bundled first by Netscape and forced unto us when IE was popular and ever since, grew into a large user community and ecosystem of tools and libraries, not to mention the large number of jobs available for JavaScript developers. This answer also explains the longevity of all the mainstream languages, irrespective of their faults, including: PHP, C++, Perl, and Visual Basic (languages everybody loves to hate).&lt;&#x2F;p&gt;
&lt;p&gt;It just has too many faults and a litteral monopoly on browser runtime to be left excused with that.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;use-javascript-just-not-the-way-you-learned-it&quot;&gt;Use Javascript, just not the way you learned it&lt;a class=&quot;zola-anchor&quot; href=&quot;#use-javascript-just-not-the-way-you-learned-it&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;You can use languages that transpile to JavaScript to avoid its pitfalls or bugs. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;javascript-non-grata&#x2F;the-super-surrogates-of-javascript-862460199915&quot;&gt;Here&lt;&#x2F;a&gt; are some of the better ones, but &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jashkenas&#x2F;coffeescript&#x2F;wiki&#x2F;list-of-languages-that-compile-to-js&quot;&gt;there are many, many languages to choose from&lt;&#x2F;a&gt;. For front-end development, you don’t have to choose JavaScript unless you’re sheep.&lt;&#x2F;p&gt;
&lt;p&gt;So it’s really your choice. It’s up to you whether you want to dive into the chaotic world of JavaScript. That’s where the money is in terms of front-end jobs. But that’s also where the unholy mess of JS web frameworks is, which leads to “framework fatigue.” Angular 1, Angular 2, React, Ember, Meteor, Backbone, Knockout, Mercury, Polymer, Aurelia, Mithril, Vue, etc. I’ve even personally used Angular 1&#x2F;2, Ember, Meteor and React (my favorite). I would even have used Knockout if my projects were not to be used by others! But I definitely felt that fatigue.&lt;&#x2F;p&gt;
&lt;p&gt;While I still haven’t chosen a transpiler to start with, I have come accross &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;witheve.com&#x2F;philosophy&#x2F;&quot;&gt;one I like in its own setting&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;a-bright-light-in-the-future-webassembly&quot;&gt;A bright light in the future: WebAssembly&lt;a class=&quot;zola-anchor&quot; href=&quot;#a-bright-light-in-the-future-webassembly&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;An improvement to JavaScript&lt;&#x2F;em&gt;: Implement your performance critical stuff in wasm and import it like a standard JavaScript module.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;A new language&lt;&#x2F;em&gt;: WebAssembly code defines an AST (Abstract Syntax Tree) represented in a binary format. You can author and debug in a text format so it’s readable.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;A browser improvement&lt;&#x2F;em&gt;: Browsers will understand the binary format, which means we’ll be able to compile binary bundles that compress smaller than the text JavaScript we use today. Smaller payloads mean faster delivery. Depending on compile-time optimization opportunities, WebAssembly bundles may run faster than JavaScript, too!&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;A Compile Target&lt;&#x2F;em&gt;: A way for other languages to get first-class binary support across the entire web platform stack.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Oh my, I diverged again from the initial subject, right?&lt;&#x2F;p&gt;
</description>
                <content:encoded>&lt;p&gt;This week’s focus was mainly on getting the blog to comply with PageSpeed Insights’s recommandation, and globally getting a finer understanding on best practices for serving this blog to you with my small VPS.&lt;&#x2F;p&gt;
&lt;p&gt;It so appears that &lt;em&gt;compressing assets is of utmost importance&lt;&#x2F;em&gt;, and while I already knew that through my previous experiences using gulp and other JS-based compilation tools, I also assumed nothing similar existed in the PHP world.
I have been using a Ghost blog previously, and making both Ghost and Wordpress themes for my previous blogs using npm tools. I’ve also done some SPAs for my work, which of course were sites running entirely on the client side with little to no server interaction. That plus the whole trend of using JS everywhere lead me to think you couldn’t do it in two clicks in PHP.&lt;&#x2F;p&gt;
&lt;p&gt;Oh boy I was wrong.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;compressing-assets&quot;&gt;Compressing assets&lt;a class=&quot;zola-anchor&quot; href=&quot;#compressing-assets&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Shrinking, compressing assets is what pipelines are for. Think of it as a meat grinder for Javascript, CSS files, and even more. They help solve optimization problems in website delivery:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;removing blanks, using shorter variable names, etc… compressing what can be compressed make your assets load faster. That’s the naive solution to speed up your website.&lt;&#x2F;li&gt;
&lt;li&gt;merging files when it makes sense, so that the client doesn’t have to spawn a new HTTP connection (or new stream in HTTP&#x2F;2, even if that’s less costly) for each file but one.&lt;&#x2F;li&gt;
&lt;li&gt;versioning files to bypass cache when a new set of files are generated.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;But often, these are done in JS, or are left aside, like that of async loading of assets in the right order for optimal page load.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;grav-s-fabulously-simple-asset-manager&quot;&gt;Grav’s fabulously simple Asset Manager&lt;a class=&quot;zola-anchor&quot; href=&quot;#grav-s-fabulously-simple-asset-manager&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;It does everything at once! Thanks to its Twig support, it’s as easy as putting the following snippet in your your Grav site:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;  {% block javascripts %}
&lt;&#x2F;span&gt;&lt;span&gt;    {% do assets.addJs(&amp;#39;jquery&amp;#39;,{&amp;#39;priority&amp;#39;:110,&amp;#39;pipeline&amp;#39;:true}) %}
&lt;&#x2F;span&gt;&lt;span&gt;    {% do assets.addJs(&amp;#39;theme:&#x2F;&#x2F;js&#x2F;kube.min.js&amp;#39;,{&amp;#39;pipeline&amp;#39;:true,&amp;#39;group&amp;#39;:&amp;#39;head-async&amp;#39;}) %}
&lt;&#x2F;span&gt;&lt;span&gt;  {% endblock %}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  {{ assets.js(&amp;#39;head-async&amp;#39;,{&amp;#39;loading&amp;#39;:&amp;#39;async&amp;#39;}) }}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  {% block stylesheets %}
&lt;&#x2F;span&gt;&lt;span&gt;    {% do assets.addCss(&amp;#39;theme:&#x2F;&#x2F;css&#x2F;kube.min.css&amp;#39;) %}
&lt;&#x2F;span&gt;&lt;span&gt;    {% do assets.addCss(&amp;#39;theme:&#x2F;&#x2F;css&#x2F;custom.min.css&amp;#39;) %}
&lt;&#x2F;span&gt;&lt;span&gt;  {% endblock %}
&lt;&#x2F;span&gt;&lt;span&gt;  {{ assets.css() }}
&lt;&#x2F;span&gt;&lt;span&gt;  
&lt;&#x2F;span&gt;&lt;span&gt;  ... &amp;lt;!--- after the footer ---&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;  
&lt;&#x2F;span&gt;&lt;span&gt;  {{ assets.js(&amp;#39;head&amp;#39;,{&amp;#39;loading&amp;#39;:&amp;#39;sync&amp;#39;}) }}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And at the end you get two ordered asset files (picture depicts a different version with synchronized JS assets):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;draft-notes-2&#x2F;2017-08-28-034459_796x155_scrot.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;but-why-not-that-shiny-javascript&quot;&gt;But why not that shiny Javascript?&lt;a class=&quot;zola-anchor&quot; href=&quot;#but-why-not-that-shiny-javascript&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Grav - the blogging system I use - being a PHP-based CMS, processes of course everything server-side. A Javascript-based CMS would probably put the load of computing on the client. While it can be useful if you &lt;em&gt;need&lt;&#x2F;em&gt; an ultra-scalable application with thousand of clients for a minimal server load, bear in mind that most of the time:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;usually, that means more files to send to the client (unpractical in unreliable&#x2F;+slow mobile network settings)&lt;&#x2F;li&gt;
&lt;li&gt;at best, that means the device will have to compute more (slowing even more light devices as phones)&lt;&#x2F;li&gt;
&lt;li&gt;at worst, that means more bugs, as Javascript is a cursed language.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;vade-retro-ecmascript&quot;&gt;Vade retro, ECMAScript&lt;a class=&quot;zola-anchor&quot; href=&quot;#vade-retro-ecmascript&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;cdn-images-1.medium.com&#x2F;max&#x2F;800&#x2F;1*Kd0UGiDvgooFooCy28rs8Q.jpeg&quot; alt=&quot;Book size for JS&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Oh yeah, I now try to limit my use of Javascript. Why? Let’s recap with &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;hackernoon.com&#x2F;the-javascript-phenomenon-is-a-mass-psychosis-57adebb09359&quot;&gt;something I read on Medium&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;I ran a software business for a couple of years. It got bought and right now Im developing the very product I used to sell. My former employees put AngularJs and Node.js in there. I remember my conversation 3 years ago with my best engineer : he said that javascript was taking over everything. I thought “Wow. They managed to fix that horrible language”&lt;&#x2F;p&gt;
&lt;p&gt;Well, no. And it’s worse, because at least before, we were screwing up small things with JS, it was a toy. The thing is, there is a mass psychosis about JS and it’s like everybody is pretending that it isn’t awful. And then, as if this wasn’t bad enough, someone had the brilliant idea of putting this thing in the backend. Nodejs is costing millions per year to naive companies who are adopting it. You were wondering who they are: they are startups and small companies.&lt;&#x2F;p&gt;
&lt;p&gt;Mind you, these engineers are smart, but they’re weak against crowd thinking.&lt;&#x2F;p&gt;
&lt;p&gt;At my new company, everyone was pretending that JS was alright. I got tired and spoke up. Turns out, deep down they all hated JS, it was just crowd thinking. Now they all hate JS. And we’re waiting impatiently for Web Assembly.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;One of the most amazing and distressing things about JavaScript is that it can actually fail silently at runtime due to syntactical errors! Another thing is “callback hell” which promises can mitigate but are otherwise not a perfect solution. The most notorious of JavaScript’s faults is probably in its weak typing (not to be confused with dynamic typing) which manifests in the profusion of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=2pL28CcEijU&quot;&gt;WATs and WTFs&lt;&#x2F;a&gt; that make JavaScript the butt of so many industry jokes.&lt;&#x2F;p&gt;
&lt;div &gt;
    &lt;iframe
        src=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;2pL28CcEijU&quot;
        webkitallowfullscreen
        mozallowfullscreen
        allowfullscreen&gt;
    &lt;&#x2F;iframe&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;The language is so bad that the use of a linter (such as JSLint or ESLint) is practically mandated for all JavaScript programmers. This, despite the fact that ECMAScript has undergone many, many improvements in recent years culminating in ES6. Apparently, the ECMA TC39 committee is unable to completely eliminate all of JavaScript’s most egregious faults.&lt;&#x2F;p&gt;
&lt;p&gt;The thing is, it’s broken, but it’s been bundled first by Netscape and forced unto us when IE was popular and ever since, grew into a large user community and ecosystem of tools and libraries, not to mention the large number of jobs available for JavaScript developers. This answer also explains the longevity of all the mainstream languages, irrespective of their faults, including: PHP, C++, Perl, and Visual Basic (languages everybody loves to hate).&lt;&#x2F;p&gt;
&lt;p&gt;It just has too many faults and a litteral monopoly on browser runtime to be left excused with that.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;use-javascript-just-not-the-way-you-learned-it&quot;&gt;Use Javascript, just not the way you learned it&lt;a class=&quot;zola-anchor&quot; href=&quot;#use-javascript-just-not-the-way-you-learned-it&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;You can use languages that transpile to JavaScript to avoid its pitfalls or bugs. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;javascript-non-grata&#x2F;the-super-surrogates-of-javascript-862460199915&quot;&gt;Here&lt;&#x2F;a&gt; are some of the better ones, but &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jashkenas&#x2F;coffeescript&#x2F;wiki&#x2F;list-of-languages-that-compile-to-js&quot;&gt;there are many, many languages to choose from&lt;&#x2F;a&gt;. For front-end development, you don’t have to choose JavaScript unless you’re sheep.&lt;&#x2F;p&gt;
&lt;p&gt;So it’s really your choice. It’s up to you whether you want to dive into the chaotic world of JavaScript. That’s where the money is in terms of front-end jobs. But that’s also where the unholy mess of JS web frameworks is, which leads to “framework fatigue.” Angular 1, Angular 2, React, Ember, Meteor, Backbone, Knockout, Mercury, Polymer, Aurelia, Mithril, Vue, etc. I’ve even personally used Angular 1&#x2F;2, Ember, Meteor and React (my favorite). I would even have used Knockout if my projects were not to be used by others! But I definitely felt that fatigue.&lt;&#x2F;p&gt;
&lt;p&gt;While I still haven’t chosen a transpiler to start with, I have come accross &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;witheve.com&#x2F;philosophy&#x2F;&quot;&gt;one I like in its own setting&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;a-bright-light-in-the-future-webassembly&quot;&gt;A bright light in the future: WebAssembly&lt;a class=&quot;zola-anchor&quot; href=&quot;#a-bright-light-in-the-future-webassembly&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;An improvement to JavaScript&lt;&#x2F;em&gt;: Implement your performance critical stuff in wasm and import it like a standard JavaScript module.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;A new language&lt;&#x2F;em&gt;: WebAssembly code defines an AST (Abstract Syntax Tree) represented in a binary format. You can author and debug in a text format so it’s readable.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;A browser improvement&lt;&#x2F;em&gt;: Browsers will understand the binary format, which means we’ll be able to compile binary bundles that compress smaller than the text JavaScript we use today. Smaller payloads mean faster delivery. Depending on compile-time optimization opportunities, WebAssembly bundles may run faster than JavaScript, too!&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;A Compile Target&lt;&#x2F;em&gt;: A way for other languages to get first-class binary support across the entire web platform stack.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Oh my, I diverged again from the initial subject, right?&lt;&#x2F;p&gt;
</content:encoded>
            </item>
        
            <item>
                <title>ZeroNet, quest for a decentralised and anonymous internet</title>
                <pubDate>Sat, 26 Aug 2017 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/zeronet-quest/</link>
                <guid>https://rigelk.frama.io/blog/blog/zeronet-quest/</guid>
                <description>&lt;p&gt;After testing a bit around Zeronet, I wanted to know how to create a somehow “heavy” site on ZeroNet. That is, a site hosting quite a lot a data (ex: YouTube clone). Exploring for ways to do this forced me to explore some intricacies of ZeroNet.&lt;&#x2F;p&gt;
&lt;p&gt;ZeroNet uses a combination of BitTorrent-like protocol, a custom file server and a web based user interface to create a fully decentralized internet overlay. The best thing of that big POC is that it manages to provide a pretty useable experience!&lt;&#x2F;p&gt;
&lt;p&gt;Users run a ZeroNet node and do their web browsing via the local proxy it provides (i.e.: using a local service port in your web browser of choice). Website addresses are public keys, generated using the same algorithm as used for bitcoin addresses. A request for a website key results in the node looking in the bittorrent network for peers that are seeding the site. Peers are selected and ZeroNet connects to the peer directly to a custom file server that it implements. This is used to download the files required for the site. BitTorrent is only used for selecting peers, not for the site contents. Browsing is done through a standard web browser. The interface uses Websockets to communicate with the local node and receive real time information about site updates.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;technical-limitations&quot;&gt;Technical limitations&lt;a class=&quot;zola-anchor&quot; href=&quot;#technical-limitations&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Because the website is displayed in a sandboxed iframe there are some restrictions in what it can do. The most obvious is that only relative URLs work in anchor elements. If you click on an absolute URL it does nothing. The sandboxed iframe has the allow-top-navigation option which means you can link to external pages or other ZeroNet sites if you use the target attribute of the anchor element and set it to _top. So this will work:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;&amp;lt;a href=&amp;quot;http:&#x2F;&#x2F;example.com&#x2F;&amp;quot; target=&amp;quot;_top&amp;quot;&amp;gt;click me&amp;lt;&#x2F;a&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But this will not:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;&amp;lt;a href=&amp;quot;http:&#x2F;&#x2F;example.com&#x2F;&amp;quot;&amp;gt;click me&amp;lt;&#x2F;a&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Dynamic websites are supported, but requires help using centralized services. The ZeroNet node includes an example of a dynamic website called ‘ZeroBoard’. This site allows users to enter a message in a form and it’s published to a list of messages which all peering nodes will see. It does this by posting the message to an external web application that the author runs on the standard internet. This web app updates a file inside the sites ZeroNet directory and then signs it. The result is published to all peers and they automatically get the update through the Websocket interface.&lt;&#x2F;p&gt;
&lt;p&gt;Although this works it’s unfortunate that it relies on a centralized web application. The ZeroNet author has posted that they are looking at decentralized ways of doing this, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;HelloZeroNet&#x2F;ZeroNet&#x2F;issues&#x2F;65&quot;&gt;maybe&lt;&#x2F;a&gt; using &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bitmessage.org&#x2F;&quot;&gt;bitmessage&lt;&#x2F;a&gt; or some other system of the sort. Something resembling &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;peerjs.com&#x2F;&quot;&gt;peer to peer WebRTC&lt;&#x2F;a&gt; would be interesting, although it relies on the problematic WebRTC.&lt;&#x2F;p&gt;
&lt;p&gt;ZeroNet seems to be most similar to i2p or freenet. Compared to these it lacks the anonymity and encryption aspects. But it decentralizes the site content which i2p doesn’t. Freenet provides decentralization too but does not allow JavaScript in sites. ZeroNet does allow JavaScript but this has the usual security and tracking concerns. ZeroNet can and should be proxied via Tor (it supports it very well within its interface and recommends using it).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;relies-on-trackers&quot;&gt;Relies on trackers&lt;a class=&quot;zola-anchor&quot; href=&quot;#relies-on-trackers&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Although they are not hard to replace, ZeroNet relies on trackers to discover peers - not to be mistaken with your usual advertisment trackers. ZeroNet protocol is different from torrent, so standard DHT from libtorrent won’t work. Also bittorrent DHT is UDP based, so it will not work on Tor without proxying it to TCP. And it does not support storing Tor hidden service addresses, so you would not be able to create sites on Tor.&lt;&#x2F;p&gt;
&lt;p&gt;Further development is &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;HelloZeroNet&#x2F;ZeroNet&#x2F;issues&#x2F;57&quot;&gt;directed to implement a DHT-based discovery&lt;&#x2F;a&gt;, thus liberating from some pitfalls of a tracker-based infrastructure.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;an-example-of-a-heavy-site-play&quot;&gt;An example of a heavy site: Play&lt;a class=&quot;zola-anchor&quot; href=&quot;#an-example-of-a-heavy-site-play&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;As an uncensorable, unblockable medium, ZeroNet appeals to illegal content. Well, at least to copyright-infringing content distribution. Distributing some content also implies referencing it. A typical example would be thepiratebay, which has become a target for governments and rightsholders alike. So far, the answer has been to make the site copy-friendly, so that it can be recreated elsewhere quickly. With ZeroNet, it could not only be copied, but would be copied &lt;em&gt;all the time, by each visitor at least a little&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Play is such a site, with some limitations inherent to the technology used by ZeroNet. So far, these limitations cap the size of a site and thus limit the number of films referenced as magnet links Play can host, but it basically is a POC referencing magnet links of films found on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;rarbg.to&#x2F;&quot;&gt;rarbg.to&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;user-images.githubusercontent.com&#x2F;6329880&#x2F;29749028-39f1632a-8b23-11e7-8e40-7a4ecb36cb4f.jpg&quot; alt=&quot;A film entry showing a few magnet links in Play&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As everything in ZeroNet is stored client-side via the network overlay, no backend can be used without centralizing the data (which would make the site vulnerable again). So the cap on the site size hits much more than on a regular website. Indeed, a small 8GB database here become a database stored by users, and spread like a torrent would. It’s no problem, except that the whole data has to be signed again cryptographically to be spread, so its makes your data pretty difficult to generate &lt;em&gt;à la PHP&lt;&#x2F;em&gt;. Again, more &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;HelloZeroNet&#x2F;ZeroNet&#x2F;issues&#x2F;1053&quot;&gt;WIP&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It also forces you to rewrite your website to either a static version that can be committed to the network, or that uses interaction with users of the network via the frontend APIs provided by ZeroNet, or to use a spare backend that defeats the whole decentralized model. The latter should be avoided, and the second has all the limitations aforementioned. I guess that’s where the most friction will be felt in the community, but also where you can leverage the most out of ZeroNet. A future access to .onion sites from the ZeroNet client (since it is already so well integrating with Tor as a proxy) will provide sites the possibility to provide a .onion backend in addition, which will render the latter option more desirable, albeit still centralized.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;anyone-using-it&quot;&gt;Anyone using it?&lt;a class=&quot;zola-anchor&quot; href=&quot;#anyone-using-it&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;The base of ZeroNet itself is bundled with a default interface that helps discover the websites you access (who serves it, what kind of data from that site you have downloaded and wish to host), but also explore new ones via portals or the default links already included. Indeed, the ZeroNet projet also created a few POC sites to feature the possibilities.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;camo.githubusercontent.com&#x2F;4629a7d44a828f5bb20cedd90522ae62f0947b35&#x2F;68747470733a2f2f692e696d6775722e636f6d2f4836304f4148592e706e67&quot; alt=&quot;ZeroNet’s home interface&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As for these “main sites” provided by the development team, they feature a few hundred core users:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;CMS&#x2F;blog: &lt;code&gt;http:&#x2F;&#x2F;127.0.0.1:43110&#x2F;18zZNJnTry34f681g2Ur7S2gKsYa2LqPTr&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;social network: &lt;code&gt;http:&#x2F;&#x2F;127.0.0.1:43110&#x2F;Me.ZeroNetwork.bit&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;YouTube: &lt;code&gt;http:&#x2F;&#x2F;127.0.0.1:43110&#x2F;1FUQPLXHimgCvYHH7v3bJXspJ7bMBUXcEb&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;OpenStreetMap mirror: &lt;code&gt;http:&#x2F;&#x2F;127.0.0.1:43110&#x2F;1yUji4qPD7GAog8XkP3EDMEfrL995S4Xd&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;reddit alternative: &lt;code&gt;http:&#x2F;&#x2F;127.0.0.1:43110&#x2F;Board.ZeroNetwork.bit&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;forum: &lt;code&gt;http:&#x2F;&#x2F;127.0.0.1:43110&#x2F;Talk.ZeroNetwork.bit&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;search engine: &lt;code&gt;http:&#x2F;&#x2F;127.0.0.1:43110&#x2F;kaffiene.bit&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;email: &lt;code&gt;http:&#x2F;&#x2F;127.0.0.1:43110&#x2F;1MaiL5gfBM1cyb4a8e3iiL8L5gXmoAJu27&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The Github issues and PR feature a few hundred interactions as well, so you might not say they are just gonna stay at the alpha level, but they sure need so more love to push forward ideas and fix current infrastructure limitations.&lt;&#x2F;p&gt;
&lt;p&gt;Also, bear in mind ZeroNet is &lt;em&gt;not fully audited&lt;&#x2F;em&gt; and sees much less eyes on each commit that Tor does, for instance. So don’t put ultra-sensitive data there. It &lt;em&gt;will&lt;&#x2F;em&gt; eat your cat and burn your house.&lt;&#x2F;p&gt;
&lt;p&gt;I’m currently seeing the way sites are shared as quite futuristic (at least as a technology mix) and potentially very interesting if your goal is to spread information to &lt;em&gt;a lot of people&lt;&#x2F;em&gt; (see my &lt;a href=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;draft-notes-1&#x2F;&quot;&gt;draft about relieving alternatives to the cloud&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
</description>
                <content:encoded>&lt;p&gt;After testing a bit around Zeronet, I wanted to know how to create a somehow “heavy” site on ZeroNet. That is, a site hosting quite a lot a data (ex: YouTube clone). Exploring for ways to do this forced me to explore some intricacies of ZeroNet.&lt;&#x2F;p&gt;
&lt;p&gt;ZeroNet uses a combination of BitTorrent-like protocol, a custom file server and a web based user interface to create a fully decentralized internet overlay. The best thing of that big POC is that it manages to provide a pretty useable experience!&lt;&#x2F;p&gt;
&lt;p&gt;Users run a ZeroNet node and do their web browsing via the local proxy it provides (i.e.: using a local service port in your web browser of choice). Website addresses are public keys, generated using the same algorithm as used for bitcoin addresses. A request for a website key results in the node looking in the bittorrent network for peers that are seeding the site. Peers are selected and ZeroNet connects to the peer directly to a custom file server that it implements. This is used to download the files required for the site. BitTorrent is only used for selecting peers, not for the site contents. Browsing is done through a standard web browser. The interface uses Websockets to communicate with the local node and receive real time information about site updates.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;technical-limitations&quot;&gt;Technical limitations&lt;a class=&quot;zola-anchor&quot; href=&quot;#technical-limitations&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Because the website is displayed in a sandboxed iframe there are some restrictions in what it can do. The most obvious is that only relative URLs work in anchor elements. If you click on an absolute URL it does nothing. The sandboxed iframe has the allow-top-navigation option which means you can link to external pages or other ZeroNet sites if you use the target attribute of the anchor element and set it to _top. So this will work:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;&amp;lt;a href=&amp;quot;http:&#x2F;&#x2F;example.com&#x2F;&amp;quot; target=&amp;quot;_top&amp;quot;&amp;gt;click me&amp;lt;&#x2F;a&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But this will not:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;&amp;lt;a href=&amp;quot;http:&#x2F;&#x2F;example.com&#x2F;&amp;quot;&amp;gt;click me&amp;lt;&#x2F;a&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Dynamic websites are supported, but requires help using centralized services. The ZeroNet node includes an example of a dynamic website called ‘ZeroBoard’. This site allows users to enter a message in a form and it’s published to a list of messages which all peering nodes will see. It does this by posting the message to an external web application that the author runs on the standard internet. This web app updates a file inside the sites ZeroNet directory and then signs it. The result is published to all peers and they automatically get the update through the Websocket interface.&lt;&#x2F;p&gt;
&lt;p&gt;Although this works it’s unfortunate that it relies on a centralized web application. The ZeroNet author has posted that they are looking at decentralized ways of doing this, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;HelloZeroNet&#x2F;ZeroNet&#x2F;issues&#x2F;65&quot;&gt;maybe&lt;&#x2F;a&gt; using &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bitmessage.org&#x2F;&quot;&gt;bitmessage&lt;&#x2F;a&gt; or some other system of the sort. Something resembling &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;peerjs.com&#x2F;&quot;&gt;peer to peer WebRTC&lt;&#x2F;a&gt; would be interesting, although it relies on the problematic WebRTC.&lt;&#x2F;p&gt;
&lt;p&gt;ZeroNet seems to be most similar to i2p or freenet. Compared to these it lacks the anonymity and encryption aspects. But it decentralizes the site content which i2p doesn’t. Freenet provides decentralization too but does not allow JavaScript in sites. ZeroNet does allow JavaScript but this has the usual security and tracking concerns. ZeroNet can and should be proxied via Tor (it supports it very well within its interface and recommends using it).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;relies-on-trackers&quot;&gt;Relies on trackers&lt;a class=&quot;zola-anchor&quot; href=&quot;#relies-on-trackers&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Although they are not hard to replace, ZeroNet relies on trackers to discover peers - not to be mistaken with your usual advertisment trackers. ZeroNet protocol is different from torrent, so standard DHT from libtorrent won’t work. Also bittorrent DHT is UDP based, so it will not work on Tor without proxying it to TCP. And it does not support storing Tor hidden service addresses, so you would not be able to create sites on Tor.&lt;&#x2F;p&gt;
&lt;p&gt;Further development is &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;HelloZeroNet&#x2F;ZeroNet&#x2F;issues&#x2F;57&quot;&gt;directed to implement a DHT-based discovery&lt;&#x2F;a&gt;, thus liberating from some pitfalls of a tracker-based infrastructure.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;an-example-of-a-heavy-site-play&quot;&gt;An example of a heavy site: Play&lt;a class=&quot;zola-anchor&quot; href=&quot;#an-example-of-a-heavy-site-play&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;As an uncensorable, unblockable medium, ZeroNet appeals to illegal content. Well, at least to copyright-infringing content distribution. Distributing some content also implies referencing it. A typical example would be thepiratebay, which has become a target for governments and rightsholders alike. So far, the answer has been to make the site copy-friendly, so that it can be recreated elsewhere quickly. With ZeroNet, it could not only be copied, but would be copied &lt;em&gt;all the time, by each visitor at least a little&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Play is such a site, with some limitations inherent to the technology used by ZeroNet. So far, these limitations cap the size of a site and thus limit the number of films referenced as magnet links Play can host, but it basically is a POC referencing magnet links of films found on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;rarbg.to&#x2F;&quot;&gt;rarbg.to&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;user-images.githubusercontent.com&#x2F;6329880&#x2F;29749028-39f1632a-8b23-11e7-8e40-7a4ecb36cb4f.jpg&quot; alt=&quot;A film entry showing a few magnet links in Play&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As everything in ZeroNet is stored client-side via the network overlay, no backend can be used without centralizing the data (which would make the site vulnerable again). So the cap on the site size hits much more than on a regular website. Indeed, a small 8GB database here become a database stored by users, and spread like a torrent would. It’s no problem, except that the whole data has to be signed again cryptographically to be spread, so its makes your data pretty difficult to generate &lt;em&gt;à la PHP&lt;&#x2F;em&gt;. Again, more &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;HelloZeroNet&#x2F;ZeroNet&#x2F;issues&#x2F;1053&quot;&gt;WIP&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It also forces you to rewrite your website to either a static version that can be committed to the network, or that uses interaction with users of the network via the frontend APIs provided by ZeroNet, or to use a spare backend that defeats the whole decentralized model. The latter should be avoided, and the second has all the limitations aforementioned. I guess that’s where the most friction will be felt in the community, but also where you can leverage the most out of ZeroNet. A future access to .onion sites from the ZeroNet client (since it is already so well integrating with Tor as a proxy) will provide sites the possibility to provide a .onion backend in addition, which will render the latter option more desirable, albeit still centralized.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;anyone-using-it&quot;&gt;Anyone using it?&lt;a class=&quot;zola-anchor&quot; href=&quot;#anyone-using-it&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;The base of ZeroNet itself is bundled with a default interface that helps discover the websites you access (who serves it, what kind of data from that site you have downloaded and wish to host), but also explore new ones via portals or the default links already included. Indeed, the ZeroNet projet also created a few POC sites to feature the possibilities.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;camo.githubusercontent.com&#x2F;4629a7d44a828f5bb20cedd90522ae62f0947b35&#x2F;68747470733a2f2f692e696d6775722e636f6d2f4836304f4148592e706e67&quot; alt=&quot;ZeroNet’s home interface&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As for these “main sites” provided by the development team, they feature a few hundred core users:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;CMS&#x2F;blog: &lt;code&gt;http:&#x2F;&#x2F;127.0.0.1:43110&#x2F;18zZNJnTry34f681g2Ur7S2gKsYa2LqPTr&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;social network: &lt;code&gt;http:&#x2F;&#x2F;127.0.0.1:43110&#x2F;Me.ZeroNetwork.bit&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;YouTube: &lt;code&gt;http:&#x2F;&#x2F;127.0.0.1:43110&#x2F;1FUQPLXHimgCvYHH7v3bJXspJ7bMBUXcEb&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;OpenStreetMap mirror: &lt;code&gt;http:&#x2F;&#x2F;127.0.0.1:43110&#x2F;1yUji4qPD7GAog8XkP3EDMEfrL995S4Xd&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;reddit alternative: &lt;code&gt;http:&#x2F;&#x2F;127.0.0.1:43110&#x2F;Board.ZeroNetwork.bit&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;forum: &lt;code&gt;http:&#x2F;&#x2F;127.0.0.1:43110&#x2F;Talk.ZeroNetwork.bit&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;search engine: &lt;code&gt;http:&#x2F;&#x2F;127.0.0.1:43110&#x2F;kaffiene.bit&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;email: &lt;code&gt;http:&#x2F;&#x2F;127.0.0.1:43110&#x2F;1MaiL5gfBM1cyb4a8e3iiL8L5gXmoAJu27&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The Github issues and PR feature a few hundred interactions as well, so you might not say they are just gonna stay at the alpha level, but they sure need so more love to push forward ideas and fix current infrastructure limitations.&lt;&#x2F;p&gt;
&lt;p&gt;Also, bear in mind ZeroNet is &lt;em&gt;not fully audited&lt;&#x2F;em&gt; and sees much less eyes on each commit that Tor does, for instance. So don’t put ultra-sensitive data there. It &lt;em&gt;will&lt;&#x2F;em&gt; eat your cat and burn your house.&lt;&#x2F;p&gt;
&lt;p&gt;I’m currently seeing the way sites are shared as quite futuristic (at least as a technology mix) and potentially very interesting if your goal is to spread information to &lt;em&gt;a lot of people&lt;&#x2F;em&gt; (see my &lt;a href=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;draft-notes-1&#x2F;&quot;&gt;draft about relieving alternatives to the cloud&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
</content:encoded>
            </item>
        
            <item>
                <title>Draft notes #1</title>
                <pubDate>Thu, 24 Aug 2017 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/draft-notes-1/</link>
                <guid>https://rigelk.frama.io/blog/blog/draft-notes-1/</guid>
                <description>&lt;p&gt;This weeks feels empty enough so that I could reflect on my past readings about computer science stuff. A nice &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;blog.imirhil.fr&#x2F;2017&#x2F;07&#x2F;21&#x2F;iot-chaton-autohebergement.html&quot;&gt;critique about self-hosting&lt;&#x2F;a&gt; (in french) sprung some thoughts about why most (if not every) technical alternatives to cloud giants (GAFAM and like-minded companies) the open source community pushes is wrong. Let me rephrase it: the &lt;em&gt;cloud&lt;&#x2F;em&gt; needs alternatives, yet the existing ones are failing us because they can’t scale.&lt;&#x2F;p&gt;
&lt;p&gt;Scaling might be the pain point of every naescent startup, but it also is the one of the open source community. We often don’t realise it because scale is rarely ever reached, but it is a fact you cannot expect a lambda user to administer a machine &lt;em&gt;at all&lt;&#x2F;em&gt;. Even their own laptops are seldomly updated, all thanks to repeated popups only (*sigh*).&lt;&#x2F;p&gt;
&lt;p&gt;That’s why alternatives like YunoHost, Sandstorm, Cloudfoundry and others are never gonna scale. They are good for &lt;em&gt;advanced users&lt;&#x2F;em&gt; that have time and a broad knowledge of (non-exhaustive list) :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;command line&lt;&#x2F;li&gt;
&lt;li&gt;firewalls&lt;&#x2F;li&gt;
&lt;li&gt;x509 certificates&lt;&#x2F;li&gt;
&lt;li&gt;DNS and having a domain&lt;&#x2F;li&gt;
&lt;li&gt;IP lease&lt;&#x2F;li&gt;
&lt;li&gt;http proxy configuration&lt;&#x2F;li&gt;
&lt;li&gt;vhost&lt;&#x2F;li&gt;
&lt;li&gt;ssh&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Most computer science professionals don’t even know all these, much less master them. That’s why companies still make a business&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; out of making all this administration mess for you.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;Except we can’t trust them for the very reason they are here to make money and your data is a very appealing source of money.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;pushing-nicer-alternatives&quot;&gt;Pushing nicer alternatives&lt;a class=&quot;zola-anchor&quot; href=&quot;#pushing-nicer-alternatives&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;A sure fact is that the cloud model is working, because the machines, the servers, the software you rely on is actively maintained by professionals.&lt;&#x2F;p&gt;
&lt;p&gt;Nicer models are the ones which put you in control of your data&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; but also don’t put the pain at the same scale as the user population. The problem is, the only solution so far is creating silos - centralizing data the same way GAFAM already do. We wish for silos administration-wise as we’ve seen. But another pain point is that of money. Such structure provides services and all services don’t have the same cost: hosting a video is expensive, hosting a pad (raw text) is inexpensive. Both are very popular but technically one brings a lot of stress on the provider’s infrastructure&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;being “in control” means here either having full control on it (hosting, access) or at least hosting your data at a trusted third party. The subjective notion of trust means you might consider more or less third parties trustworthy depending on how strong you want this trust to be. Some for-profits advertise on not selling or looking at your data, but your standards might be higher, especially if you want a proof of trust (ie. code).&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;3&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;3&lt;&#x2F;sup&gt;
&lt;p&gt;as shown with Alphabet’s YouTube (Google) &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.wsj.com&#x2F;articles&#x2F;viewers-dont-add-up-to-profit-for-youtube-1424897967&quot;&gt;example analysis from the WSJ&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;technology-split-or-solidarity&quot;&gt;Technology split or solidarity&lt;a class=&quot;zola-anchor&quot; href=&quot;#technology-split-or-solidarity&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Expensive services are going to pull down smaller structures like associations if they don’t unite to raise money and share the expenses. It needs coordination, and definitely cannot be like YouTube. Nice alternatives relying on WebRTC exist to lessen the load on servers&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#4&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, and some more obscure (and alpha software) like ZeroNet provide fully decentralized YouTube drafts that would not rely on any central structure to bear the costs. Right now, only the former provides a viable technical alternative.&lt;&#x2F;p&gt;
&lt;p&gt;As for a more classic alternative, there is the possibility of making a federation of service providers, that would help them split the heaviest costs. It has apparently already proved efficient with FDN, a french ISP. That also seems like a saner solution since &lt;em&gt;software cannot save the world, but people can&lt;&#x2F;em&gt;. Ethical organizations like the ones shown at &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.franciliens.net&#x2F;&quot;&gt;Franciliens&lt;&#x2F;a&gt; or FDN can. They have the big advantage of relying on humans rather than software to adapt to the problem of financing, and can react to a lack of funds. Building on software - however promising - always takes time, as shown with ZeroNet’s option.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;4&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;4&lt;&#x2F;sup&gt;
&lt;p&gt;with the drawback of relying on WebRTC, which is known to provide another way to leak your local IP address, even under the presence of a VPN.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</description>
                <content:encoded>&lt;p&gt;This weeks feels empty enough so that I could reflect on my past readings about computer science stuff. A nice &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;blog.imirhil.fr&#x2F;2017&#x2F;07&#x2F;21&#x2F;iot-chaton-autohebergement.html&quot;&gt;critique about self-hosting&lt;&#x2F;a&gt; (in french) sprung some thoughts about why most (if not every) technical alternatives to cloud giants (GAFAM and like-minded companies) the open source community pushes is wrong. Let me rephrase it: the &lt;em&gt;cloud&lt;&#x2F;em&gt; needs alternatives, yet the existing ones are failing us because they can’t scale.&lt;&#x2F;p&gt;
&lt;p&gt;Scaling might be the pain point of every naescent startup, but it also is the one of the open source community. We often don’t realise it because scale is rarely ever reached, but it is a fact you cannot expect a lambda user to administer a machine &lt;em&gt;at all&lt;&#x2F;em&gt;. Even their own laptops are seldomly updated, all thanks to repeated popups only (*sigh*).&lt;&#x2F;p&gt;
&lt;p&gt;That’s why alternatives like YunoHost, Sandstorm, Cloudfoundry and others are never gonna scale. They are good for &lt;em&gt;advanced users&lt;&#x2F;em&gt; that have time and a broad knowledge of (non-exhaustive list) :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;command line&lt;&#x2F;li&gt;
&lt;li&gt;firewalls&lt;&#x2F;li&gt;
&lt;li&gt;x509 certificates&lt;&#x2F;li&gt;
&lt;li&gt;DNS and having a domain&lt;&#x2F;li&gt;
&lt;li&gt;IP lease&lt;&#x2F;li&gt;
&lt;li&gt;http proxy configuration&lt;&#x2F;li&gt;
&lt;li&gt;vhost&lt;&#x2F;li&gt;
&lt;li&gt;ssh&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Most computer science professionals don’t even know all these, much less master them. That’s why companies still make a business&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; out of making all this administration mess for you.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;Except we can’t trust them for the very reason they are here to make money and your data is a very appealing source of money.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;pushing-nicer-alternatives&quot;&gt;Pushing nicer alternatives&lt;a class=&quot;zola-anchor&quot; href=&quot;#pushing-nicer-alternatives&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;A sure fact is that the cloud model is working, because the machines, the servers, the software you rely on is actively maintained by professionals.&lt;&#x2F;p&gt;
&lt;p&gt;Nicer models are the ones which put you in control of your data&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; but also don’t put the pain at the same scale as the user population. The problem is, the only solution so far is creating silos - centralizing data the same way GAFAM already do. We wish for silos administration-wise as we’ve seen. But another pain point is that of money. Such structure provides services and all services don’t have the same cost: hosting a video is expensive, hosting a pad (raw text) is inexpensive. Both are very popular but technically one brings a lot of stress on the provider’s infrastructure&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;being “in control” means here either having full control on it (hosting, access) or at least hosting your data at a trusted third party. The subjective notion of trust means you might consider more or less third parties trustworthy depending on how strong you want this trust to be. Some for-profits advertise on not selling or looking at your data, but your standards might be higher, especially if you want a proof of trust (ie. code).&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;3&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;3&lt;&#x2F;sup&gt;
&lt;p&gt;as shown with Alphabet’s YouTube (Google) &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.wsj.com&#x2F;articles&#x2F;viewers-dont-add-up-to-profit-for-youtube-1424897967&quot;&gt;example analysis from the WSJ&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;technology-split-or-solidarity&quot;&gt;Technology split or solidarity&lt;a class=&quot;zola-anchor&quot; href=&quot;#technology-split-or-solidarity&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Expensive services are going to pull down smaller structures like associations if they don’t unite to raise money and share the expenses. It needs coordination, and definitely cannot be like YouTube. Nice alternatives relying on WebRTC exist to lessen the load on servers&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#4&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, and some more obscure (and alpha software) like ZeroNet provide fully decentralized YouTube drafts that would not rely on any central structure to bear the costs. Right now, only the former provides a viable technical alternative.&lt;&#x2F;p&gt;
&lt;p&gt;As for a more classic alternative, there is the possibility of making a federation of service providers, that would help them split the heaviest costs. It has apparently already proved efficient with FDN, a french ISP. That also seems like a saner solution since &lt;em&gt;software cannot save the world, but people can&lt;&#x2F;em&gt;. Ethical organizations like the ones shown at &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.franciliens.net&#x2F;&quot;&gt;Franciliens&lt;&#x2F;a&gt; or FDN can. They have the big advantage of relying on humans rather than software to adapt to the problem of financing, and can react to a lack of funds. Building on software - however promising - always takes time, as shown with ZeroNet’s option.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;4&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;4&lt;&#x2F;sup&gt;
&lt;p&gt;with the drawback of relying on WebRTC, which is known to provide another way to leak your local IP address, even under the presence of a VPN.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content:encoded>
            </item>
        
            <item>
                <title>Building LineageOS for my Mate 8</title>
                <pubDate>Thu, 17 Aug 2017 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/building-lineageos-mate-8/</link>
                <guid>https://rigelk.frama.io/blog/blog/building-lineageos-mate-8/</guid>
                <description>&lt;p&gt;Android, being open-source, means people can take the code, make their modifications and publish it. CyanogenMod was one such project, bringing many features on top of AOSP (standard) Android we now take for granted. After some trouble with commercialisation, the project rebranded as LineageOS in December 2016. At the time of writing, the project is basically just the code from cm-14.1. Bigger changes will come when a new Android version is released to the Android Open Source Project.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;requirements&quot;&gt;Requirements&lt;a class=&quot;zola-anchor&quot; href=&quot;#requirements&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;You’re going to need:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;a recent *Nix system&lt;&#x2F;li&gt;
&lt;li&gt;a reasonable knowledge of the command line&lt;&#x2F;li&gt;
&lt;li&gt;8GB+ RAM&lt;&#x2F;li&gt;
&lt;li&gt;Dual-core+ CPU&lt;&#x2F;li&gt;
&lt;li&gt;Lots of disk space (~50GB for the actual source code, ~30GB per device and however much you want for cache)&lt;&#x2F;li&gt;
&lt;li&gt;10mbps+ internet (if you want to get anything done)&lt;&#x2F;li&gt;
&lt;li&gt;sudo privileges&lt;&#x2F;li&gt;
&lt;li&gt;a Huawei Mate 8 (of course :))&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;open_mate_8.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
    
      &lt;source srcset=&quot;open_mate_8.jpg&quot; type=&quot;image&#x2F;jpeg&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;open_mate_8.jpg&quot; &#x2F;&gt;
    
    
  &lt;&#x2F;picture&gt;

  
&lt;&#x2F;div&gt;
&lt;p&gt;You don’t need to have it wide open like above, just a cable to connect it via USB.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;dependancies&quot;&gt;Dependancies&lt;a class=&quot;zola-anchor&quot; href=&quot;#dependancies&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;bc bison build-essential curl flex git gnupg gperf libesd0-dev liblz4-tool libncurses5-dev libsdl1.2-dev libwxgtk3.0-dev libxml2 libxml2-utils lzop maven openjdk-8-jdk pngcrush schedtool squashfs-tools xsltproc zip zlib1g-dev android-tools-adb android-tools-fastboot&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Additionally for 64bit systems, &lt;code&gt;g++-multilib gcc-multilib lib32ncurses5-dev lib32readline6-dev lib32z1-dev&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Now we also need &lt;code&gt;repo&lt;&#x2F;code&gt;, a tool written by Google to manage git repositories. It’s not the best (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tankerapp&#x2F;tsrc&quot;&gt;tsrc&lt;&#x2F;a&gt; could be better), but it’s the one chosen by the project to download all its parts easily and you should stick to it.&lt;&#x2F;p&gt;
&lt;p&gt;Ensure you have &lt;em&gt;openjdk 8&lt;&#x2F;em&gt; and the Android SDK in your path (installed).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;prebuild-parameters&quot;&gt;Prebuild parameters&lt;a class=&quot;zola-anchor&quot; href=&quot;#prebuild-parameters&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;RAM&lt;&#x2F;strong&gt;: an important consideration, as you need a decent amount. You need at least 4GB really, but I made mine 6G, so I wouldn’t run into problems: &lt;code&gt;export ANDROID_JACK_VM_ARGS=&quot;-Xmx6g -Dfile.encoding=UTF-8 -XX:+TieredCompilation&quot;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;CCACHE&lt;&#x2F;strong&gt;: CCACHE is amazing. When you get round to building, it checks to see what has changed and only builds files that are different from the build. This saves unbelievable amounts of time, as some files, hardly ever touched, only need to be built once! Activate it with &lt;code&gt;export USE_CCACHE=1&lt;&#x2F;code&gt; and &lt;code&gt;prebuilts&#x2F;misc&#x2F;linux-x86&#x2F;ccache&#x2F;ccache -M 50G&lt;&#x2F;code&gt; where 50 is the disk space you wish to allocate to it.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;getting-the-code&quot;&gt;Getting the code&lt;a class=&quot;zola-anchor&quot; href=&quot;#getting-the-code&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# make the folder to store all the Android code
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# This is where you can choose to store all this somewhere else
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;mkdir -p ~&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;android&#x2F;system
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Move into the directory, ready to start downloading
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;cd &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;~&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;android&#x2F;system&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Tell repo what we want to download
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# init = initialise the repositories
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# https:&#x2F;&#x2F;github.com&#x2F;LineageOS&#x2F;android.git = the list of repositories to download
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# -b cm-14.1 =  the branch or version of code we are downloading
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#               this will change depending on the version *you* want. This is for cm-14.1 (CyanogenMod 14.1 based on Android 7.1.1)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;repo&lt;&#x2F;span&gt;&lt;span&gt; init&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -u&lt;&#x2F;span&gt;&lt;span&gt; https:&#x2F;&#x2F;github.com&#x2F;LineageOS&#x2F;android.git&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -b&lt;&#x2F;span&gt;&lt;span&gt; cm-14.1
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Start the download
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;repo&lt;&#x2F;span&gt;&lt;span&gt; sync
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point, (unless you have gigabit internet), go get a &lt;del&gt;coffee&lt;&#x2F;del&gt; day off. This is gonna take a HUGE while.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;device-specific-code&quot;&gt;Device-specific code&lt;a class=&quot;zola-anchor&quot; href=&quot;#device-specific-code&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;The code we just downloaded is the general or common code for Android. Put simply, it’s the stuff that’s the same on all the devices.&lt;&#x2F;p&gt;
&lt;p&gt;To get specific files for a device (such as angler), we need to tell repo which device you want. As well as the open-source device specifics, you need some proprietary files (things like camera libraries or sound FX libraries). These can be either extracted from a device already running stock android: (with Developer Settings enabled - tap on Build number in Settings &amp;gt; About seven times), but are best downloaded online.&lt;&#x2F;p&gt;
&lt;p&gt;Just replace yourdevicecodenamehere with your device’s codename. For instance, the Nexus 6P’s is &lt;em&gt;angler&lt;&#x2F;em&gt;, the Nexus 9’s is &lt;em&gt;flounder&lt;&#x2F;em&gt; and Motorola Moto G (2013)’s is &lt;em&gt;falcon&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;source&lt;&#x2F;span&gt;&lt;span&gt; build&#x2F;envsetup.sh
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;breakfast&lt;&#x2F;span&gt;&lt;span&gt; yourdevicecodenamehere
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You should see some errors, at which point you want to download the proprietary code for your manufacturer. All this can be done in the next section, once we go through some terms.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;proprietary-files&quot;&gt;Proprietary files&lt;a class=&quot;zola-anchor&quot; href=&quot;#proprietary-files&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Repo decides what repositories to download by looking through manifests. The main manifest (downloaded when we initialised repo) is present in &lt;code&gt;~&#x2F;home&#x2F;yourusername&#x2F;android&#x2F;system&#x2F;.repo&#x2F;manifest.xml&lt;&#x2F;code&gt; and contains loads of repos needed for building common Android files.&lt;&#x2F;p&gt;
&lt;p&gt;You could edit this file, but since this is updated when new things are added to Android, your changes would always be being overwritten. So the better option is to use local manifests. If you edit &lt;code&gt;~&#x2F;home&#x2F;yourusername&#x2F;android&#x2F;system&#x2F;.repo&#x2F;local_manifests&#x2F;roomservice.xml&lt;&#x2F;code&gt;, where you can add and remove your own repos to the main list, without editing the main manifest.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;why-on-earth-might-you-do-this&quot;&gt;Why on earth might you do this?&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-on-earth-might-you-do-this&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;If you want to make changes to device specific files, or even common Android things, you can fork the repository you’d like to change. You can make your changes in this repo (which you own) and then incorporate those changes into your builds.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;how-do-i-make-a-manifest-then&quot;&gt;How do I make a manifest then?&lt;a class=&quot;zola-anchor&quot; href=&quot;#how-do-i-make-a-manifest-then&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Edit roomservice: &lt;code&gt;nano ~&#x2F;android&#x2F;system&#x2F;.repo&#x2F;local_manifests&#x2F;roomservice.xml&lt;&#x2F;code&gt; You should see some content already here, based loosely on this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;xml&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span&gt;&amp;lt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;xml &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;version&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;encoding&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;UTF-8&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;?&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;manifest&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;remote &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;github&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;fetch&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;review&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;review.lineageos.org&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &#x2F;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;project &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;path&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;where&#x2F;the&#x2F;files&#x2F;need&#x2F;to&#x2F;go&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;LineageOS&#x2F;name_of_repo&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;remote&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;github&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&#x2F;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;manifest&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This contains all the device-specific code (excluding the proprietary stuff). To download the proprietary stuff, wander over to TheMuppets GitHub and search for your manufacturer. Take note of the name of the repository. Then add this before &lt;code&gt;&amp;lt;&#x2F;manifest&amp;gt;&lt;&#x2F;code&gt; at the bottom of the file:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;xml&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;project &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;path&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;vendor&#x2F;MANUFACTURER&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;TheMuppets&#x2F;NAME_OF_REPO&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;remote&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;github&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&#x2F;&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For instance, as I want to work on Paul Fasola’s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;PaulFasola&#x2F;android_device_huawei_next&quot;&gt;WIP for the Huawei Mate 8&lt;&#x2F;a&gt;, I find its local manifest in &lt;code&gt;local_manifests&#x2F;roomservice.xml&lt;&#x2F;code&gt; and copy&#x2F;append it to &lt;code&gt;.repo&#x2F;local_manifests&#x2F;roomservice.xml&lt;&#x2F;code&gt;. Putting the code you will further develop in a repository dedicated to the device is a nice way to share your code, and ideally should integrate with &lt;code&gt;repo&lt;&#x2F;code&gt; (see the &lt;a href=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;building-lineageos-mate-8&#x2F;#sharing-your-code&quot;&gt;dedicated section&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;After you’ve made any changes to your manifest or want to update the code from LineageOS, run:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# From your ~&#x2F;android&#x2F;system directory
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;repo&lt;&#x2F;span&gt;&lt;span&gt; sync
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;first-build&quot;&gt;First build&lt;a class=&quot;zola-anchor&quot; href=&quot;#first-build&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Before you do anything, make sure your codebase is up-to-date:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# From your ~&#x2F;android&#x2F;system directory
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;repo&lt;&#x2F;span&gt;&lt;span&gt; sync
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then simply:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Replace DEVICECODENAME with the device&amp;#39;s codename in lowercase
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;brunch&lt;&#x2F;span&gt;&lt;span&gt; DEVICECODENAME
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now it’s time for another coffee :-)&lt;&#x2F;p&gt;
&lt;p&gt;When it’s done (returned you back to the shell prompt), you should find the build under &lt;code&gt;~&#x2F;android&#x2F;system&#x2F;out&#x2F;target&#x2F;product&#x2F;DEVICECODENAME&#x2F;&lt;&#x2F;code&gt; called something like &lt;code&gt;cm-14.1-20161231-UNOFFICIAL-DEVICECODENAME.zip&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;!! &lt;strong&gt;Warning:&lt;&#x2F;strong&gt; You can install this image as any other official image, with again, &lt;em&gt;results that will eat your cat&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Remember, you assume all risk of trying this, but you will reap the rewards! It’s pretty satisfying to boot into a fresh operating system you baked at home, and it gives you knowledge of what’s inside.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;going-further&quot;&gt;Going further&lt;a class=&quot;zola-anchor&quot; href=&quot;#going-further&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;sharing-your-code&quot;&gt;Sharing your code&lt;a class=&quot;zola-anchor&quot; href=&quot;#sharing-your-code&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Sharing is caring, but it’s also an important feature of LineageOS since it’s built in a very composable way. Understanding how it is shared will help you get all the parts you need to build your custom&#x2F;WIP ROM.&lt;&#x2F;p&gt;
&lt;p&gt;Once you’ve started your device folder, create your own GitHub account and set up your folder as a public GitHub repository. This is a great opportunity to learn about git, and also your source can be accessible to others who can collaborate with you.&lt;&#x2F;p&gt;
&lt;p&gt;When naming your repository, use the format &lt;code&gt;android_device_VENDOR_CODENAME&lt;&#x2F;code&gt;, where &lt;code&gt;VENDOR&lt;&#x2F;code&gt; and &lt;code&gt;CODENAME&lt;&#x2F;code&gt; use the new device’s values. So, let’s say your GitHub account name is “fat-tire” and your device codename is “encore”, manufactured by Barnes and Noble. You should call your repository android_device_bn_encore. It would be accessible at https:&#x2F;&#x2F;github.com&#x2F;fat-tire&#x2F;android_device_bn_encore. Similarly, the kernel repository would be called android_kernel_bn_encore. It would be accessible at https:&#x2F;&#x2F;github.com&#x2F;fat-tire&#x2F;android_kernel_bn_encore.&lt;&#x2F;p&gt;
&lt;p&gt;The last thing to do is create a local manifest for other people to use to automatically download and their keep up-to-date with your changes. Here’s an example, using the above scenario:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;xml&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span&gt;&amp;lt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;xml &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;version&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;encoding&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;UTF-8&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;?&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;manifest&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;project &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;fat-tire&#x2F;android_device_bn_encore&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;path&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;device&#x2F;bn&#x2F;encore&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;remote&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;github&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;revision&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;cm-10.1&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &#x2F;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;project &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;fat-tire&#x2F;android_kernel_bn_encore&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;path&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;kernel&#x2F;bn&#x2F;encore&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;remote&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;github&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;revision&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;cm-10.1&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &#x2F;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;manifest&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;! &lt;strong&gt;note:&lt;&#x2F;strong&gt; the revision attribute is optional. If it is omitted, &lt;code&gt;repo&lt;&#x2F;code&gt; sync will use the revision specified by the &lt;code&gt;&amp;lt;default ... &#x2F;&amp;gt;&lt;&#x2F;code&gt; tag in the default manifest.&lt;&#x2F;p&gt;
&lt;p&gt;Once you’ve tested that the local manifest file works, you can pass it on to others, who can then try out your work.&lt;&#x2F;p&gt;
&lt;p&gt;! &lt;strong&gt;note:&lt;&#x2F;strong&gt; if you find that for some reason you need to replace or supplement other repositories provided by LineageOS, you can add additional repositories using the local manifest. Once you’ve got everything working, you can use Gerrit to submit stuff found in those repositories back upstream to CyanogenMod.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;adding-xml-overlays&quot;&gt;Adding XML overlays&lt;a class=&quot;zola-anchor&quot; href=&quot;#adding-xml-overlays&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;It’s very likely in your &lt;code&gt;device_[codename].mk&lt;&#x2F;code&gt; file, there’s a line that looks like this:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;DEVICE_PACKAGE_OVERLAYS := \
&lt;&#x2F;span&gt;&lt;span&gt;    device&#x2F;[vendor]&#x2F;[codename]&#x2F;overlay
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;What this does is set the &lt;code&gt;overlay&#x2F;&lt;&#x2F;code&gt; folder to allow you to override any XML file used by Android frameworks or apps, just for this device. To do so, create a directory structure which mirrors the path leading to an XML file, starting from the root of your source. Then replace the file you want to overlay.&lt;&#x2F;p&gt;
&lt;p&gt;Example: Let’s say you want to override some standard Android settings. Look at the file in &lt;code&gt;frameworks&#x2F;base&#x2F;core&#x2F;res&#x2F;res&#x2F;values&#x2F;config.xml&lt;&#x2F;code&gt;. Then copy it to &lt;code&gt;device&#x2F;[vendor]&#x2F;[codename]&#x2F;overlay&#x2F;frameworks&#x2F;base&#x2F;core&#x2F;res&#x2F;res&#x2F;values&#x2F;config.xml&lt;&#x2F;code&gt;. Now YOUR version will be used instead of the other one. You only need to include the settings you wish to override - not all of them, so you can pare down the file to those few that change from the default.&lt;&#x2F;p&gt;
&lt;p&gt;You can overlay any XML file, affecting layouts, settings, preferences, translations, and more.&lt;&#x2F;p&gt;
</description>
                <content:encoded>&lt;p&gt;Android, being open-source, means people can take the code, make their modifications and publish it. CyanogenMod was one such project, bringing many features on top of AOSP (standard) Android we now take for granted. After some trouble with commercialisation, the project rebranded as LineageOS in December 2016. At the time of writing, the project is basically just the code from cm-14.1. Bigger changes will come when a new Android version is released to the Android Open Source Project.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;requirements&quot;&gt;Requirements&lt;a class=&quot;zola-anchor&quot; href=&quot;#requirements&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;You’re going to need:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;a recent *Nix system&lt;&#x2F;li&gt;
&lt;li&gt;a reasonable knowledge of the command line&lt;&#x2F;li&gt;
&lt;li&gt;8GB+ RAM&lt;&#x2F;li&gt;
&lt;li&gt;Dual-core+ CPU&lt;&#x2F;li&gt;
&lt;li&gt;Lots of disk space (~50GB for the actual source code, ~30GB per device and however much you want for cache)&lt;&#x2F;li&gt;
&lt;li&gt;10mbps+ internet (if you want to get anything done)&lt;&#x2F;li&gt;
&lt;li&gt;sudo privileges&lt;&#x2F;li&gt;
&lt;li&gt;a Huawei Mate 8 (of course :))&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;div class=&quot;flex flex-column&quot;&gt;
  &lt;picture class=&quot;flex&quot; x-data=&quot;{ open: true }&quot;&gt;
    &lt;div class=&quot;js-only sensitive-content-actions&quot; x-show=&quot;!open&quot;&gt;
      &lt;button class=&quot;f6 link dim br1 ba ph3 pv2 mb2 bg-light-gray&quot; @click=&quot;open = true&quot;&gt;view sensitive content&lt;&#x2F;button&gt;
    &lt;&#x2F;div&gt;

    &lt;source srcset=&quot;open_mate_8.webp&quot; type=&quot;image&#x2F;webp&quot;&gt;
    
    
      &lt;source srcset=&quot;open_mate_8.jpg&quot; type=&quot;image&#x2F;jpeg&quot;&gt;
      &lt;img :class=&quot;{ &#x27;blurred&#x27;: !open }&quot; src=&quot;open_mate_8.jpg&quot; &#x2F;&gt;
    
    
  &lt;&#x2F;picture&gt;

  
&lt;&#x2F;div&gt;
&lt;p&gt;You don’t need to have it wide open like above, just a cable to connect it via USB.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;dependancies&quot;&gt;Dependancies&lt;a class=&quot;zola-anchor&quot; href=&quot;#dependancies&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;bc bison build-essential curl flex git gnupg gperf libesd0-dev liblz4-tool libncurses5-dev libsdl1.2-dev libwxgtk3.0-dev libxml2 libxml2-utils lzop maven openjdk-8-jdk pngcrush schedtool squashfs-tools xsltproc zip zlib1g-dev android-tools-adb android-tools-fastboot&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Additionally for 64bit systems, &lt;code&gt;g++-multilib gcc-multilib lib32ncurses5-dev lib32readline6-dev lib32z1-dev&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Now we also need &lt;code&gt;repo&lt;&#x2F;code&gt;, a tool written by Google to manage git repositories. It’s not the best (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tankerapp&#x2F;tsrc&quot;&gt;tsrc&lt;&#x2F;a&gt; could be better), but it’s the one chosen by the project to download all its parts easily and you should stick to it.&lt;&#x2F;p&gt;
&lt;p&gt;Ensure you have &lt;em&gt;openjdk 8&lt;&#x2F;em&gt; and the Android SDK in your path (installed).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;prebuild-parameters&quot;&gt;Prebuild parameters&lt;a class=&quot;zola-anchor&quot; href=&quot;#prebuild-parameters&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;RAM&lt;&#x2F;strong&gt;: an important consideration, as you need a decent amount. You need at least 4GB really, but I made mine 6G, so I wouldn’t run into problems: &lt;code&gt;export ANDROID_JACK_VM_ARGS=&quot;-Xmx6g -Dfile.encoding=UTF-8 -XX:+TieredCompilation&quot;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;CCACHE&lt;&#x2F;strong&gt;: CCACHE is amazing. When you get round to building, it checks to see what has changed and only builds files that are different from the build. This saves unbelievable amounts of time, as some files, hardly ever touched, only need to be built once! Activate it with &lt;code&gt;export USE_CCACHE=1&lt;&#x2F;code&gt; and &lt;code&gt;prebuilts&#x2F;misc&#x2F;linux-x86&#x2F;ccache&#x2F;ccache -M 50G&lt;&#x2F;code&gt; where 50 is the disk space you wish to allocate to it.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;getting-the-code&quot;&gt;Getting the code&lt;a class=&quot;zola-anchor&quot; href=&quot;#getting-the-code&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# make the folder to store all the Android code
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# This is where you can choose to store all this somewhere else
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;mkdir -p ~&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;android&#x2F;system
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Move into the directory, ready to start downloading
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;cd &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;~&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;android&#x2F;system&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Tell repo what we want to download
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# init = initialise the repositories
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# https:&#x2F;&#x2F;github.com&#x2F;LineageOS&#x2F;android.git = the list of repositories to download
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# -b cm-14.1 =  the branch or version of code we are downloading
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#               this will change depending on the version *you* want. This is for cm-14.1 (CyanogenMod 14.1 based on Android 7.1.1)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;repo&lt;&#x2F;span&gt;&lt;span&gt; init&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -u&lt;&#x2F;span&gt;&lt;span&gt; https:&#x2F;&#x2F;github.com&#x2F;LineageOS&#x2F;android.git&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -b&lt;&#x2F;span&gt;&lt;span&gt; cm-14.1
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Start the download
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;repo&lt;&#x2F;span&gt;&lt;span&gt; sync
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point, (unless you have gigabit internet), go get a &lt;del&gt;coffee&lt;&#x2F;del&gt; day off. This is gonna take a HUGE while.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;device-specific-code&quot;&gt;Device-specific code&lt;a class=&quot;zola-anchor&quot; href=&quot;#device-specific-code&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;The code we just downloaded is the general or common code for Android. Put simply, it’s the stuff that’s the same on all the devices.&lt;&#x2F;p&gt;
&lt;p&gt;To get specific files for a device (such as angler), we need to tell repo which device you want. As well as the open-source device specifics, you need some proprietary files (things like camera libraries or sound FX libraries). These can be either extracted from a device already running stock android: (with Developer Settings enabled - tap on Build number in Settings &amp;gt; About seven times), but are best downloaded online.&lt;&#x2F;p&gt;
&lt;p&gt;Just replace yourdevicecodenamehere with your device’s codename. For instance, the Nexus 6P’s is &lt;em&gt;angler&lt;&#x2F;em&gt;, the Nexus 9’s is &lt;em&gt;flounder&lt;&#x2F;em&gt; and Motorola Moto G (2013)’s is &lt;em&gt;falcon&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;source&lt;&#x2F;span&gt;&lt;span&gt; build&#x2F;envsetup.sh
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;breakfast&lt;&#x2F;span&gt;&lt;span&gt; yourdevicecodenamehere
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You should see some errors, at which point you want to download the proprietary code for your manufacturer. All this can be done in the next section, once we go through some terms.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;proprietary-files&quot;&gt;Proprietary files&lt;a class=&quot;zola-anchor&quot; href=&quot;#proprietary-files&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Repo decides what repositories to download by looking through manifests. The main manifest (downloaded when we initialised repo) is present in &lt;code&gt;~&#x2F;home&#x2F;yourusername&#x2F;android&#x2F;system&#x2F;.repo&#x2F;manifest.xml&lt;&#x2F;code&gt; and contains loads of repos needed for building common Android files.&lt;&#x2F;p&gt;
&lt;p&gt;You could edit this file, but since this is updated when new things are added to Android, your changes would always be being overwritten. So the better option is to use local manifests. If you edit &lt;code&gt;~&#x2F;home&#x2F;yourusername&#x2F;android&#x2F;system&#x2F;.repo&#x2F;local_manifests&#x2F;roomservice.xml&lt;&#x2F;code&gt;, where you can add and remove your own repos to the main list, without editing the main manifest.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;why-on-earth-might-you-do-this&quot;&gt;Why on earth might you do this?&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-on-earth-might-you-do-this&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;If you want to make changes to device specific files, or even common Android things, you can fork the repository you’d like to change. You can make your changes in this repo (which you own) and then incorporate those changes into your builds.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;how-do-i-make-a-manifest-then&quot;&gt;How do I make a manifest then?&lt;a class=&quot;zola-anchor&quot; href=&quot;#how-do-i-make-a-manifest-then&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h4&gt;
&lt;p&gt;Edit roomservice: &lt;code&gt;nano ~&#x2F;android&#x2F;system&#x2F;.repo&#x2F;local_manifests&#x2F;roomservice.xml&lt;&#x2F;code&gt; You should see some content already here, based loosely on this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;xml&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span&gt;&amp;lt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;xml &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;version&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;encoding&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;UTF-8&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;?&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;manifest&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;remote &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;github&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;fetch&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;..&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;review&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;review.lineageos.org&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &#x2F;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;project &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;path&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;where&#x2F;the&#x2F;files&#x2F;need&#x2F;to&#x2F;go&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;LineageOS&#x2F;name_of_repo&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;remote&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;github&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&#x2F;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;manifest&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This contains all the device-specific code (excluding the proprietary stuff). To download the proprietary stuff, wander over to TheMuppets GitHub and search for your manufacturer. Take note of the name of the repository. Then add this before &lt;code&gt;&amp;lt;&#x2F;manifest&amp;gt;&lt;&#x2F;code&gt; at the bottom of the file:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;xml&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;project &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;path&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;vendor&#x2F;MANUFACTURER&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;TheMuppets&#x2F;NAME_OF_REPO&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;remote&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;github&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&#x2F;&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For instance, as I want to work on Paul Fasola’s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;PaulFasola&#x2F;android_device_huawei_next&quot;&gt;WIP for the Huawei Mate 8&lt;&#x2F;a&gt;, I find its local manifest in &lt;code&gt;local_manifests&#x2F;roomservice.xml&lt;&#x2F;code&gt; and copy&#x2F;append it to &lt;code&gt;.repo&#x2F;local_manifests&#x2F;roomservice.xml&lt;&#x2F;code&gt;. Putting the code you will further develop in a repository dedicated to the device is a nice way to share your code, and ideally should integrate with &lt;code&gt;repo&lt;&#x2F;code&gt; (see the &lt;a href=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;building-lineageos-mate-8&#x2F;#sharing-your-code&quot;&gt;dedicated section&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;After you’ve made any changes to your manifest or want to update the code from LineageOS, run:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# From your ~&#x2F;android&#x2F;system directory
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;repo&lt;&#x2F;span&gt;&lt;span&gt; sync
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;first-build&quot;&gt;First build&lt;a class=&quot;zola-anchor&quot; href=&quot;#first-build&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Before you do anything, make sure your codebase is up-to-date:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# From your ~&#x2F;android&#x2F;system directory
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;repo&lt;&#x2F;span&gt;&lt;span&gt; sync
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then simply:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Replace DEVICECODENAME with the device&amp;#39;s codename in lowercase
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;brunch&lt;&#x2F;span&gt;&lt;span&gt; DEVICECODENAME
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now it’s time for another coffee :-)&lt;&#x2F;p&gt;
&lt;p&gt;When it’s done (returned you back to the shell prompt), you should find the build under &lt;code&gt;~&#x2F;android&#x2F;system&#x2F;out&#x2F;target&#x2F;product&#x2F;DEVICECODENAME&#x2F;&lt;&#x2F;code&gt; called something like &lt;code&gt;cm-14.1-20161231-UNOFFICIAL-DEVICECODENAME.zip&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;!! &lt;strong&gt;Warning:&lt;&#x2F;strong&gt; You can install this image as any other official image, with again, &lt;em&gt;results that will eat your cat&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Remember, you assume all risk of trying this, but you will reap the rewards! It’s pretty satisfying to boot into a fresh operating system you baked at home, and it gives you knowledge of what’s inside.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;going-further&quot;&gt;Going further&lt;a class=&quot;zola-anchor&quot; href=&quot;#going-further&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;sharing-your-code&quot;&gt;Sharing your code&lt;a class=&quot;zola-anchor&quot; href=&quot;#sharing-your-code&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Sharing is caring, but it’s also an important feature of LineageOS since it’s built in a very composable way. Understanding how it is shared will help you get all the parts you need to build your custom&#x2F;WIP ROM.&lt;&#x2F;p&gt;
&lt;p&gt;Once you’ve started your device folder, create your own GitHub account and set up your folder as a public GitHub repository. This is a great opportunity to learn about git, and also your source can be accessible to others who can collaborate with you.&lt;&#x2F;p&gt;
&lt;p&gt;When naming your repository, use the format &lt;code&gt;android_device_VENDOR_CODENAME&lt;&#x2F;code&gt;, where &lt;code&gt;VENDOR&lt;&#x2F;code&gt; and &lt;code&gt;CODENAME&lt;&#x2F;code&gt; use the new device’s values. So, let’s say your GitHub account name is “fat-tire” and your device codename is “encore”, manufactured by Barnes and Noble. You should call your repository android_device_bn_encore. It would be accessible at https:&#x2F;&#x2F;github.com&#x2F;fat-tire&#x2F;android_device_bn_encore. Similarly, the kernel repository would be called android_kernel_bn_encore. It would be accessible at https:&#x2F;&#x2F;github.com&#x2F;fat-tire&#x2F;android_kernel_bn_encore.&lt;&#x2F;p&gt;
&lt;p&gt;The last thing to do is create a local manifest for other people to use to automatically download and their keep up-to-date with your changes. Here’s an example, using the above scenario:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;xml&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span&gt;&amp;lt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;xml &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;version&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;encoding&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;UTF-8&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;?&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;manifest&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;project &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;fat-tire&#x2F;android_device_bn_encore&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;path&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;device&#x2F;bn&#x2F;encore&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;remote&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;github&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;revision&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;cm-10.1&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &#x2F;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;project &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;fat-tire&#x2F;android_kernel_bn_encore&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;path&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;kernel&#x2F;bn&#x2F;encore&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;remote&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;github&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;revision&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;cm-10.1&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &#x2F;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;manifest&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;! &lt;strong&gt;note:&lt;&#x2F;strong&gt; the revision attribute is optional. If it is omitted, &lt;code&gt;repo&lt;&#x2F;code&gt; sync will use the revision specified by the &lt;code&gt;&amp;lt;default ... &#x2F;&amp;gt;&lt;&#x2F;code&gt; tag in the default manifest.&lt;&#x2F;p&gt;
&lt;p&gt;Once you’ve tested that the local manifest file works, you can pass it on to others, who can then try out your work.&lt;&#x2F;p&gt;
&lt;p&gt;! &lt;strong&gt;note:&lt;&#x2F;strong&gt; if you find that for some reason you need to replace or supplement other repositories provided by LineageOS, you can add additional repositories using the local manifest. Once you’ve got everything working, you can use Gerrit to submit stuff found in those repositories back upstream to CyanogenMod.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;adding-xml-overlays&quot;&gt;Adding XML overlays&lt;a class=&quot;zola-anchor&quot; href=&quot;#adding-xml-overlays&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;It’s very likely in your &lt;code&gt;device_[codename].mk&lt;&#x2F;code&gt; file, there’s a line that looks like this:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;DEVICE_PACKAGE_OVERLAYS := \
&lt;&#x2F;span&gt;&lt;span&gt;    device&#x2F;[vendor]&#x2F;[codename]&#x2F;overlay
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;What this does is set the &lt;code&gt;overlay&#x2F;&lt;&#x2F;code&gt; folder to allow you to override any XML file used by Android frameworks or apps, just for this device. To do so, create a directory structure which mirrors the path leading to an XML file, starting from the root of your source. Then replace the file you want to overlay.&lt;&#x2F;p&gt;
&lt;p&gt;Example: Let’s say you want to override some standard Android settings. Look at the file in &lt;code&gt;frameworks&#x2F;base&#x2F;core&#x2F;res&#x2F;res&#x2F;values&#x2F;config.xml&lt;&#x2F;code&gt;. Then copy it to &lt;code&gt;device&#x2F;[vendor]&#x2F;[codename]&#x2F;overlay&#x2F;frameworks&#x2F;base&#x2F;core&#x2F;res&#x2F;res&#x2F;values&#x2F;config.xml&lt;&#x2F;code&gt;. Now YOUR version will be used instead of the other one. You only need to include the settings you wish to override - not all of them, so you can pare down the file to those few that change from the default.&lt;&#x2F;p&gt;
&lt;p&gt;You can overlay any XML file, affecting layouts, settings, preferences, translations, and more.&lt;&#x2F;p&gt;
</content:encoded>
            </item>
        
            <item>
                <title>VoidLinux: Full Disk Encryption</title>
                <pubDate>Sat, 12 Aug 2017 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/voidlinux-full-disk-encryption/</link>
                <guid>https://rigelk.frama.io/blog/blog/voidlinux-full-disk-encryption/</guid>
                <description>&lt;p&gt;In order to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;without-systemd.org&#x2F;wiki&#x2F;index.php&#x2F;Main_Page&quot;&gt;get rid of systemd&lt;&#x2F;a&gt;, quite a few nice options arise. My favorites range from the recent (albeit battle-tested through Docker) &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;alpinelinux.org&#x2F;about&#x2F;&quot;&gt;Alpine Linux&lt;&#x2F;a&gt;, Gentoo&#x2F;Funtoo, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sabotage-linux&#x2F;sabotage&quot;&gt;Sabotage&lt;&#x2F;a&gt; Linux or &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;sta.li&#x2F;&quot;&gt;sta.li&lt;&#x2F;a&gt;. Others I have not tested.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;option-1-your-disk-uses-mbr&quot;&gt;Option 1: your disk uses MBR&lt;a class=&quot;zola-anchor&quot; href=&quot;#option-1-your-disk-uses-mbr&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Void Linux is on a good way, as it uses &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.voidlinux.org&#x2F;usage&#x2F;runit&#x2F;&quot;&gt;runit&lt;&#x2F;a&gt; instead of the intrusive and immature systemd. Since the “&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;wiki.voidlinux.org&#x2F;Install_LVM_LUKS&quot;&gt;official&lt;&#x2F;a&gt;” manual for full disk encryption (FDE) does not work properly (at least, not for me), this is a complete list of instructions to achieve the FDE my way.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-goal-and-the-problem&quot;&gt;The goal and The problem&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-goal-and-the-problem&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;The aim is to have a single encrypted primary partition created using LUKS&#x2F;LVM on a MBR disk scheme with logical disk scheme (one root partition and one swap partition). Using ArchLinux mkinicpio’s kernel hooks, a binary &#x2F;crypto_keyfile.bin is added into a initramfs image in order to be able to decrypt and mount the partition automatically. User adds a password only a single time, when the computer starts (once GRUB asks for it).&lt;&#x2F;p&gt;
&lt;p&gt;The same principle should work in the Void Linux. The problem is that no matter the partition table (MBR or GPT), no matter the configuration, it still asks for the password two times…&lt;&#x2F;p&gt;
&lt;h3 id=&quot;solution&quot;&gt;Solution&lt;a class=&quot;zola-anchor&quot; href=&quot;#solution&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;The problem is a requirement of &lt;code&gt;&#x2F;etc&#x2F;crypttab&lt;&#x2F;code&gt; file, which needs to be provided to the initramfs as well (and which references to the &#x2F;dev&#x2F;sda1 encrypted partition).&lt;&#x2F;p&gt;
&lt;p&gt;So, no 3rd party “patch” is needed. Only a slight modification, such as the following:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; blkid | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;grep&lt;&#x2F;span&gt;&lt;span&gt; LUKS | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;awk &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;{print $2}&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sed &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;s&#x2F;UUID=&amp;quot;&#x2F;lvm-system        UUID=&#x2F;g&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sed &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;s&#x2F;&amp;quot;&#x2F;    \&#x2F;crypto_keyfile.bin    luks&#x2F;g&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; &amp;gt;&amp;gt; &#x2F;etc&#x2F;crypttab
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; cat &#x2F;etc&#x2F;crypttab &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# and check crypttab to look similar to the following
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# crypttab: mappings for encrypted partitions
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;lvm-system&lt;&#x2F;span&gt;&lt;span&gt;	UUID=01234567-89ab-cdef-0123-456789abcdef	&#x2F;crypto_keyfile.bin	luks
&lt;&#x2F;span&gt;&lt;span&gt;```	
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Rewrite&lt;&#x2F;span&gt;&lt;span&gt; the grub configuration and recompile the kernel&#x2F;initramfs image and that’s it!
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;### Summary
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;```bash
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; fdisk &#x2F;dev&#x2F;sda &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# starting with an empty disk (create MBR with a single partition)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Command&lt;&#x2F;span&gt;&lt;span&gt; (m for help)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; o
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Command&lt;&#x2F;span&gt;&lt;span&gt; (m for help)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; n
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Select&lt;&#x2F;span&gt;&lt;span&gt; (default p)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;: 
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Partition&lt;&#x2F;span&gt;&lt;span&gt; number (1-4, default 1)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;: 
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;First&lt;&#x2F;span&gt;&lt;span&gt; sector (2048-500118191, default 2048)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;: 
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Last&lt;&#x2F;span&gt;&lt;span&gt; sector, +sectors or +size{K,M,G,T,P} (2048-500118191, default 500118191)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;: 
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Command&lt;&#x2F;span&gt;&lt;span&gt; (m for help)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; p
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Command&lt;&#x2F;span&gt;&lt;span&gt; (m for help)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; w
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; cryptsetup luksFormat&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -v&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;dev&#x2F;sda1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# let&amp;#39;s encrypt the single partition
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Are&lt;&#x2F;span&gt;&lt;span&gt; you sure? (Type uppercase yes)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; YES
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; cryptsetup luksOpen &#x2F;dev&#x2F;sda1 lvm-system &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# open it
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; pvcreate &#x2F;dev&#x2F;mapper&#x2F;lvm-system &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# create a physical volume
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; vgcreate lvmSystem &#x2F;dev&#x2F;mapper&#x2F;lvm-system &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# create a volume group
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; lvcreate&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -L&lt;&#x2F;span&gt;&lt;span&gt; 2.84G lvmSystem&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -n&lt;&#x2F;span&gt;&lt;span&gt; volSwap &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# create a logical swap partition (e.g same size as the RAM)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; lvcreate&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -l&lt;&#x2F;span&gt;&lt;span&gt; +100%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;FREE&lt;&#x2F;span&gt;&lt;span&gt; lvmSystem&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -n&lt;&#x2F;span&gt;&lt;span&gt; volRoot &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# create a logical root partition (the rest of the available space)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; mkswap &#x2F;dev&#x2F;lvmSystem&#x2F;volSwap &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# format the swap partition
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; mkfs.ext4 &#x2F;dev&#x2F;lvmSystem&#x2F;volRoot &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# format the root partition
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; mount &#x2F;dev&#x2F;lvmSystem&#x2F;volRoot &#x2F;mnt &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# mount root
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; swapon &#x2F;dev&#x2F;lvmSystem&#x2F;volSwap &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# mount swap
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; mkdir &#x2F;mnt&#x2F;{boot,dev,proc,sys,home,root} &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# create necessary directories
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; mount&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; --rbind&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;dev &#x2F;mnt&#x2F;dev
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; mount&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; --rbind&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;proc &#x2F;mnt&#x2F;proc
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; mount&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; --rbind&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;sys &#x2F;mnt&#x2F;sys
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; xbps-install&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -S -R&lt;&#x2F;span&gt;&lt;span&gt; https:&#x2F;&#x2F;repo.voidlinux.eu&#x2F;current&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -r&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;mnt base-system base-devel lvm2 cryptsetup grub
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;[*]&lt;&#x2F;span&gt;&lt;span&gt; Updating `&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;https:&#x2F;&#x2F;repo.voidlinux.eu&#x2F;current&#x2F;&#x2F;x86_64-repodata&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt; ...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;x86_64-repodata: 1085KB [avg rate: 128KB&#x2F;s]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`https:&#x2F;&#x2F;repo.voidlinux.eu&#x2F;current&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; repository has been RSA signed by &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Void Linux&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Fingerprint:&lt;&#x2F;span&gt;&lt;span&gt; 60:ae:0c:d6:f0:95:17:80:bc:93:46:7a:89:af:a3:2d
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Do&lt;&#x2F;span&gt;&lt;span&gt; you want to import this public key? &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Y&#x2F;n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt; Y
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;List&lt;&#x2F;span&gt;&lt;span&gt; of packages to be installed into the &#x2F;mnt directory...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Do&lt;&#x2F;span&gt;&lt;span&gt; you want to continue? &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Y&#x2F;n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt; Y
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;[*]&lt;&#x2F;span&gt;&lt;span&gt; Downloading binary packages
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;[*]&lt;&#x2F;span&gt;&lt;span&gt; Verifying package integrity
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;[*]&lt;&#x2F;span&gt;&lt;span&gt; Running transaction tasks
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;[*]&lt;&#x2F;span&gt;&lt;span&gt; Configuring unpacked packages
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;150&lt;&#x2F;span&gt;&lt;span&gt; downloaded, 150 installed, 0 updated, 150 configured, 0 removed.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; chroot &#x2F;mnt &#x2F;bin&#x2F;bash
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; passwd root
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;New&lt;&#x2F;span&gt;&lt;span&gt; password:
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Retype&lt;&#x2F;span&gt;&lt;span&gt; new password:
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; chown root:root &#x2F;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; chmod 755 &#x2F;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; vi &#x2F;etc&#x2F;rc.conf &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# set TIMEZONE
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; echo DESIREDHOSTNAME &amp;gt; &#x2F;etc&#x2F;hostname
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; blkid | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;grep&lt;&#x2F;span&gt;&lt;span&gt; volRoot | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sed &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;s&#x2F;^.*UUID=&amp;quot;&#x2F;UUID=&#x2F;g&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sed &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;s&#x2F;&amp;quot;.*&#x2F; \&#x2F;              ext4            rw,relatime,data=ordered,discard        0 1&#x2F;g&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; blkid | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;grep&lt;&#x2F;span&gt;&lt;span&gt; volSwap | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sed &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;s&#x2F;^.*UUID=&amp;quot;&#x2F;UUID=&#x2F;g&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sed &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;s&#x2F;&amp;quot;.*&#x2F; none            swap            defaults                                0 0&#x2F;g&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; cat &#x2F;etc&#x2F;fstab &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# and check fstab to look similar to the following
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# 						
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;tmpfs&lt;&#x2F;span&gt;&lt;span&gt;		&#x2F;tmp	tmpfs	defaults,nosuid,nodev   0       0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;UUID&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;abcdef01-2345-6789-abcd-ef0123456789	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;         	ext4      	rw,relatime,data=ordered,discard	0 1
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;UUID&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;98765432-10fe-dcba-9876-543210fedcba	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;none&lt;&#x2F;span&gt;&lt;span&gt;      	swap      	defaults  				0 0
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; echo &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;LANG=en_US.UTF-8&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &amp;gt; &#x2F;etc&#x2F;locale.conf &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# or DESIRED LOCALE
&lt;&#x2F;span&gt;&lt;span&gt;bash-4.3# echo &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;en_US.UTF-8 UTF-8&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &amp;gt;&amp;gt; &#x2F;etc&#x2F;default&#x2F;libc-locales
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; xbps-reconfigure&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -f&lt;&#x2F;span&gt;&lt;span&gt; glibc-locales
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; echo hostonly=yes &amp;gt; &#x2F;etc&#x2F;dracut.conf.d&#x2F;hostonly
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; cat &#x2F;etc&#x2F;default&#x2F;grub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# to look as follows
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Configuration file for GRUB.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GRUB_DEFAULT&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#GRUB_HIDDEN_TIMEOUT=0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#GRUB_HIDDEN_TIMEOUT_QUIET=false
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GRUB_TIMEOUT&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;5
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GRUB_DISTRIBUTOR&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Void&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GRUB_CMDLINE_LINUX_DEFAULT&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;loglevel=4&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Uncomment to use basic console
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#GRUB_TERMINAL_INPUT=&amp;quot;console&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Uncomment to disable graphical terminal
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#GRUB_TERMINAL_OUTPUT=console
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GRUB_BACKGROUND&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;usr&#x2F;share&#x2F;void-artwork&#x2F;splash.png
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#GRUB_GFXMODE=1920x1080x32
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#GRUB_DISABLE_LINUX_UUID=true
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#GRUB_DISABLE_RECOVERY=true
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GRUB_CRYPTODISK_ENABLE&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;y  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# This option worked on void
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GRUB_ENABLE_CRYPTODISK&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;y  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# This one worked on Arch (include both just in case).
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GRUB_CMDLINE_LINUX_DEFAULT&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;loglevel=4 rd.auto=1&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GRUB_CMDLINE_LINUX&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;cryptdevice=&#x2F;dev&#x2F;sda1:lvm-system&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; dd if=&#x2F;dev&#x2F;urandom of=&#x2F;crypto_keyfile.bin bs=512 count=8 iflag=fullblock &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# generate a random key
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; cryptsetup luksAddKey &#x2F;dev&#x2F;sda1 &#x2F;crypto_keyfile.bin &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# add the key
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; blkid | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;grep&lt;&#x2F;span&gt;&lt;span&gt; LUKS | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;awk &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;{print $2}&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sed &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;s&#x2F;UUID=&amp;quot;&#x2F;lvm-system        UUID=&#x2F;g&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sed &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;s&#x2F;&amp;quot;&#x2F;    \&#x2F;crypto_keyfile.bin    luks&#x2F;g&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; &amp;gt;&amp;gt; &#x2F;etc&#x2F;crypttab
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; cat &#x2F;etc&#x2F;crypttab &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# and check crypttab to look similar to the following
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# crypttab: mappings for encrypted partitions
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;lvm-system&lt;&#x2F;span&gt;&lt;span&gt;	UUID=01234567-89ab-cdef-0123-456789abcdef	&#x2F;crypto_keyfile.bin	luks
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; echo &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;install_items+=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;etc&#x2F;crypttab &#x2F;crypto_keyfile.bin&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &amp;gt;&amp;gt; &#x2F;etc&#x2F;dracut.conf.d&#x2F;10-crypt.conf
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; cat &#x2F;etc&#x2F;dracut.conf.d&#x2F;10-crypt.conf
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; chmod 000 &#x2F;crypto_keyfile.bin &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# actually, even root doesn&amp;#39;t need to access the keys
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; chmod&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -R&lt;&#x2F;span&gt;&lt;span&gt; g-rwx,o-rwx &#x2F;boot
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; mkdir &#x2F;boot&#x2F;grub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# installation of GRUB # grub directory is missing, da fuq?!
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; grub-mkconfig&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;boot&#x2F;grub&#x2F;grub.cfg &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# create initramfs image
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; grub-install &#x2F;dev&#x2F;sda &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# install grub
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; xbps-reconfigure&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -f&lt;&#x2F;span&gt;&lt;span&gt; linux4.6 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# recompile the current kernel (whilst ignoring locale errors)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; chsh&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -s&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;bin&#x2F;bash &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# change the default shell for root, &#x2F;bin&#x2F;sh as default, ye serious?!
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; exit &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# exit chroot
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; reboot &amp;amp;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;exit &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# reboot and exit the installation process
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</description>
                <content:encoded>&lt;p&gt;In order to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;without-systemd.org&#x2F;wiki&#x2F;index.php&#x2F;Main_Page&quot;&gt;get rid of systemd&lt;&#x2F;a&gt;, quite a few nice options arise. My favorites range from the recent (albeit battle-tested through Docker) &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;alpinelinux.org&#x2F;about&#x2F;&quot;&gt;Alpine Linux&lt;&#x2F;a&gt;, Gentoo&#x2F;Funtoo, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sabotage-linux&#x2F;sabotage&quot;&gt;Sabotage&lt;&#x2F;a&gt; Linux or &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;sta.li&#x2F;&quot;&gt;sta.li&lt;&#x2F;a&gt;. Others I have not tested.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;option-1-your-disk-uses-mbr&quot;&gt;Option 1: your disk uses MBR&lt;a class=&quot;zola-anchor&quot; href=&quot;#option-1-your-disk-uses-mbr&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Void Linux is on a good way, as it uses &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.voidlinux.org&#x2F;usage&#x2F;runit&#x2F;&quot;&gt;runit&lt;&#x2F;a&gt; instead of the intrusive and immature systemd. Since the “&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;wiki.voidlinux.org&#x2F;Install_LVM_LUKS&quot;&gt;official&lt;&#x2F;a&gt;” manual for full disk encryption (FDE) does not work properly (at least, not for me), this is a complete list of instructions to achieve the FDE my way.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-goal-and-the-problem&quot;&gt;The goal and The problem&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-goal-and-the-problem&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;The aim is to have a single encrypted primary partition created using LUKS&#x2F;LVM on a MBR disk scheme with logical disk scheme (one root partition and one swap partition). Using ArchLinux mkinicpio’s kernel hooks, a binary &#x2F;crypto_keyfile.bin is added into a initramfs image in order to be able to decrypt and mount the partition automatically. User adds a password only a single time, when the computer starts (once GRUB asks for it).&lt;&#x2F;p&gt;
&lt;p&gt;The same principle should work in the Void Linux. The problem is that no matter the partition table (MBR or GPT), no matter the configuration, it still asks for the password two times…&lt;&#x2F;p&gt;
&lt;h3 id=&quot;solution&quot;&gt;Solution&lt;a class=&quot;zola-anchor&quot; href=&quot;#solution&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;The problem is a requirement of &lt;code&gt;&#x2F;etc&#x2F;crypttab&lt;&#x2F;code&gt; file, which needs to be provided to the initramfs as well (and which references to the &#x2F;dev&#x2F;sda1 encrypted partition).&lt;&#x2F;p&gt;
&lt;p&gt;So, no 3rd party “patch” is needed. Only a slight modification, such as the following:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; blkid | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;grep&lt;&#x2F;span&gt;&lt;span&gt; LUKS | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;awk &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;{print $2}&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sed &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;s&#x2F;UUID=&amp;quot;&#x2F;lvm-system        UUID=&#x2F;g&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sed &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;s&#x2F;&amp;quot;&#x2F;    \&#x2F;crypto_keyfile.bin    luks&#x2F;g&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; &amp;gt;&amp;gt; &#x2F;etc&#x2F;crypttab
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; cat &#x2F;etc&#x2F;crypttab &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# and check crypttab to look similar to the following
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# crypttab: mappings for encrypted partitions
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;lvm-system&lt;&#x2F;span&gt;&lt;span&gt;	UUID=01234567-89ab-cdef-0123-456789abcdef	&#x2F;crypto_keyfile.bin	luks
&lt;&#x2F;span&gt;&lt;span&gt;```	
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Rewrite&lt;&#x2F;span&gt;&lt;span&gt; the grub configuration and recompile the kernel&#x2F;initramfs image and that’s it!
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;### Summary
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;```bash
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; fdisk &#x2F;dev&#x2F;sda &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# starting with an empty disk (create MBR with a single partition)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Command&lt;&#x2F;span&gt;&lt;span&gt; (m for help)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; o
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Command&lt;&#x2F;span&gt;&lt;span&gt; (m for help)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; n
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Select&lt;&#x2F;span&gt;&lt;span&gt; (default p)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;: 
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Partition&lt;&#x2F;span&gt;&lt;span&gt; number (1-4, default 1)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;: 
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;First&lt;&#x2F;span&gt;&lt;span&gt; sector (2048-500118191, default 2048)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;: 
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Last&lt;&#x2F;span&gt;&lt;span&gt; sector, +sectors or +size{K,M,G,T,P} (2048-500118191, default 500118191)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;: 
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Command&lt;&#x2F;span&gt;&lt;span&gt; (m for help)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; p
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Command&lt;&#x2F;span&gt;&lt;span&gt; (m for help)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; w
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; cryptsetup luksFormat&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -v&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;dev&#x2F;sda1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# let&amp;#39;s encrypt the single partition
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Are&lt;&#x2F;span&gt;&lt;span&gt; you sure? (Type uppercase yes)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; YES
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; cryptsetup luksOpen &#x2F;dev&#x2F;sda1 lvm-system &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# open it
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; pvcreate &#x2F;dev&#x2F;mapper&#x2F;lvm-system &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# create a physical volume
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; vgcreate lvmSystem &#x2F;dev&#x2F;mapper&#x2F;lvm-system &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# create a volume group
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; lvcreate&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -L&lt;&#x2F;span&gt;&lt;span&gt; 2.84G lvmSystem&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -n&lt;&#x2F;span&gt;&lt;span&gt; volSwap &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# create a logical swap partition (e.g same size as the RAM)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; lvcreate&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -l&lt;&#x2F;span&gt;&lt;span&gt; +100%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;FREE&lt;&#x2F;span&gt;&lt;span&gt; lvmSystem&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -n&lt;&#x2F;span&gt;&lt;span&gt; volRoot &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# create a logical root partition (the rest of the available space)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; mkswap &#x2F;dev&#x2F;lvmSystem&#x2F;volSwap &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# format the swap partition
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; mkfs.ext4 &#x2F;dev&#x2F;lvmSystem&#x2F;volRoot &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# format the root partition
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; mount &#x2F;dev&#x2F;lvmSystem&#x2F;volRoot &#x2F;mnt &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# mount root
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; swapon &#x2F;dev&#x2F;lvmSystem&#x2F;volSwap &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# mount swap
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; mkdir &#x2F;mnt&#x2F;{boot,dev,proc,sys,home,root} &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# create necessary directories
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; mount&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; --rbind&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;dev &#x2F;mnt&#x2F;dev
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; mount&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; --rbind&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;proc &#x2F;mnt&#x2F;proc
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; mount&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; --rbind&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;sys &#x2F;mnt&#x2F;sys
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; xbps-install&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -S -R&lt;&#x2F;span&gt;&lt;span&gt; https:&#x2F;&#x2F;repo.voidlinux.eu&#x2F;current&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -r&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;mnt base-system base-devel lvm2 cryptsetup grub
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;[*]&lt;&#x2F;span&gt;&lt;span&gt; Updating `&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;https:&#x2F;&#x2F;repo.voidlinux.eu&#x2F;current&#x2F;&#x2F;x86_64-repodata&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt; ...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;x86_64-repodata: 1085KB [avg rate: 128KB&#x2F;s]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;`https:&#x2F;&#x2F;repo.voidlinux.eu&#x2F;current&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; repository has been RSA signed by &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Void Linux&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Fingerprint:&lt;&#x2F;span&gt;&lt;span&gt; 60:ae:0c:d6:f0:95:17:80:bc:93:46:7a:89:af:a3:2d
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Do&lt;&#x2F;span&gt;&lt;span&gt; you want to import this public key? &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Y&#x2F;n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt; Y
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;List&lt;&#x2F;span&gt;&lt;span&gt; of packages to be installed into the &#x2F;mnt directory...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Do&lt;&#x2F;span&gt;&lt;span&gt; you want to continue? &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Y&#x2F;n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt; Y
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;[*]&lt;&#x2F;span&gt;&lt;span&gt; Downloading binary packages
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;[*]&lt;&#x2F;span&gt;&lt;span&gt; Verifying package integrity
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;[*]&lt;&#x2F;span&gt;&lt;span&gt; Running transaction tasks
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;[*]&lt;&#x2F;span&gt;&lt;span&gt; Configuring unpacked packages
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;150&lt;&#x2F;span&gt;&lt;span&gt; downloaded, 150 installed, 0 updated, 150 configured, 0 removed.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; chroot &#x2F;mnt &#x2F;bin&#x2F;bash
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; passwd root
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;New&lt;&#x2F;span&gt;&lt;span&gt; password:
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Retype&lt;&#x2F;span&gt;&lt;span&gt; new password:
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; chown root:root &#x2F;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; chmod 755 &#x2F;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; vi &#x2F;etc&#x2F;rc.conf &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# set TIMEZONE
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; echo DESIREDHOSTNAME &amp;gt; &#x2F;etc&#x2F;hostname
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; blkid | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;grep&lt;&#x2F;span&gt;&lt;span&gt; volRoot | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sed &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;s&#x2F;^.*UUID=&amp;quot;&#x2F;UUID=&#x2F;g&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sed &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;s&#x2F;&amp;quot;.*&#x2F; \&#x2F;              ext4            rw,relatime,data=ordered,discard        0 1&#x2F;g&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; blkid | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;grep&lt;&#x2F;span&gt;&lt;span&gt; volSwap | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sed &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;s&#x2F;^.*UUID=&amp;quot;&#x2F;UUID=&#x2F;g&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sed &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;s&#x2F;&amp;quot;.*&#x2F; none            swap            defaults                                0 0&#x2F;g&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; cat &#x2F;etc&#x2F;fstab &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# and check fstab to look similar to the following
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# 						
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;tmpfs&lt;&#x2F;span&gt;&lt;span&gt;		&#x2F;tmp	tmpfs	defaults,nosuid,nodev   0       0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;UUID&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;abcdef01-2345-6789-abcd-ef0123456789	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;         	ext4      	rw,relatime,data=ordered,discard	0 1
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;UUID&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;98765432-10fe-dcba-9876-543210fedcba	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;none&lt;&#x2F;span&gt;&lt;span&gt;      	swap      	defaults  				0 0
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; echo &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;LANG=en_US.UTF-8&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &amp;gt; &#x2F;etc&#x2F;locale.conf &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# or DESIRED LOCALE
&lt;&#x2F;span&gt;&lt;span&gt;bash-4.3# echo &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;en_US.UTF-8 UTF-8&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &amp;gt;&amp;gt; &#x2F;etc&#x2F;default&#x2F;libc-locales
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; xbps-reconfigure&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -f&lt;&#x2F;span&gt;&lt;span&gt; glibc-locales
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; echo hostonly=yes &amp;gt; &#x2F;etc&#x2F;dracut.conf.d&#x2F;hostonly
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; cat &#x2F;etc&#x2F;default&#x2F;grub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# to look as follows
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Configuration file for GRUB.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GRUB_DEFAULT&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#GRUB_HIDDEN_TIMEOUT=0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#GRUB_HIDDEN_TIMEOUT_QUIET=false
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GRUB_TIMEOUT&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;5
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GRUB_DISTRIBUTOR&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Void&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GRUB_CMDLINE_LINUX_DEFAULT&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;loglevel=4&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Uncomment to use basic console
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#GRUB_TERMINAL_INPUT=&amp;quot;console&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Uncomment to disable graphical terminal
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#GRUB_TERMINAL_OUTPUT=console
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GRUB_BACKGROUND&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;usr&#x2F;share&#x2F;void-artwork&#x2F;splash.png
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#GRUB_GFXMODE=1920x1080x32
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#GRUB_DISABLE_LINUX_UUID=true
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;#GRUB_DISABLE_RECOVERY=true
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GRUB_CRYPTODISK_ENABLE&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;y  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# This option worked on void
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GRUB_ENABLE_CRYPTODISK&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;y  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# This one worked on Arch (include both just in case).
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GRUB_CMDLINE_LINUX_DEFAULT&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;loglevel=4 rd.auto=1&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;GRUB_CMDLINE_LINUX&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;cryptdevice=&#x2F;dev&#x2F;sda1:lvm-system&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; dd if=&#x2F;dev&#x2F;urandom of=&#x2F;crypto_keyfile.bin bs=512 count=8 iflag=fullblock &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# generate a random key
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; cryptsetup luksAddKey &#x2F;dev&#x2F;sda1 &#x2F;crypto_keyfile.bin &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# add the key
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; blkid | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;grep&lt;&#x2F;span&gt;&lt;span&gt; LUKS | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;awk &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;{print $2}&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sed &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;s&#x2F;UUID=&amp;quot;&#x2F;lvm-system        UUID=&#x2F;g&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; | &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sed &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;s&#x2F;&amp;quot;&#x2F;    \&#x2F;crypto_keyfile.bin    luks&#x2F;g&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39; &amp;gt;&amp;gt; &#x2F;etc&#x2F;crypttab
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; cat &#x2F;etc&#x2F;crypttab &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# and check crypttab to look similar to the following
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# crypttab: mappings for encrypted partitions
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;lvm-system&lt;&#x2F;span&gt;&lt;span&gt;	UUID=01234567-89ab-cdef-0123-456789abcdef	&#x2F;crypto_keyfile.bin	luks
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; echo &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;install_items+=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;etc&#x2F;crypttab &#x2F;crypto_keyfile.bin&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; &amp;gt;&amp;gt; &#x2F;etc&#x2F;dracut.conf.d&#x2F;10-crypt.conf
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; cat &#x2F;etc&#x2F;dracut.conf.d&#x2F;10-crypt.conf
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; chmod 000 &#x2F;crypto_keyfile.bin &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# actually, even root doesn&amp;#39;t need to access the keys
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; chmod&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -R&lt;&#x2F;span&gt;&lt;span&gt; g-rwx,o-rwx &#x2F;boot
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; mkdir &#x2F;boot&#x2F;grub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# installation of GRUB # grub directory is missing, da fuq?!
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; grub-mkconfig&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;boot&#x2F;grub&#x2F;grub.cfg &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# create initramfs image
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; grub-install &#x2F;dev&#x2F;sda &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# install grub
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; xbps-reconfigure&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -f&lt;&#x2F;span&gt;&lt;span&gt; linux4.6 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# recompile the current kernel (whilst ignoring locale errors)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; chsh&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -s&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;bin&#x2F;bash &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# change the default shell for root, &#x2F;bin&#x2F;sh as default, ye serious?!
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; exit &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# exit chroot
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-bash-4.3#&lt;&#x2F;span&gt;&lt;span&gt; reboot &amp;amp;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;exit &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# reboot and exit the installation process
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content:encoded>
            </item>
        
            <item>
                <title>Git tricks</title>
                <pubDate>Tue, 13 Jun 2017 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/git-tricks/</link>
                <guid>https://rigelk.frama.io/blog/blog/git-tricks/</guid>
                <description>&lt;p&gt;Git is a bless but pushing repositories into the wild got me worried with two points: security and size. The following is a course a summary of my experiences with snippets found on other sites.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;size&quot;&gt;Size&lt;a class=&quot;zola-anchor&quot; href=&quot;#size&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;With time every git repository tends to get dirty. Going a direction and changing your mind the second after come at a cost in versionned environments: references are kept and take a lot of place, especially if your keep track of archives.&lt;&#x2F;p&gt;
&lt;p&gt;See how bad the situation is with:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;git bundle create tmp.bundle --all  
&lt;&#x2F;span&gt;&lt;span&gt;du -sh tmp.bundle  
&lt;&#x2F;span&gt;&lt;span&gt;rm tmp.bundle  
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We first need to detect which files are causing trouble. That comes in the following 3 commands:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;git rev-list --objects --all | sort -k 2 &amp;gt; allfileshas.txt&lt;&#x2F;code&gt; to get a list of all files in the history.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;git gc &amp;amp;&amp;amp; git verify-pack -v .git&#x2F;objects&#x2F;pack&#x2F;pack-*.idx | egrep &quot;^\w+ blob\W+[0-9]+ [0-9]+ [0-9]+$&quot; | sort -k 3 -n -r &amp;gt; bigobjects.txt&lt;&#x2F;code&gt; to get a list of big files by decreasing size order.&lt;&#x2F;p&gt;
&lt;p&gt;Now get the real file names:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;for SHA in `cut -f 1 -d\  &amp;lt; bigobjects.txt`;  
&lt;&#x2F;span&gt;&lt;span&gt;do  
&lt;&#x2F;span&gt;&lt;span&gt;   echo $(grep $SHA bigobjects.txt) $(grep $SHA allfileshas.txt) | awk &amp;#39;{print $1,$3,$7}&amp;#39; &amp;gt;&amp;gt; bigtosmall.txt
&lt;&#x2F;span&gt;&lt;span&gt;done;  
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;cloning-is-caring&quot;&gt;Cloning is caring&lt;a class=&quot;zola-anchor&quot; href=&quot;#cloning-is-caring&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;The remedy comes with the following list, though step #1 is probably the most important and cloning is just to make things clean with hard links. Clone locally your repo to have clean references and do:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git filter-branch --index-filter &#x27;git rm --cached --ignore-unmatch &amp;lt;FILE NAME&amp;gt;&#x27;&lt;&#x2F;code&gt; Removes the file from all revisions.
&lt;ul&gt;
&lt;li&gt;ex. &lt;code&gt;git filter-branch --index-filter &#x27;git rm --cached --ignore-unmatch **&#x2F;subdirectory&#x2F;*&#x27;&lt;&#x2F;code&gt; All subdirectories that appears in multiple directories&lt;&#x2F;li&gt;
&lt;li&gt;ex. &lt;code&gt;git filter-branch --index-filter &#x27;git rm --cached --ignore-unmatch &#x2F;subdirectory&#x2F;*.jpg&#x27;&lt;&#x2F;code&gt; All jpg files in this subdirectory.&lt;&#x2F;li&gt;
&lt;li&gt;ex. &lt;code&gt;git filter-branch --index-filter &#x27;git rm --cached --ignore-unmatch &#x2F;subdirectory&#x2F;*&#x27;&lt;&#x2F;code&gt; All files in this subdirectory and consequently this subdirectory because git doesn’t support empty directories.&lt;&#x2F;li&gt;
&lt;li&gt;ex. &lt;code&gt;git filter-branch --index-filter &#x27;git rm --cached --ignore-unmatch subdirectory&#x2F;**&#x2F;subdirectory2&#x2F;*&#x27;&lt;&#x2F;code&gt; All subdirectory2 which are contained within the subdirectory&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;rm -rf .git&#x2F;refs&#x2F;original&#x2F;&lt;&#x2F;code&gt; Remove git’s backup.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;git reflog expire --expire=now --all&lt;&#x2F;code&gt; Expires all the loose objects.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;git fsck --full --unreachable&lt;&#x2F;code&gt; Checks if there are any loose objects.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;git repack -A -d&lt;&#x2F;code&gt; Repacks the pack.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;git gc --aggressive --prune=now&lt;&#x2F;code&gt; Finally removes those objects.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;git push --force [remote] master&lt;&#x2F;code&gt; You will need to do a force push, because the remote will sort of think you went back in time, so just make sure you’ve pulled before you started all of this.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;security&quot;&gt;Security&lt;a class=&quot;zola-anchor&quot; href=&quot;#security&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Yet to come 😉&lt;&#x2F;p&gt;
</description>
                <content:encoded>&lt;p&gt;Git is a bless but pushing repositories into the wild got me worried with two points: security and size. The following is a course a summary of my experiences with snippets found on other sites.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;size&quot;&gt;Size&lt;a class=&quot;zola-anchor&quot; href=&quot;#size&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;With time every git repository tends to get dirty. Going a direction and changing your mind the second after come at a cost in versionned environments: references are kept and take a lot of place, especially if your keep track of archives.&lt;&#x2F;p&gt;
&lt;p&gt;See how bad the situation is with:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;git bundle create tmp.bundle --all  
&lt;&#x2F;span&gt;&lt;span&gt;du -sh tmp.bundle  
&lt;&#x2F;span&gt;&lt;span&gt;rm tmp.bundle  
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We first need to detect which files are causing trouble. That comes in the following 3 commands:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;git rev-list --objects --all | sort -k 2 &amp;gt; allfileshas.txt&lt;&#x2F;code&gt; to get a list of all files in the history.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;git gc &amp;amp;&amp;amp; git verify-pack -v .git&#x2F;objects&#x2F;pack&#x2F;pack-*.idx | egrep &quot;^\w+ blob\W+[0-9]+ [0-9]+ [0-9]+$&quot; | sort -k 3 -n -r &amp;gt; bigobjects.txt&lt;&#x2F;code&gt; to get a list of big files by decreasing size order.&lt;&#x2F;p&gt;
&lt;p&gt;Now get the real file names:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;for SHA in `cut -f 1 -d\  &amp;lt; bigobjects.txt`;  
&lt;&#x2F;span&gt;&lt;span&gt;do  
&lt;&#x2F;span&gt;&lt;span&gt;   echo $(grep $SHA bigobjects.txt) $(grep $SHA allfileshas.txt) | awk &amp;#39;{print $1,$3,$7}&amp;#39; &amp;gt;&amp;gt; bigtosmall.txt
&lt;&#x2F;span&gt;&lt;span&gt;done;  
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;cloning-is-caring&quot;&gt;Cloning is caring&lt;a class=&quot;zola-anchor&quot; href=&quot;#cloning-is-caring&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;The remedy comes with the following list, though step #1 is probably the most important and cloning is just to make things clean with hard links. Clone locally your repo to have clean references and do:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git filter-branch --index-filter &#x27;git rm --cached --ignore-unmatch &amp;lt;FILE NAME&amp;gt;&#x27;&lt;&#x2F;code&gt; Removes the file from all revisions.
&lt;ul&gt;
&lt;li&gt;ex. &lt;code&gt;git filter-branch --index-filter &#x27;git rm --cached --ignore-unmatch **&#x2F;subdirectory&#x2F;*&#x27;&lt;&#x2F;code&gt; All subdirectories that appears in multiple directories&lt;&#x2F;li&gt;
&lt;li&gt;ex. &lt;code&gt;git filter-branch --index-filter &#x27;git rm --cached --ignore-unmatch &#x2F;subdirectory&#x2F;*.jpg&#x27;&lt;&#x2F;code&gt; All jpg files in this subdirectory.&lt;&#x2F;li&gt;
&lt;li&gt;ex. &lt;code&gt;git filter-branch --index-filter &#x27;git rm --cached --ignore-unmatch &#x2F;subdirectory&#x2F;*&#x27;&lt;&#x2F;code&gt; All files in this subdirectory and consequently this subdirectory because git doesn’t support empty directories.&lt;&#x2F;li&gt;
&lt;li&gt;ex. &lt;code&gt;git filter-branch --index-filter &#x27;git rm --cached --ignore-unmatch subdirectory&#x2F;**&#x2F;subdirectory2&#x2F;*&#x27;&lt;&#x2F;code&gt; All subdirectory2 which are contained within the subdirectory&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;rm -rf .git&#x2F;refs&#x2F;original&#x2F;&lt;&#x2F;code&gt; Remove git’s backup.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;git reflog expire --expire=now --all&lt;&#x2F;code&gt; Expires all the loose objects.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;git fsck --full --unreachable&lt;&#x2F;code&gt; Checks if there are any loose objects.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;git repack -A -d&lt;&#x2F;code&gt; Repacks the pack.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;git gc --aggressive --prune=now&lt;&#x2F;code&gt; Finally removes those objects.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;git push --force [remote] master&lt;&#x2F;code&gt; You will need to do a force push, because the remote will sort of think you went back in time, so just make sure you’ve pulled before you started all of this.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;security&quot;&gt;Security&lt;a class=&quot;zola-anchor&quot; href=&quot;#security&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Yet to come 😉&lt;&#x2F;p&gt;
</content:encoded>
            </item>
        
            <item>
                <title>Reverse-engineering Android apps to regain freedom</title>
                <pubDate>Thu, 08 Jun 2017 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/reverse-android-regain-freedom/</link>
                <guid>https://rigelk.frama.io/blog/blog/reverse-android-regain-freedom/</guid>
                <description>&lt;p&gt;Hot Damn. Mobile applications nowadays make me thinks of stone age as far as freedoms are concerned. My latest example was with Le Monde’s La Matinale, which displays two fullpage video ads every time you launch the app or refocus on it. Let’s try to change that behaviour.&lt;&#x2F;p&gt;
&lt;p&gt;To reverse-engineer La Matinale du Monde, I gathered information by exploring its code. It apparently uses &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.iab.com&#x2F;wp-content&#x2F;uploads&#x2F;2015&#x2F;08&#x2F;IAB_MRAID_v2_FINAL.pdf&quot;&gt;MRAID (Mobile Rich-media Ad Interface Definitions)&lt;&#x2F;a&gt; through &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;smartadserver.com&#x2F;publisher-platform&#x2F;premium-programmatic&#x2F;&quot;&gt;Smart Adserver&lt;&#x2F;a&gt;’s service and A4S’s library. It might seem useless to do such background checks, but that case proved useful as Le Monde publishes &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;mpublicite.fr&#x2F;&quot;&gt;its explanation&lt;&#x2F;a&gt; (for marketing purposes) of the terms used to describe parts of the application: Topsitial, Intersitial.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;reverse-android-regain-freedom&#x2F;topstitial.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Our application makes use of Topsitial advertising, as seen by its rather extended use in the extracted code (through dex2jar). Chosing a modification in its code was rather simple: in the configuration handler, return null on every Topsitial instanciation. I used &lt;strong&gt;apkstudio&lt;&#x2F;strong&gt; to do just that:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;reverse-android-regain-freedom&#x2F;dlavik.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;part-2-compiling-packaging-signing&quot;&gt;Part 2: compiling, packaging, signing&lt;a class=&quot;zola-anchor&quot; href=&quot;#part-2-compiling-packaging-signing&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Compiling is really simple through apkstudio. Maybe a simple setting of the RAM usage away and you’re done. Then, signing requires you to create a key to sign with. First, generate a keystore using&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;keytool -genkey -v -keystore&lt;&#x2F;span&gt;&lt;span&gt; my-release-key.keystore&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -alias&lt;&#x2F;span&gt;&lt;span&gt; alias_name&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -keyalg&lt;&#x2F;span&gt;&lt;span&gt; RSA&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -keysize&lt;&#x2F;span&gt;&lt;span&gt; 2048&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -validity&lt;&#x2F;span&gt;&lt;span&gt; 10000
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then generate the key using &lt;strong&gt;apk-signer&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;reverse-android-regain-freedom&#x2F;signer2.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The alignement is an optional procedure to do before using your app in production:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;reverse-android-regain-freedom&#x2F;signer.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And &lt;em&gt;Tada!&lt;&#x2F;em&gt;, your app is ready, with no ads! The resulting app is available on Aptoid, for study purposes and no warranty, under rigelk’s store.&lt;&#x2F;p&gt;
</description>
                <content:encoded>&lt;p&gt;Hot Damn. Mobile applications nowadays make me thinks of stone age as far as freedoms are concerned. My latest example was with Le Monde’s La Matinale, which displays two fullpage video ads every time you launch the app or refocus on it. Let’s try to change that behaviour.&lt;&#x2F;p&gt;
&lt;p&gt;To reverse-engineer La Matinale du Monde, I gathered information by exploring its code. It apparently uses &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.iab.com&#x2F;wp-content&#x2F;uploads&#x2F;2015&#x2F;08&#x2F;IAB_MRAID_v2_FINAL.pdf&quot;&gt;MRAID (Mobile Rich-media Ad Interface Definitions)&lt;&#x2F;a&gt; through &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;smartadserver.com&#x2F;publisher-platform&#x2F;premium-programmatic&#x2F;&quot;&gt;Smart Adserver&lt;&#x2F;a&gt;’s service and A4S’s library. It might seem useless to do such background checks, but that case proved useful as Le Monde publishes &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;mpublicite.fr&#x2F;&quot;&gt;its explanation&lt;&#x2F;a&gt; (for marketing purposes) of the terms used to describe parts of the application: Topsitial, Intersitial.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;reverse-android-regain-freedom&#x2F;topstitial.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Our application makes use of Topsitial advertising, as seen by its rather extended use in the extracted code (through dex2jar). Chosing a modification in its code was rather simple: in the configuration handler, return null on every Topsitial instanciation. I used &lt;strong&gt;apkstudio&lt;&#x2F;strong&gt; to do just that:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;reverse-android-regain-freedom&#x2F;dlavik.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;part-2-compiling-packaging-signing&quot;&gt;Part 2: compiling, packaging, signing&lt;a class=&quot;zola-anchor&quot; href=&quot;#part-2-compiling-packaging-signing&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Compiling is really simple through apkstudio. Maybe a simple setting of the RAM usage away and you’re done. Then, signing requires you to create a key to sign with. First, generate a keystore using&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;keytool -genkey -v -keystore&lt;&#x2F;span&gt;&lt;span&gt; my-release-key.keystore&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -alias&lt;&#x2F;span&gt;&lt;span&gt; alias_name&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -keyalg&lt;&#x2F;span&gt;&lt;span&gt; RSA&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -keysize&lt;&#x2F;span&gt;&lt;span&gt; 2048&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt; -validity&lt;&#x2F;span&gt;&lt;span&gt; 10000
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then generate the key using &lt;strong&gt;apk-signer&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;reverse-android-regain-freedom&#x2F;signer2.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The alignement is an optional procedure to do before using your app in production:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;reverse-android-regain-freedom&#x2F;signer.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And &lt;em&gt;Tada!&lt;&#x2F;em&gt;, your app is ready, with no ads! The resulting app is available on Aptoid, for study purposes and no warranty, under rigelk’s store.&lt;&#x2F;p&gt;
</content:encoded>
            </item>
        
            <item>
                <title>Using Traffic Control with Virtualbox</title>
                <pubDate>Thu, 01 Jun 2017 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/traffic-control-virtualbox/</link>
                <guid>https://rigelk.frama.io/blog/blog/traffic-control-virtualbox/</guid>
                <description>&lt;p&gt;VirtualBox provides a traffic limiting tool through its CLI interface. However, one might want to use the full power of traffic control to further limit or shape the traffic going in&#x2F;out or ever between VMs. Problems arise when your VM needs access to internet, and we are going to see how to circumvent them.&lt;&#x2F;p&gt;
&lt;p&gt;VirtualBox does a fairly good job with its built-in &lt;em&gt;NAT adapter&lt;&#x2F;em&gt; feature. But it does so by using a socket and not a distinct network device visible in &#x2F;sys&#x2F;class&#x2F;net&#x2F;. This comes with some drawbacks:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You can’t easily monitor the network on the built-in NAT.  So if your VM is misbehaving, you couldn’t use tcpdump to troubleshoot.&lt;&#x2F;li&gt;
&lt;li&gt;The built in NAT reaches directly to the Internet in a transparent manner.  If you wanted to control access to the Internet you would have to switch to a bridge device or go with host-only.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I figured out the only solution to these would be to make the VM use an interface I could fully control. And while Virtualbox supports an option through the CLI utility VBoxManage to make the built-in NAT go through an interface by designating its IP, I went for another option: make a &lt;em&gt;Host-Only adapter&lt;&#x2F;em&gt; in Virtualbox.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;getting-a-host-only-adapter&quot;&gt;Getting a Host-Only adapter&lt;a class=&quot;zola-anchor&quot; href=&quot;#getting-a-host-only-adapter&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;This is done in &lt;code&gt;File -&amp;gt; Preferences -&amp;gt; Network&lt;&#x2F;code&gt;. Click the green icon with a PLUS sign in it.  A new network is created, probably called vboxnet0. Then click the little screwdriver icon to edit the vboxnet0 settings. Select the DHCP Server tab and make sure “Enable Server” is unticked. It will be ticked by default. We don’t want the default DHCP server, because it will bind its lease on the Virtualbox socket.&lt;&#x2F;p&gt;
&lt;p&gt;Then install &lt;strong&gt;dnsmasq&lt;&#x2F;strong&gt;. We are gonna use it to deal with the DHCP leases and DNS entries. While dnsmasq configuration can vary depending on your host system, it is generally found under a &lt;em&gt;&#x2F;etc&#x2F;dnsmasq.conf&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;vboxnet0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bind-interface
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;dhcp-range&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;192.168.56.2,192.168.56.150
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The range is up to you. If you set the vboxnet0 adapter to 192.168.56.0&#x2F;24, then any range within this lane will fit. After you have done it, restart the dnsmasq service with your host service manager.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kernel-nat-masquerading&quot;&gt;Kernel NAT Masquerading&lt;a class=&quot;zola-anchor&quot; href=&quot;#kernel-nat-masquerading&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;The big advantage of having that network device for ourselves and not just hidden inside a socket managed by Virtualbox is that we can now use kernel features to deal with packets. But that also means we have to setup the NAT feature ourselves. Hopefully this is (almost) a one-liner.&lt;&#x2F;p&gt;
&lt;p&gt;We are gonna use &lt;strong&gt;iptables&lt;&#x2F;strong&gt; for this. If you are using another firewall like ufw, disable it beforehand.&lt;&#x2F;p&gt;
&lt;p&gt;We also have to activate the ip forwarding at the kernel level. It can be done in &lt;em&gt;&#x2F;etc&#x2F;syctl.conf&lt;&#x2F;em&gt; or by running &lt;code&gt;sysctl -w net.ipv4.ip_forward=1&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Then we can setup the nat filter rule for iptables with &lt;code&gt;iptables -t nat -A POSTROUTING -s 192.168.56.0&#x2F;24 -j MASQUERADE&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Make sure to have the iptables running and to save the configuration with &lt;code&gt;iptables-save &amp;gt; &#x2F;etc&#x2F;iptables&#x2F;iptables.rules&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We then have an operable interface. You can launch the VM, but be sure to make it use the previously defined adapter with said settings.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;constraining-the-interface&quot;&gt;Constraining the interface&lt;a class=&quot;zola-anchor&quot; href=&quot;#constraining-the-interface&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Using traffic control (tc), we can constrain the vboxnet0 interface without harming our main internet-providing interface (typically eth0 or wlan0, YMMV). However I recommend the tc wrapper &lt;strong&gt;tcconfig&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;access-the-host-from-the-vm&quot;&gt;Access the host from the VM&lt;a class=&quot;zola-anchor&quot; href=&quot;#access-the-host-from-the-vm&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Another requirement for me was to setup a second interface for the host to get access to the host services without the constraint of tc. This time add a new Host-Only adapter with the embedded DHCP activated. You can access the host through this interface just by going to the adapter’s address.&lt;&#x2F;p&gt;
&lt;p&gt;To do it the other way around, just type :&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;VBoxManage&lt;&#x2F;span&gt;&lt;span&gt; list vms
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;VBoxManage&lt;&#x2F;span&gt;&lt;span&gt; guestproperty get &amp;lt;vm name&amp;gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;VirtualBox&#x2F;GuestInfo&#x2F;Net&#x2F;0&#x2F;V4&#x2F;IP&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</description>
                <content:encoded>&lt;p&gt;VirtualBox provides a traffic limiting tool through its CLI interface. However, one might want to use the full power of traffic control to further limit or shape the traffic going in&#x2F;out or ever between VMs. Problems arise when your VM needs access to internet, and we are going to see how to circumvent them.&lt;&#x2F;p&gt;
&lt;p&gt;VirtualBox does a fairly good job with its built-in &lt;em&gt;NAT adapter&lt;&#x2F;em&gt; feature. But it does so by using a socket and not a distinct network device visible in &#x2F;sys&#x2F;class&#x2F;net&#x2F;. This comes with some drawbacks:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You can’t easily monitor the network on the built-in NAT.  So if your VM is misbehaving, you couldn’t use tcpdump to troubleshoot.&lt;&#x2F;li&gt;
&lt;li&gt;The built in NAT reaches directly to the Internet in a transparent manner.  If you wanted to control access to the Internet you would have to switch to a bridge device or go with host-only.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I figured out the only solution to these would be to make the VM use an interface I could fully control. And while Virtualbox supports an option through the CLI utility VBoxManage to make the built-in NAT go through an interface by designating its IP, I went for another option: make a &lt;em&gt;Host-Only adapter&lt;&#x2F;em&gt; in Virtualbox.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;getting-a-host-only-adapter&quot;&gt;Getting a Host-Only adapter&lt;a class=&quot;zola-anchor&quot; href=&quot;#getting-a-host-only-adapter&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;This is done in &lt;code&gt;File -&amp;gt; Preferences -&amp;gt; Network&lt;&#x2F;code&gt;. Click the green icon with a PLUS sign in it.  A new network is created, probably called vboxnet0. Then click the little screwdriver icon to edit the vboxnet0 settings. Select the DHCP Server tab and make sure “Enable Server” is unticked. It will be ticked by default. We don’t want the default DHCP server, because it will bind its lease on the Virtualbox socket.&lt;&#x2F;p&gt;
&lt;p&gt;Then install &lt;strong&gt;dnsmasq&lt;&#x2F;strong&gt;. We are gonna use it to deal with the DHCP leases and DNS entries. While dnsmasq configuration can vary depending on your host system, it is generally found under a &lt;em&gt;&#x2F;etc&#x2F;dnsmasq.conf&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;interface&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;vboxnet0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;bind-interface
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;dhcp-range&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;192.168.56.2,192.168.56.150
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The range is up to you. If you set the vboxnet0 adapter to 192.168.56.0&#x2F;24, then any range within this lane will fit. After you have done it, restart the dnsmasq service with your host service manager.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kernel-nat-masquerading&quot;&gt;Kernel NAT Masquerading&lt;a class=&quot;zola-anchor&quot; href=&quot;#kernel-nat-masquerading&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;The big advantage of having that network device for ourselves and not just hidden inside a socket managed by Virtualbox is that we can now use kernel features to deal with packets. But that also means we have to setup the NAT feature ourselves. Hopefully this is (almost) a one-liner.&lt;&#x2F;p&gt;
&lt;p&gt;We are gonna use &lt;strong&gt;iptables&lt;&#x2F;strong&gt; for this. If you are using another firewall like ufw, disable it beforehand.&lt;&#x2F;p&gt;
&lt;p&gt;We also have to activate the ip forwarding at the kernel level. It can be done in &lt;em&gt;&#x2F;etc&#x2F;syctl.conf&lt;&#x2F;em&gt; or by running &lt;code&gt;sysctl -w net.ipv4.ip_forward=1&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Then we can setup the nat filter rule for iptables with &lt;code&gt;iptables -t nat -A POSTROUTING -s 192.168.56.0&#x2F;24 -j MASQUERADE&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Make sure to have the iptables running and to save the configuration with &lt;code&gt;iptables-save &amp;gt; &#x2F;etc&#x2F;iptables&#x2F;iptables.rules&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We then have an operable interface. You can launch the VM, but be sure to make it use the previously defined adapter with said settings.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;constraining-the-interface&quot;&gt;Constraining the interface&lt;a class=&quot;zola-anchor&quot; href=&quot;#constraining-the-interface&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Using traffic control (tc), we can constrain the vboxnet0 interface without harming our main internet-providing interface (typically eth0 or wlan0, YMMV). However I recommend the tc wrapper &lt;strong&gt;tcconfig&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;access-the-host-from-the-vm&quot;&gt;Access the host from the VM&lt;a class=&quot;zola-anchor&quot; href=&quot;#access-the-host-from-the-vm&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h3&gt;
&lt;p&gt;Another requirement for me was to setup a second interface for the host to get access to the host services without the constraint of tc. This time add a new Host-Only adapter with the embedded DHCP activated. You can access the host through this interface just by going to the adapter’s address.&lt;&#x2F;p&gt;
&lt;p&gt;To do it the other way around, just type :&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;VBoxManage&lt;&#x2F;span&gt;&lt;span&gt; list vms
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;VBoxManage&lt;&#x2F;span&gt;&lt;span&gt; guestproperty get &amp;lt;vm name&amp;gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;VirtualBox&#x2F;GuestInfo&#x2F;Net&#x2F;0&#x2F;V4&#x2F;IP&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content:encoded>
            </item>
        
            <item>
                <title>Free servers for students of the university</title>
                <pubDate>Fri, 09 Sep 2016 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/free-servers-university/</link>
                <guid>https://rigelk.frama.io/blog/blog/free-servers-university/</guid>
                <description>&lt;p&gt;Sometimes it becomes tricky to get a good machine to run tests or research programs, be it as a Ph.d student or as freshman willing to discover what bare metal means.&lt;&#x2F;p&gt;
&lt;p&gt;As I’ve always been interested in hardware, I couldn’t feed my appetite for network programming and machines with the few courses provided by the university. Seems like those courses only teach you to write down pseudo-code on paper…&lt;&#x2F;p&gt;
&lt;p&gt;That’s why I joined the IT association ASCIII : to get my hands dirty ! The association, however, was empty at first as I only found a Dell Poweredge 4200. An old 2003 server aimed at small offices for backup. It was more like a bench than a computer (for those wondering it did end up as a bench ;). Pwah ! That is certainly the worst thing I could find.&lt;&#x2F;p&gt;
&lt;p&gt;So I decided to gather some hardware to play with.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-teaching-platform&quot;&gt;A teaching platform&lt;a class=&quot;zola-anchor&quot; href=&quot;#a-teaching-platform&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;I come from the Internet. A place where one needs to learn by oneself. It is quite different however down here on planet Earth : one needs tools to experiment with and show others.&lt;&#x2F;p&gt;
&lt;p&gt;That comes with physical machines. The kind of you can play with, look at the internals and make work as long as you care about them. Well, I could have risen an army of old computers but that wouldn’t fit in the small office of the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;ascii.univ-nantes.fr&#x2F;&quot;&gt;ASCII&lt;&#x2F;a&gt; ! Plus, servers are a different kind of hardware, more specific but also more reliable. They bring a whole new dimension to hardware understanding and their firepower shadows their age. (with an average of 8 years)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-testlab&quot;&gt;A testlab&lt;a class=&quot;zola-anchor&quot; href=&quot;#a-testlab&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;With great power come great responsabilty. Well, not here. Those machines are here to get dirty and anybody can test what he wants.&lt;&#x2F;p&gt;
&lt;p&gt;We ended up with no less that 5 running servers by the end of the 2015 academic year :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;3 HP Proliant 3650 (8GB RAM&#x2F;140GB HDD each)&lt;&#x2F;li&gt;
&lt;li&gt;1 Dell PowerEdge 1750 (4GB RAM&#x2F;140HB HDD)&lt;&#x2F;li&gt;
&lt;li&gt;1 homemade server with 16GB RAM and ~300GB mixed SATA&#x2F;PATA drives&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;moar-service-ideas&quot;&gt;Moar service ideas&lt;a class=&quot;zola-anchor&quot; href=&quot;#moar-service-ideas&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;The number of servers a bay can hold is more than enough to get a part of it for the testlab, and the other for durable services.&lt;&#x2F;p&gt;
&lt;p&gt;At least, those services are reachable in the ASCII network. It is quite small but with a few Wifi antennas it can cover the whole campus !&lt;&#x2F;p&gt;
&lt;p&gt;As for the services involved, it can be as cool as a showcase of students’ work, an archive to examination corrections, or it can be as fun as a gaming server, for furious in-university gaming (which already exists but lacks good infrastructure). It can and will eventually more be research-oriented, with the disposal of servers to doctorate students for heavy calculus.
why calculus ?&lt;&#x2F;p&gt;
&lt;p&gt;Well, after SETI@HOME and such decentralised projects which give you the ability to dispose your machine to others when it’s not used by you (more specificaly, it’s giving NASA CPU cycles you don’t make use of), the idea of letting the cluster of servers I had gathered in an idle state (due to its use by university students only being made during work hours) seemed unthinkable. That would have been a huge waste.&lt;&#x2F;p&gt;
&lt;p&gt;First, a waste of electricity as the machines are conveniently running 24&#x2F;7. Then, a waste of hardware as servers wear slowly.&lt;&#x2F;p&gt;
&lt;p&gt;Then, I guess the choice is due to our commitment to the libre&#x2F;open source community. When you get so many it’s always good to give back, be it with pure calculus or remote compilation for open source projects.&lt;&#x2F;p&gt;
</description>
                <content:encoded>&lt;p&gt;Sometimes it becomes tricky to get a good machine to run tests or research programs, be it as a Ph.d student or as freshman willing to discover what bare metal means.&lt;&#x2F;p&gt;
&lt;p&gt;As I’ve always been interested in hardware, I couldn’t feed my appetite for network programming and machines with the few courses provided by the university. Seems like those courses only teach you to write down pseudo-code on paper…&lt;&#x2F;p&gt;
&lt;p&gt;That’s why I joined the IT association ASCIII : to get my hands dirty ! The association, however, was empty at first as I only found a Dell Poweredge 4200. An old 2003 server aimed at small offices for backup. It was more like a bench than a computer (for those wondering it did end up as a bench ;). Pwah ! That is certainly the worst thing I could find.&lt;&#x2F;p&gt;
&lt;p&gt;So I decided to gather some hardware to play with.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-teaching-platform&quot;&gt;A teaching platform&lt;a class=&quot;zola-anchor&quot; href=&quot;#a-teaching-platform&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;I come from the Internet. A place where one needs to learn by oneself. It is quite different however down here on planet Earth : one needs tools to experiment with and show others.&lt;&#x2F;p&gt;
&lt;p&gt;That comes with physical machines. The kind of you can play with, look at the internals and make work as long as you care about them. Well, I could have risen an army of old computers but that wouldn’t fit in the small office of the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;ascii.univ-nantes.fr&#x2F;&quot;&gt;ASCII&lt;&#x2F;a&gt; ! Plus, servers are a different kind of hardware, more specific but also more reliable. They bring a whole new dimension to hardware understanding and their firepower shadows their age. (with an average of 8 years)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-testlab&quot;&gt;A testlab&lt;a class=&quot;zola-anchor&quot; href=&quot;#a-testlab&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;With great power come great responsabilty. Well, not here. Those machines are here to get dirty and anybody can test what he wants.&lt;&#x2F;p&gt;
&lt;p&gt;We ended up with no less that 5 running servers by the end of the 2015 academic year :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;3 HP Proliant 3650 (8GB RAM&#x2F;140GB HDD each)&lt;&#x2F;li&gt;
&lt;li&gt;1 Dell PowerEdge 1750 (4GB RAM&#x2F;140HB HDD)&lt;&#x2F;li&gt;
&lt;li&gt;1 homemade server with 16GB RAM and ~300GB mixed SATA&#x2F;PATA drives&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;moar-service-ideas&quot;&gt;Moar service ideas&lt;a class=&quot;zola-anchor&quot; href=&quot;#moar-service-ideas&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;The number of servers a bay can hold is more than enough to get a part of it for the testlab, and the other for durable services.&lt;&#x2F;p&gt;
&lt;p&gt;At least, those services are reachable in the ASCII network. It is quite small but with a few Wifi antennas it can cover the whole campus !&lt;&#x2F;p&gt;
&lt;p&gt;As for the services involved, it can be as cool as a showcase of students’ work, an archive to examination corrections, or it can be as fun as a gaming server, for furious in-university gaming (which already exists but lacks good infrastructure). It can and will eventually more be research-oriented, with the disposal of servers to doctorate students for heavy calculus.
why calculus ?&lt;&#x2F;p&gt;
&lt;p&gt;Well, after SETI@HOME and such decentralised projects which give you the ability to dispose your machine to others when it’s not used by you (more specificaly, it’s giving NASA CPU cycles you don’t make use of), the idea of letting the cluster of servers I had gathered in an idle state (due to its use by university students only being made during work hours) seemed unthinkable. That would have been a huge waste.&lt;&#x2F;p&gt;
&lt;p&gt;First, a waste of electricity as the machines are conveniently running 24&#x2F;7. Then, a waste of hardware as servers wear slowly.&lt;&#x2F;p&gt;
&lt;p&gt;Then, I guess the choice is due to our commitment to the libre&#x2F;open source community. When you get so many it’s always good to give back, be it with pure calculus or remote compilation for open source projects.&lt;&#x2F;p&gt;
</content:encoded>
            </item>
        
            <item>
                <title>The age of engineering ignorance</title>
                <pubDate>Sat, 30 Jul 2016 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/engineering-ignorance/</link>
                <guid>https://rigelk.frama.io/blog/blog/engineering-ignorance/</guid>
                <description>&lt;p&gt;Highschool students may admit it or not, they ignore a lot about the choices they make. Taking whatever course we want? Parents often let us go our way. And when they push us, it’s just not our choice. Duh.&lt;&#x2F;p&gt;
&lt;p&gt;Most students haven’t experienced enough to actually choose a major. They often mimic others or just choose what seems to be the easiest way out. I am of the few who made their mind about what they wanted to do before graduation, so that i could choose a corresponding major for my last year in highschool. That didn’t make my life easier, but at least I am sure of what I want to do. A lot of people don’t have that chance and choose either:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the easiest major&lt;&#x2F;li&gt;
&lt;li&gt;the same major as friends&lt;&#x2F;li&gt;
&lt;li&gt;the major they see fit their gender&#x2F;lifestyle&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This is a common situation for students. It’s easy to listen to these voices in our heads – invisible scripts – that dictate our everyday behavior and impact our lifelong success. They may feel that is “enough” if the subject feels “right”. They may even avoid trying to avoid failing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;schools-should-we-care&quot;&gt;Schools: should we care?&lt;a class=&quot;zola-anchor&quot; href=&quot;#schools-should-we-care&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;As long as the default choices are in average balanced both in parity and quantity, that ignorance only has two (though significant) consequences:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;feeling low&lt;&#x2F;li&gt;
&lt;li&gt;postponing career start&#x2F;progression&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;once employed, it is way more difficult to find time&#x2F;money to study again and change a career path.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;But as one witnesses in college, parity is rarely respected and quantity – though difficult to consider beyond capacity – no better. That means default choices are replicating sexist quotas.&lt;&#x2F;p&gt;
&lt;p&gt;Unfortunately schools don’t have the budget to change the situation and they’re not the victims of that lack of information given to students. We are. Engineering jobs are. Men&#x2F;Women ratios in all professions are.&lt;&#x2F;p&gt;
&lt;p&gt;That is a dangerous mix. Students won’t be as happy as they could be, we won’t get a good parity, and we will have our lot of lost souls, that just aren’t doing the right job. Yes, that means companies could find more easily engineers! With people choosing a job rather than a default one, no wonder they prove more valuable to companies.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;beyond-school-the-it-example&quot;&gt;Beyond school: the IT example&lt;a class=&quot;zola-anchor&quot; href=&quot;#beyond-school-the-it-example&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;As a computer scientist, I often see the results of both ignorance and history facts: the IT sector had a better women ratio in the fifties than it has now (see the ENIAC girls pictured in this article), as the coding task was only devoluted to women. Coding in its early days consisted indeed mainly in reproducing branching sequences on the target machine – that arid work was unattractive to men, hence the high ratio women&#x2F;men in the field at the time.&lt;&#x2F;p&gt;
&lt;p&gt;Then what made the IT field get that low ratio we have now? What shaped the profession and how non-programmers and potential aspiring programmers perceive it? And how might all that be connected to our ongoing struggle to achieve more diversity in the industry?&lt;&#x2F;p&gt;
&lt;p&gt;In her speech a programmer is… (2015, Codemotion Berlin), Brigitta Böckeler pointed out that back in the 60s, programming was considered a “Black Art” and that “Programmers are born, not made”. So… Forty years later, we still hear these stories:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;There are people who are born to do this, and I am not one of them. And it’s definitely not one of those things that, like, “Oh, with practice, you will become one who is born to do it.” …
You just gotta be born to be like, ‘Computers! Yeah! They are awesome!! They are my life!’ You know, a lot of computer scientists, that’s all they do.”
&lt;cite&gt;a CS student, ca. 2014&lt;&#x2F;cite&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;That couldn’t be worse: even us programmers consider ourselves to be part of a community that corresponds to the image we need to get rid of to reach balance. The fact is, that image finds its roots with the recruiting tests to find programmers in the 60s. At the time, companies didn’t know what were the common caracteristics among programmers. So they looked at the programmers they had at the time. They found that they were:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;crazy about puzzles&lt;&#x2F;li&gt;
&lt;li&gt;tend to like research applications and risk-taking&lt;&#x2F;li&gt;
&lt;li&gt;dislike routine and regimentation&lt;&#x2F;li&gt;
&lt;li&gt;and don’t like people…&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;(source: William M. Cannon and Dallis K. Perry. 1966. A vocational interest scale for computer programmers. In Proceedings of the fourth SIGCPR conference on Computer personnel research (SIGCPR ’66), A. W. Stalnaker (Ed.). ACM, New York, NY, USA, 61-82. )&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“If we are using a single model to identify potential programmers, we
will miss many potential students.”&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;So the first thing is to fight that model we still convey fifty years later, by not using it to recruit and developing models we would like to positively shape the IT field.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;create-experiences&quot;&gt;Create experiences&lt;a class=&quot;zola-anchor&quot; href=&quot;#create-experiences&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;And not just conferences.&lt;&#x2F;p&gt;
&lt;p&gt;You code? Go volunteer to teach practical IT at your local highschool, be it for a workshop or in the long run.&lt;&#x2F;p&gt;
&lt;p&gt;You’re a techie girl? Go show girls and boys computer science is not (only) for hooded nerds.&lt;&#x2F;p&gt;
&lt;p&gt;You’re a teacher? What are you waiting for? Make your students do something with practical purpose and a clear vision that they can later leverage not only as a grade, but as an insightful experience. All students are skeptical of the course they are given. Even the most theoretical course can be interesting if they focus (and of course they don’t), but focus is not a magical thing that some students have and others don’t. Focus comes with interest, and interest with a sense of purpose, so make the latter very clear upfront.&lt;&#x2F;p&gt;
</description>
                <content:encoded>&lt;p&gt;Highschool students may admit it or not, they ignore a lot about the choices they make. Taking whatever course we want? Parents often let us go our way. And when they push us, it’s just not our choice. Duh.&lt;&#x2F;p&gt;
&lt;p&gt;Most students haven’t experienced enough to actually choose a major. They often mimic others or just choose what seems to be the easiest way out. I am of the few who made their mind about what they wanted to do before graduation, so that i could choose a corresponding major for my last year in highschool. That didn’t make my life easier, but at least I am sure of what I want to do. A lot of people don’t have that chance and choose either:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the easiest major&lt;&#x2F;li&gt;
&lt;li&gt;the same major as friends&lt;&#x2F;li&gt;
&lt;li&gt;the major they see fit their gender&#x2F;lifestyle&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This is a common situation for students. It’s easy to listen to these voices in our heads – invisible scripts – that dictate our everyday behavior and impact our lifelong success. They may feel that is “enough” if the subject feels “right”. They may even avoid trying to avoid failing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;schools-should-we-care&quot;&gt;Schools: should we care?&lt;a class=&quot;zola-anchor&quot; href=&quot;#schools-should-we-care&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;As long as the default choices are in average balanced both in parity and quantity, that ignorance only has two (though significant) consequences:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;feeling low&lt;&#x2F;li&gt;
&lt;li&gt;postponing career start&#x2F;progression&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;once employed, it is way more difficult to find time&#x2F;money to study again and change a career path.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;But as one witnesses in college, parity is rarely respected and quantity – though difficult to consider beyond capacity – no better. That means default choices are replicating sexist quotas.&lt;&#x2F;p&gt;
&lt;p&gt;Unfortunately schools don’t have the budget to change the situation and they’re not the victims of that lack of information given to students. We are. Engineering jobs are. Men&#x2F;Women ratios in all professions are.&lt;&#x2F;p&gt;
&lt;p&gt;That is a dangerous mix. Students won’t be as happy as they could be, we won’t get a good parity, and we will have our lot of lost souls, that just aren’t doing the right job. Yes, that means companies could find more easily engineers! With people choosing a job rather than a default one, no wonder they prove more valuable to companies.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;beyond-school-the-it-example&quot;&gt;Beyond school: the IT example&lt;a class=&quot;zola-anchor&quot; href=&quot;#beyond-school-the-it-example&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;As a computer scientist, I often see the results of both ignorance and history facts: the IT sector had a better women ratio in the fifties than it has now (see the ENIAC girls pictured in this article), as the coding task was only devoluted to women. Coding in its early days consisted indeed mainly in reproducing branching sequences on the target machine – that arid work was unattractive to men, hence the high ratio women&#x2F;men in the field at the time.&lt;&#x2F;p&gt;
&lt;p&gt;Then what made the IT field get that low ratio we have now? What shaped the profession and how non-programmers and potential aspiring programmers perceive it? And how might all that be connected to our ongoing struggle to achieve more diversity in the industry?&lt;&#x2F;p&gt;
&lt;p&gt;In her speech a programmer is… (2015, Codemotion Berlin), Brigitta Böckeler pointed out that back in the 60s, programming was considered a “Black Art” and that “Programmers are born, not made”. So… Forty years later, we still hear these stories:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;There are people who are born to do this, and I am not one of them. And it’s definitely not one of those things that, like, “Oh, with practice, you will become one who is born to do it.” …
You just gotta be born to be like, ‘Computers! Yeah! They are awesome!! They are my life!’ You know, a lot of computer scientists, that’s all they do.”
&lt;cite&gt;a CS student, ca. 2014&lt;&#x2F;cite&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;That couldn’t be worse: even us programmers consider ourselves to be part of a community that corresponds to the image we need to get rid of to reach balance. The fact is, that image finds its roots with the recruiting tests to find programmers in the 60s. At the time, companies didn’t know what were the common caracteristics among programmers. So they looked at the programmers they had at the time. They found that they were:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;crazy about puzzles&lt;&#x2F;li&gt;
&lt;li&gt;tend to like research applications and risk-taking&lt;&#x2F;li&gt;
&lt;li&gt;dislike routine and regimentation&lt;&#x2F;li&gt;
&lt;li&gt;and don’t like people…&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;(source: William M. Cannon and Dallis K. Perry. 1966. A vocational interest scale for computer programmers. In Proceedings of the fourth SIGCPR conference on Computer personnel research (SIGCPR ’66), A. W. Stalnaker (Ed.). ACM, New York, NY, USA, 61-82. )&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;“If we are using a single model to identify potential programmers, we
will miss many potential students.”&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;So the first thing is to fight that model we still convey fifty years later, by not using it to recruit and developing models we would like to positively shape the IT field.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;create-experiences&quot;&gt;Create experiences&lt;a class=&quot;zola-anchor&quot; href=&quot;#create-experiences&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;And not just conferences.&lt;&#x2F;p&gt;
&lt;p&gt;You code? Go volunteer to teach practical IT at your local highschool, be it for a workshop or in the long run.&lt;&#x2F;p&gt;
&lt;p&gt;You’re a techie girl? Go show girls and boys computer science is not (only) for hooded nerds.&lt;&#x2F;p&gt;
&lt;p&gt;You’re a teacher? What are you waiting for? Make your students do something with practical purpose and a clear vision that they can later leverage not only as a grade, but as an insightful experience. All students are skeptical of the course they are given. Even the most theoretical course can be interesting if they focus (and of course they don’t), but focus is not a magical thing that some students have and others don’t. Focus comes with interest, and interest with a sense of purpose, so make the latter very clear upfront.&lt;&#x2F;p&gt;
</content:encoded>
            </item>
        
            <item>
                <title>Benchmarking (raw) speech recognition APIs</title>
                <pubDate>Wed, 13 Jul 2016 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/benchmarking-speech-apis/</link>
                <guid>https://rigelk.frama.io/blog/blog/benchmarking-speech-apis/</guid>
                <description>&lt;p&gt;This is a research draft and while its aim is to benchmark APIs, it recommends tools that have not been benchmarked. So if you feel some tools would better fit, please reach out!&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;api.ai: &lt;em&gt;untested&lt;&#x2F;em&gt; -&amp;gt; paid plan required&lt;&#x2F;li&gt;
&lt;li&gt;Amazon voice service: &lt;em&gt;untested&lt;&#x2F;em&gt; -&amp;gt; german model unavailable (english only)&lt;&#x2F;li&gt;
&lt;li&gt;Nuance ASR: &lt;em&gt;tested&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Google Voice Service: &lt;em&gt;test planned&lt;&#x2F;em&gt; -&amp;gt; waiting for the use request approval&lt;&#x2F;li&gt;
&lt;li&gt;Microsoft Cognitive Services (formerly Project Oxford) Speech To Text API: &lt;em&gt;untested&lt;&#x2F;em&gt; -&amp;gt; unless you use their SDK (iOS, Android, C#), you cannot stream to their service and only use a REST API with no partial result streaming.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;from-uses-cases-to-audio-files&quot;&gt;From uses cases to audio files&lt;a class=&quot;zola-anchor&quot; href=&quot;#from-uses-cases-to-audio-files&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Would you want to replicate that little test, you need to use a few use cases to asses the variety of domains supported by the API. I focused on what my use cases were at the time: problem description with audio of varying length (15 to 256s, 6 use cases).&lt;&#x2F;p&gt;
&lt;p&gt;We used the following sequence for experiment purposes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Delivered an audio file with recorded search phrases to external services&lt;&#x2F;li&gt;
&lt;li&gt;Received recognized text from automatic speech recognition service&lt;&#x2F;li&gt;
&lt;li&gt;Evaluated quality metrics of recognized text vs. actual search phrase&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;converting-audio-files&quot;&gt;Converting audio files&lt;a class=&quot;zola-anchor&quot; href=&quot;#converting-audio-files&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Here I used the sox CLI tool, which stands for &lt;strong&gt;So&lt;&#x2F;strong&gt;und e&lt;strong&gt;X&lt;&#x2F;strong&gt;change. I actually just needed to convert a stereo 44.1kHz floating point mp3 file to 16kHz, merge it into a single mono file, convert the mono file to a signed PCM, process some filter on the raw files, convert them back to mono WAVs (that’s the api.ai requirements). To accomplish this, I used these commands, which were neither well documented, nor correctly referred to by most of the blogs I’ve read today, even five years later¹.&lt;&#x2F;p&gt;
&lt;p&gt;First, if you don’t know what your audio files are made of, use soxi:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;benchmarking-speech-apis&#x2F;soxi1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Then, the basics. The following converts to wave, only keeps the left channel (channel 1, thus converting to mono if it wasn’t already) and to a sample rate of 16000kHz with the sox intents.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;sox Example1.mp3 Example1.wav channels 1 rate 16k  
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But the signed PCM² is still lacking.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;sox Example1.mp3 -e signed-integer Example1.wav channels 1 rate 16k  
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Problem n°1&lt;&#x2F;strong&gt;: we have to take into account more information-rich files (especially stereo, even if it is unlikely with phone or laptop microphones). Here we keep stereo info by doing a mix-down of both channels, averaging them:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;sox stereo.wav -c 1 mono.wav avg  
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Problem n°2&lt;&#x2F;strong&gt;: we have to reduce clipping. Clipping is distortion that occurs when an audio signal level (or ‘volume’) exceeds the range of the chosen representation. In most cases, clipping is undesirable and so should be corrected by adjusting the level prior to the point (in the processing chain) at which it occurs.&lt;&#x2F;p&gt;
&lt;p&gt;In SoX, clipping could occur, as you might expect, when using the vol or gain effects to increase the audio volume. Clipping could also occur with many other effects, when converting one format to another, and even when simply playing the audio.&lt;&#x2F;p&gt;
&lt;p&gt;For these reasons, it is usual to make sure that an audio file’s signal level has some ‘headroom’, i.e. it does not exceed a particular level below the maximum possible level for the given representation. Some standards bodies recommend as much as 9dB headroom, but in most cases, 3dB (≈ 70% linear) is enough. Note that this wisdom seems to have been lost in modern music production; in fact, many CDs, MP3s, etc. are now mastered at levels above 0dBFS i.e. the audio is clipped as delivered³.&lt;&#x2F;p&gt;
&lt;p&gt;All of that can be fine tuned by hand, and I tried a few tweaks that may prove useful on other, more complicated examples. But as my dataset was quite simple, and sox has a neat -G option to do it automagically, I used the latter.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Problem n°3&lt;&#x2F;strong&gt;: Dither. Same thing. Sox does a lot and dither awaits around the corner. Apply dither whenever reducing bit depth, to ameliorate the bad effects of quantization error, with the dither sox intent.&lt;&#x2F;p&gt;
&lt;p&gt;All of that to obtain a good input audio file:&lt;&#x2F;p&gt;
</description>
                <content:encoded>&lt;p&gt;This is a research draft and while its aim is to benchmark APIs, it recommends tools that have not been benchmarked. So if you feel some tools would better fit, please reach out!&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;api.ai: &lt;em&gt;untested&lt;&#x2F;em&gt; -&amp;gt; paid plan required&lt;&#x2F;li&gt;
&lt;li&gt;Amazon voice service: &lt;em&gt;untested&lt;&#x2F;em&gt; -&amp;gt; german model unavailable (english only)&lt;&#x2F;li&gt;
&lt;li&gt;Nuance ASR: &lt;em&gt;tested&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Google Voice Service: &lt;em&gt;test planned&lt;&#x2F;em&gt; -&amp;gt; waiting for the use request approval&lt;&#x2F;li&gt;
&lt;li&gt;Microsoft Cognitive Services (formerly Project Oxford) Speech To Text API: &lt;em&gt;untested&lt;&#x2F;em&gt; -&amp;gt; unless you use their SDK (iOS, Android, C#), you cannot stream to their service and only use a REST API with no partial result streaming.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;from-uses-cases-to-audio-files&quot;&gt;From uses cases to audio files&lt;a class=&quot;zola-anchor&quot; href=&quot;#from-uses-cases-to-audio-files&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Would you want to replicate that little test, you need to use a few use cases to asses the variety of domains supported by the API. I focused on what my use cases were at the time: problem description with audio of varying length (15 to 256s, 6 use cases).&lt;&#x2F;p&gt;
&lt;p&gt;We used the following sequence for experiment purposes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Delivered an audio file with recorded search phrases to external services&lt;&#x2F;li&gt;
&lt;li&gt;Received recognized text from automatic speech recognition service&lt;&#x2F;li&gt;
&lt;li&gt;Evaluated quality metrics of recognized text vs. actual search phrase&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;converting-audio-files&quot;&gt;Converting audio files&lt;a class=&quot;zola-anchor&quot; href=&quot;#converting-audio-files&quot;&gt;&lt;&#x2F;a&gt;&amp;nbsp;&lt;&#x2F;h2&gt;
&lt;p&gt;Here I used the sox CLI tool, which stands for &lt;strong&gt;So&lt;&#x2F;strong&gt;und e&lt;strong&gt;X&lt;&#x2F;strong&gt;change. I actually just needed to convert a stereo 44.1kHz floating point mp3 file to 16kHz, merge it into a single mono file, convert the mono file to a signed PCM, process some filter on the raw files, convert them back to mono WAVs (that’s the api.ai requirements). To accomplish this, I used these commands, which were neither well documented, nor correctly referred to by most of the blogs I’ve read today, even five years later¹.&lt;&#x2F;p&gt;
&lt;p&gt;First, if you don’t know what your audio files are made of, use soxi:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;rigelk.frama.io&#x2F;blog&#x2F;blog&#x2F;benchmarking-speech-apis&#x2F;soxi1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Then, the basics. The following converts to wave, only keeps the left channel (channel 1, thus converting to mono if it wasn’t already) and to a sample rate of 16000kHz with the sox intents.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;sox Example1.mp3 Example1.wav channels 1 rate 16k  
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But the signed PCM² is still lacking.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;sox Example1.mp3 -e signed-integer Example1.wav channels 1 rate 16k  
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Problem n°1&lt;&#x2F;strong&gt;: we have to take into account more information-rich files (especially stereo, even if it is unlikely with phone or laptop microphones). Here we keep stereo info by doing a mix-down of both channels, averaging them:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;sox stereo.wav -c 1 mono.wav avg  
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Problem n°2&lt;&#x2F;strong&gt;: we have to reduce clipping. Clipping is distortion that occurs when an audio signal level (or ‘volume’) exceeds the range of the chosen representation. In most cases, clipping is undesirable and so should be corrected by adjusting the level prior to the point (in the processing chain) at which it occurs.&lt;&#x2F;p&gt;
&lt;p&gt;In SoX, clipping could occur, as you might expect, when using the vol or gain effects to increase the audio volume. Clipping could also occur with many other effects, when converting one format to another, and even when simply playing the audio.&lt;&#x2F;p&gt;
&lt;p&gt;For these reasons, it is usual to make sure that an audio file’s signal level has some ‘headroom’, i.e. it does not exceed a particular level below the maximum possible level for the given representation. Some standards bodies recommend as much as 9dB headroom, but in most cases, 3dB (≈ 70% linear) is enough. Note that this wisdom seems to have been lost in modern music production; in fact, many CDs, MP3s, etc. are now mastered at levels above 0dBFS i.e. the audio is clipped as delivered³.&lt;&#x2F;p&gt;
&lt;p&gt;All of that can be fine tuned by hand, and I tried a few tweaks that may prove useful on other, more complicated examples. But as my dataset was quite simple, and sox has a neat -G option to do it automagically, I used the latter.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Problem n°3&lt;&#x2F;strong&gt;: Dither. Same thing. Sox does a lot and dither awaits around the corner. Apply dither whenever reducing bit depth, to ameliorate the bad effects of quantization error, with the dither sox intent.&lt;&#x2F;p&gt;
&lt;p&gt;All of that to obtain a good input audio file:&lt;&#x2F;p&gt;
</content:encoded>
            </item>
        
            <item>
                <title>Good reads!</title>
                <pubDate>Fri, 24 Jun 2016 00:00:00 +0000</pubDate>
                <link>https://rigelk.frama.io/blog/blog/good-reads/</link>
                <guid>https://rigelk.frama.io/blog/blog/good-reads/</guid>
                <description>&lt;p&gt;Who would ever think of keeping track of books read and of the eventual progress in their reading? Well, that’s part of the concept of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;goodreads.com&#x2F;&quot;&gt;goodreads.com&lt;&#x2F;a&gt;, or at least the way I make use of its features since I discovered it a few days ago.&lt;&#x2F;p&gt;
&lt;p&gt;A quite small change in my life, but a useful one. Keeping track of activities has always proven useful (GitHub, Redmine, or for some hardcore users, social networks themselves), but I would never have expected that for books.&lt;&#x2F;p&gt;
&lt;p&gt;The site itself encourages you to register the books you already read, want to read or are currently reading. It acts like a to-to list, and for me as a way to showcase my readings (be it along my CV or to my friends to get recommendations based on what I’ve read). That creates a motivating synergy which made me read some books again and post update statuses of those I was reading.&lt;&#x2F;p&gt;
&lt;p&gt;Plus, I often read technical books and it is quite hard to find varied comments about them. Recently I found myself reading Introduction to Algorithms (Cormen, editions Dunod) and found only (extremely) positive comments on developer sites. As with masses, comments tend to reach a point where all counter-opinion is either ignored or not valued enough. Here on Goodreads, comments were surprisingly varied (though still positive) and easily &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;review&#x2F;show&#x2F;583842291&quot;&gt;pointed to alternatives&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If only traditional social networks were as refreshing!&lt;&#x2F;p&gt;
&lt;p&gt;P.S: a link with my &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;goodreads.com&#x2F;rigelk&quot;&gt;goodreads profile&lt;&#x2F;a&gt;, would you want to recommend me something.&lt;&#x2F;p&gt;
</description>
                <content:encoded>&lt;p&gt;Who would ever think of keeping track of books read and of the eventual progress in their reading? Well, that’s part of the concept of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;goodreads.com&#x2F;&quot;&gt;goodreads.com&lt;&#x2F;a&gt;, or at least the way I make use of its features since I discovered it a few days ago.&lt;&#x2F;p&gt;
&lt;p&gt;A quite small change in my life, but a useful one. Keeping track of activities has always proven useful (GitHub, Redmine, or for some hardcore users, social networks themselves), but I would never have expected that for books.&lt;&#x2F;p&gt;
&lt;p&gt;The site itself encourages you to register the books you already read, want to read or are currently reading. It acts like a to-to list, and for me as a way to showcase my readings (be it along my CV or to my friends to get recommendations based on what I’ve read). That creates a motivating synergy which made me read some books again and post update statuses of those I was reading.&lt;&#x2F;p&gt;
&lt;p&gt;Plus, I often read technical books and it is quite hard to find varied comments about them. Recently I found myself reading Introduction to Algorithms (Cormen, editions Dunod) and found only (extremely) positive comments on developer sites. As with masses, comments tend to reach a point where all counter-opinion is either ignored or not valued enough. Here on Goodreads, comments were surprisingly varied (though still positive) and easily &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.goodreads.com&#x2F;review&#x2F;show&#x2F;583842291&quot;&gt;pointed to alternatives&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If only traditional social networks were as refreshing!&lt;&#x2F;p&gt;
&lt;p&gt;P.S: a link with my &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;goodreads.com&#x2F;rigelk&quot;&gt;goodreads profile&lt;&#x2F;a&gt;, would you want to recommend me something.&lt;&#x2F;p&gt;
</content:encoded>
            </item>
        
    </channel>
</rss>
