So I rewrote my blog

Friday 18 October 2024 at 23:30 CEST

I have become a meme. It does not feel good.

Let's be honest. I was always a meme. My hobbies are computer programming, making coffee, and playing video games. I wear rectangular glasses and can't see without them. I have finger-toe shoes for running. My favourite band plays Viking metal. And rather than writing on my blog, I rewrote my blog.

The only weird thing about me is that I'm not white.

But I digress.

A computer person does some computering

I got bored of the previous incarnation of my blog (see the previous post, A new look). So I made a new one.

Part of this came from a frustration with Hugo, which is a very respectable static site generator, but not exactly what I was looking for. So, in the grand tradition of software programmers who get too full of themselves, I started to write my own.

It didn't need to do much, so I tried to make it work by combining existing utilities (primarily Pandoc) with Shake. This ended up going badly; I needed to process the YAML front-matter, which meant I had to use the Pandoc API, but then I couldn't get away with chaining it with other things to handle the "shortcodes" (Hugo-speak for custom injected behaviour)… long story short, didn't work.

I ended up settling on Eleventy, which solves most problems for me. It's not perfect, but we've already seen how striving for some kind of perfection turned out, so I guess I'm happy enough.

Porting the blog went pretty well once I settled on that.

Presenting: this website's tech stack

Why? Because for some reason, people care. I mean, I care too. I'm just surprised anyone else does.

Input

I mostly write the text, of course, but there's some other bits and bobs.

Third-party assets

All the code for this site was written by hand. However, it makes use of some third-party assets. All assets are hosted on this site and requests are not tracked.

The CSS makes use of Josh W. Comeau's Modern CSS Reset (public domain).

The colours are from the gorgeous Catppuccin pastel colour theme (MIT-licensed), slightly tweaked.

The fonts are:

All fonts used are licensed under the SIL Open Font License 1.1.

In some posts, code is optionally embedded in a CodePen so that you can see the result of some CSS or JavaScript. There's some custom JavaScript wrapping this so that CodePens are only loaded when someone clicks the appropriate button. Until then, no third-party code is loaded, and the code is rendered as normal, without the result. At the time of writing, this is the only JavaScript on the site, and it's only on one page, Toggling browser elements without JavaScript.

Build

This is a statically-generated site; it does not run any code on the server, though it does come with some server-side configuration.

  1. The third-party assets are specified with Nix, using a Nixpkgs overlay.
  2. Shake is configured to build the assets with Nix, and then copy the relevant files to a specified directory.
  3. Eleventy copies static files from there, as well as other locations.
  4. Eleventy builds the content on demand.
    1. The HTML templates use Liquid, mostly trivially, except when listing posts.
    2. Eleventy is configured to use Remark (rather than the default of markdown-it) to compile Markdown.
    3. There's a couple of extra Remark plugins to handle features such as footnotes.
    4. Remark uses KaTeX to compile LaTeX mathematical expressions into something readable.
    5. I've added support for some custom shortcodes.
    6. CSS is compiled with PostCSS. (The original version of this article stated that it was not compiled, but this has changed since.)
      1. Imports are inlined for performance, so the browser only needs to load one file.
      2. Nested CSS rules are flattened, as they are not always fully supported.
    7. HTML is piped through Prettier to make sure the output is human-readable, because I care about that.
  5. I have some scripts set up with Just which I use for development.
  6. To "productionize" the output, I add two things for each output file:
    1. a file containing a BLAKE3 checksum ("b3sum"), and
    2. a Zstandard-compressed version of the file (for text-based data such as HTML and CSS).
  7. The productionized output can be built with Shake, Eleventy and running the productionize.nu script, but more importantly, you can also build it with Nix using nix-build.

Version control

This repository is hosted on Codeberg as ooble/self.

Hardware

This site runs on a Raspberry Pi 5 which sits on my desk, and is connected to the Internet via my home connection. It seems to be pretty reliable most of the time.

The Raspberry Pi is easily performant enough, but has some downsides. It runs a custom variant of Debian and other Linux distros have little to no support for it, which means I couldn't install NixOS on it easily, and I had issues attaching an NVMe hard drive. If I were to replace it, I would probably shop around for another computer with a very small form factor. (Surprisingly, I've had no issues with the Aarch64/ARM64 chip.)

Deployment

Deployment consists of pushing to Codeberg, then SSHing into my server and running the deploy self command with the current revision hash.

That script runs:

nix-build --out-link /data/static/self "https://codeberg.org/ooble/self/archive/${VERSION}.tar.gz"

This asks Nix to download the source code for the specified revision and build it according to the default.nix file it finds there, which produces a content-addressed directory in the Nix store containing the site's data and configuration.

The command also asks Nix to symlink the built directory to somewhere we know, in this case, /data/static/self.

It then reloads the web server.

Serving

The server runs Caddy, a very powerful web server that I've found a joy to use, in a Docker container.

The /data/static directory, as well as /nix (where the Nix store lives), are mounted into this container.

Caddy loads a configuration file which sets the path to the site's files in a variable, then loads the website's Caddy configuration. This file contains the rest of the configuration:

Caddy handles TLS itself by automatically acquiring and renewing 90-day certificates from Let's Encrypt.

HTTP server logs are stored on the server, and I mostly ignore them. There is no client-side tracking.

Viewing

You're doing it!

If you made it this far, thank you for reading. I hope you found some tools and ideas that resonate with you.


If you enjoyed this post, you can subscribe to this blog using Atom.

Maybe you have something to say. You can email me or toot at me. I love feedback. I also love gigantic compliments, so please send those too.

Please feel free to share this on any and all good social networks.

This article is licensed under the Creative Commons Attribution 4.0 International Public License (CC-BY-4.0).