Mon Blog // Archives numériques

Pensées, projets et notes techniques

À l'origine, la configuration de mon blog était prévue comme un projet exclusivement IPv6 via WireGuard, car le tout est hébergé sur un serveur domestique (on peut d'ailleurs obtenir des adresses IPv6 gratuites sur route64.org). Pour améliorer l'accessibilité, j'ai maintenant ajouté un proxy IPv4 externe (merci à @Larvitz).

Cependant, des problèmes SSL sont immédiatement apparus : comme les enregistrements A et AAAA passaient initialement tous deux par le proxy, la validation Let's Encrypt a échoué sur mon serveur.

La solution : le « hack IPv6 »

La solution a consisté à pointer explicitement l'enregistrement AAAA directement vers l'IP WireGuard de mon serveur, au lieu de le faire passer également par le proxy.

  • Domaine : blog.burningboard.org
  • Enregistrement A (Proxy) : 194.28.98.217
  • Enregistrement AAAA (Serveur) : 2a11:6c7:f05:a8::2 (WireGuard)

Grâce à cet enregistrement AAAA direct vers mon IP WireGuard, Let's Encrypt continue d'atteindre mon serveur directement via IPv6 (car l'enregistrement AAAA est prioritaire par défaut) et délivre le certificat SSL. Le trafic IPv4 est transmis de manière chiffrée par le proxy jusqu'à moi.

La configuration finale

Pour que la communication fonctionne sans accroc, nous avons dû adapter les serveurs Caddy :

1. Sur mon serveur (NixOS, blog.nix)

Pour que les adresses IP réelles des visiteurs arrivent correctement et ne soient pas écrasées par l'IP du proxy, celui-ci doit être marqué comme fiable :

services.caddy.globalConfig = ''
  servers {
      trusted_proxies static 2a06:9801:1c:1000::10
  }
'';

2. Sur le proxy externe (Caddy)

Pour que le proxy communique correctement avec mon serveur via HTTPS, il doit envoyer le nom d'hôte (SNI) :

reverse_proxy [https://[2a11:6c7:f05:a8::2]:443](https://[2a11:6c7:f05:a8::2]:443) {
    header_up Host {host}
    transport http {
        tls_server_name blog.burningboard.org
    }
}

Le blog est désormais accessible via IPv4 et IPv6, chiffré de manière sécurisée, et mon IP domestique reste tout de même privée ! 🚀

L'essentiel d'abord : les fichiers Markdown habituels restent la base – je suis tout simplement un grand fan de cette solution simple. Mais sous le capot, beaucoup de choses ont changé :

J'ai pas mal bricolé la configuration :

📂 Fichiers MD : La structure du blog reste simple, basée sur le Markdown.

🌍 Plus mondial que jamais : mon blog supporte désormais des traductions en 43 langues. Oui, y compris le klingon ! 🖖 (Qapla' !)

Ce qui était prévu, c'était une traduction en temps réel entièrement automatique basée sur la détection de la langue du navigateur. Spoiler : cela n'a fonctionné que partiellement. On s'en rend compte : l'IA est impressionnante, mais pas encore tout à fait « là » où nous aimerions qu'elle soit.

La solution : je traduis désormais chaque article à l'avance dans toutes les langues définies, ce qui est également bien meilleur pour le référencement (SEO). Si la détection automatique ne fonctionne pas, vous pouvez définir manuellement votre langue préférée via l'icône du globe, qui sera ensuite enregistrée très simplement via un cookie.

Les traductions sont désormais effectuées avec Gemini 3 Flash, ce qui donne des résultats étonnamment bons. Cependant, il faut surveiller l'IA de près : lors du premier passage en masse, les tags ont également été traduits par erreur, ce qui n'était évidemment pas prévu.

Le code est toujours disponible (n'hésitez pas à m'envoyer un message si vous êtes intéressé) 👍 Notez cependant que le système nécessite désormais sa propre clé API Gemini 🔑.

J'ai décidé de migrer mon blog de WriteFreely vers une solution développée par mes soins : MD-Blog (le MD signifie bien sûr Markdown). Le déclencheur a été l'échec d'une mise à jour de l'ancien système – mais au final, ce fut l'impulsion parfaite pour tout simplifier radicalement et reprendre le plein contrôle sur le design.

Le cœur du système repose sur de simples fichiers Markdown situés dans le dossier data/, qui sont convertis en HTML moderne lors de l'exécution. Le résultat est ultra-rapide, fonctionne sans base de données et, grâce à mon propre système de design (incluant le mode sombre), ressemble désormais exactement à ce que j'avais imaginé. Même un bouton de partage Mastodon moderne est désormais directement intégré.

Si vous êtes intéressés par le code ou cette configuration légère, n'hésitez pas à me contacter sur Mastodon !

En principe, l'idée derrière #Winboat est excellente, mais la mise en œuvre semble encore un peu instable pour le moment. Bien que le système ait fonctionné depuis l'installation au début de l'année, le logiciel a complètement cessé de fonctionner aujourd'hui.

L'image a soudainement signalé une mémoire vive (RAM) insuffisante. J'ai essayé de résoudre le problème manuellement, mais cela a malheureusement rendu le système définitivement inutilisable. Au lieu de perdre plus de temps à chercher l'erreur, je suis passé directement à l'image Windows Dockurr – celle-ci constitue de toute façon la base technique de Winboat.

Message d'erreur

1. Préparation

Comme j'utilise Podman, j'ai d'abord créé les répertoires nécessaires sur mon système hôte. Cela permet de préserver l'intégrité des données si le conteneur doit être recréé :

mkdir -p $HOME/Windows/System
mkdir -p $HOME/Windows/Shared

2. La commande de démarrage

Remarque importante : Dans les variables -e USERNAME et -e PASSWORD, remplacez les espaces réservés par vos identifiants personnels.

podman run -d \
  --name windows \
  -p 8006:8006 \
  --device=/dev/kvm \
  --cap-add NET_ADMIN \
  -e RAM_SIZE="8G" \
  -e USERNAME="Carsten" \
  -e PASSWORD="1234" \
  -e LANGUAGE="German" \
  -v $HOME/Windows/System:/storage:Z \
  -v $HOME/Windows/Shared:/shared:Z \
  --stop-timeout 120 \
  dockurr/windows

Une fois que le conteneur est actif, vous pouvez accéder à l'instance Windows directement via votre navigateur :

http://127.0.0.1:8006

Conteneur en cours d'exécution

3. Résumé

Je n'ai eu à exécuter la commande ci-dessus qu'une seule fois. En utilisation quotidienne, l'environnement Windows peut désormais être piloté très facilement via ces commandes rapides :

  • Démarrer : podman start windows
  • Arrêter : podman stop windows (ou arrêter directement depuis Windows)
  • Vérifier le statut : podman ps -a

Liens utiles :

J'ai installé mon propre blog — principalement pour mieux découvrir #NixOS. À ma grande surprise, tout s'est déroulé de manière assez simple.

WriteFreely s'y prête particulièrement bien : minimaliste, rapide à mettre en place et sans fioritures. C'est l'outil idéal pour se lancer tout en apprenant. La configuration est agréablement claire. Quelques options définies, un répertoire préparé, un reverse proxy devant — et le tour est joué.

Voici à quoi ressemble ma configuration NixOS actuelle pour ce service :

{ config, pkgs, ... }:

{
  services.writefreely = {
    enable = true;
    host = "blog.burningboard.org"; 
    settings = {
      server = {
        port = 8080;
        min_log_level = "debug";
      };
      app = {
        host = "https://blog.burningboard.org";
        single_user = true;
        landing = "/read";
        wf_modesty = true;
        federation = true;
        public_stats = true;
        theme = "write";
      };
    };
    stateDir = "/opt/writefreely";
  };

  # Correctif pour la génération de clés ActivityPub : la fédération nécessite openssl
  systemd.services.writefreely.path = [ pkgs.openssl ];

  # Création automatique du répertoire de données avec les permissions appropriées
  systemd.tmpfiles.rules = [
    "d /opt/writefreely 0700 writefreely writefreely -"
  ];

  services.caddy.virtualHosts."blog.burningboard.org".extraConfig = ''
    reverse_proxy 127.0.0.1:8080 {
      header_up Host {host}
      header_up X-Real-IP {remote_host}
      header_up X-Forwarded-For {remote_host}
      header_up X-Forwarded-Proto {scheme}
    }
  '';
}

C'est essentiellement tout. NixOS rend vraiment facile la configuration propre et reproductible de tels services.