Huhu, ich hab mir in den Kopf gesetzt, dass es doch eine gute Idee wäre, einen Blog zu haben. Also los geht’s… ähm, aber wie? Wie soll ich den Blog bereitstellen? Wie wird aus einem Text eine ansehnliche Internetseite? In diesem ersten Beitrag geht’s also darum, wie ich diesen Blog aufgesetzt habe. Zuerst einmal die Anforderungen:

Wie möchte ich Beiträge schreiben?

  • In einem Git Repository
  • In Markdown
  • Wenn ich Pushe soll automatisch veröffentlicht werden

Was soll der Blog dem Leser (technisch) bieten

  • Kommentare
  • Einigermaßen ansehnlich sein
  • RSS Feed

Wie man offensichtlich schon erkennt hab ich mich für Hugo als Framework und PaperMod als Theme entschieden. Das war soweit problemlos, abgesehen davon, dass PaperMod oft .Permalink anstatt .RelPermalink verwendet, aber dazu später mehr. Für die Kommentare habe ich einfach mastodon-comments benutzt.

Um möglichst wenig Überraschungen zu erfahren wenn plötzlich in einer CI Pipeline gebaut wird, wird hugo in einer Nix Derivation aufgerufen anstatt in der Pipeline direkt.

      blog = pkgs.stdenv.mkDerivation {
        name = "blog";
        src = ./.;
        nativeBuildInputs = [pkgs.hugo];
        buildPhase = ''
          mkdir -p themes/Theme
          cp -r ${theme}/* themes/Theme/
          hugo --minify
        '';
        installPhase = ''
          mkdir -p $out

          cp -r public/* $out
          sed '/prefers-color-scheme: dark/{n; s/:root {/html:not([data-theme="light"]) {/}' ${mastodon-comments}/mastodon-comments.js > $out/mastodon-comments.js
          cp ${dompurify}/dist/purify.min.js $out
          mkdir -p $out/font-awesome
          cp -r ${font-awesome}/{css,webfonts} $out/font-awesome
        '';
      };

So sieht das dann ungefähr aus. Die ganze Nix Flake gibt’s übrigens auf Radicle

Das ist ziemlich cool, jetzt kann ich einfach nix build aufrufen und bekomme die exakt selbe version die auch eine CI Pipeline bauen würde. Aber was ist jetzt mit der CI Pipeline? Die soll natürlich auch in der Lage sein den gebauten Blog zu veröffentlichen. Wie eigentlich fast jedes Problem lässt sich dieses auch durch eine Nix Derivation lösen :)

     publish =
        pkgs.writeShellScriptBin "publish"
        ''
          if ! cid=$(${pkgs.kubo}/bin/ipfs add --cid-version=1 $IPFS_FLAGS -r --quiet ${self.packages.${system}.blog} | tail -n1); then
            echo "IPFS upload failed"
            exit 1
          fi

          echo "Blog online on https://''${cid}".ipfs.menzel.lol

          ${pkgs.kubo}/bin/ipfs name publish -k blog ''${cid}

        '';

Dieses kleine Skript lädt den blog auf IPFS hoch und veröffentlicht ihn anschließend auf IPNS. Das geht aber nur wenn in der Umgebung in der das Skript läuft auch ein IPFS Knoten zur Verfügung steht. Auch dieses Problem löst Nix, bzw. genauer gesagt NixOS. Einfach den Kubo Service aktivieren services.kubo.enable = true und los geht’s.

Aber wie wird das Skript denn jetzt überhaupt ausgeführt? Dazu hab ich einfach den Radicle CI-Broker und den Native CI-Adapter installiert:

services.radicle = {
    ci = {
      broker = {
        enable = true;
        enableHardening = false;
        settings = {
          triggers = [
            {
              adapter = "default";
              filters = [
                {
                  And = [
                    {HasFile = ".radicle/native.yaml";}
                    {Node = "z6MkvyWEEW8wNFmkp7cnTuSsQ4YFHf1gb7FM6DeBGVgxeVSo";}
                    {
                      Or = [
                        "DefaultBranch"
                        "PatchCreated"
                        "PatchUpdated"
                      ];
                    }
                  ];
                }
              ];
            }
          ];
        };
      };
      adapters.native.instances.default = {
        enable = true;
        settings.base_url = "rad.menzel.lol";
        runtimePackages = with pkgs; [
          nix
          git
        ];
      };
    };
};

und im Repository die datei .radicle/native.yaml angelegt

shell: "nix run .#publish"

wenn ich jetzt also git push ausführe, kann man den blog bereits auf ipns://k51qzi5uqu5dkfgg4vy759ui3xogdttd8gmn31bn9w8om9obvjh3b24fkrj4kf oder auf jedem beliebigen IPFS Gateway aufrufen.

Das Ganze bis jetzt ohne Server :) :) :) ok die Aussage ist etwas gemogelt, weil ich den CI-Broker auf meinem Server ausführe, aber es würde auch problemlos auf jedem anderen NixOS gerät gehen, also auch auf meinem Laptop, aber es ist schon praktisch wenn der CI-Broker 24/7 läuft.

Jetzt habe ich auch das Problem mit den Absoluten vs. Relativen Links im PaperMod theme entdeckt, als baseURL hab ich (weil schlussendlich dort auch der Blog aufrufbar sein soll) blog.menzel.lol eingetragen, jetzt ist das aber noch nicht eingerichtet, also alle Navigations-Links führten immer zu https://blog.menzel.lol… was die Seite echt unbrauchbar macht. Ist aber nichts das sich nicht reparieren lässt.

Fehlt nur noch die Domain. DNS Link macht es schonmal möglich ipns://blog.menzel.lol aufzurufen, aber das ist immer noch nicht das Wahre. Jetzt kommt also die einzige stelle an der ich leider wirklich einen Server brauche. Auf dem Server habe ich Nginx so konfiguriert dass blog.menzel.lol zu blog-menzel-lol.ipns.menzel.lol geproxied wird.