Set up a Zola blog using WSL and nix flakes
I've always enjoyed writing and sharing what I've learned. As I've gotten older I've also come to appreciate just how much one forgets in their life, and the importance of writing things down for your future self. I've scratched my writing itch at work, writing up design proposals or guides to get things done, but haven't done anything publicly in a long time. Today, I'm fixing that, and I'm going to write down how.
Static site generators
I remember hearing about jekyll way back when, and had a vague idea of what it did, but never used it. Instead I would clicky-click through menus on my cheap hosting provider to deploy WordPress sites and write there. Years later my role involved writing up technical blog posts, which we did using Hakyll -- a static site generator written in Haskell. It was then that I got to understand the joy and simplicity of a statically generated site.
Fast forward to today, and there are a huge range of static site generators to choose from. There are entire sites and github repos dedicated to listing them all. To get my personal blog started, I first needed to choose a generator. Without going into too much detail, I poked around a few lists while building some rough selection criteria in my head. My criteria were something like:
- Simple to use.
- Easy to find a selection of decent themes.
- Big enough that it's well documented and supported.
- Can use it cross platform.
- Ideally a single binary that does it all.
- Written in a language I like or am interested in.
That last criteria isn't a big deal, but it's nice to be able to rummage around in the code and/or fix bugs if you need to, and I'm more inclined to do that if I have positive feelings towards the language.
After my poking around, I initially tried Cobalt. However, I made the mistake of trying to get it setup at night when I was tired. I can't remember the specific bumps, but I think it was the lack of themes and documenation that made me feel like things were harder than they needed to be. Given my impatience to get a dopamine hit and put something on the web, I decided to try something with better support. Hugo looks very well supported, but I found some grumblings about its templates and am a little skeptical of Go as a language. I also got the impression that it was more complicated than I needed it to be. That said, it might be the next thing I try if I feel the need to switch. Finally, I came across Zola, which seems to tick my boxes and suit my needs. So here we are, giving it a go.
WSL
I've been a NixOS user since about 2017, however my personal laptop doesn't work with my nice new dual monitor setup. As a result, I thought I'd have a crack getting Nix to run on my gaming PC running Windows 11. However, given I wanted to write and deploy my blog from any of my machines, I couldn't got past using Nix flakes to setup a developer shell. Flakes give us easy to use and repeatable developer environments, and now that I'm comfortable with them I find them hard to give up. One little problem: Nix doesn't work on Windows.
Thankfully, there's WSL. WSL, or Windows Subsystem for Linux, allows users to run a Linux distro that's hosted by Windows. There's a config somewhere to run NixOS on WSL, but I've been curious to try out Nix from other Linux distributions, so went with the default Ubuntu on WSL and installed Nix on top of it. Following all the standard instructions to install WSL and then Nix worked without any issues or quirks and I was off to the races.
A flake for blogs
To get a pinned version of Zola installed that would be the same everywhere I worked, I setup a quick flake. Despite some boilerplate, there's very little to it. It takes a nixpkgs as an input, and then outputs a developer shell that contains zola. Some of the boilerplate that deals with handling different systems could be done away with given I'm unlikely to run this on more than one system, but I'm used to working in dev teams with macOS running on different types of silicone, so it was no hassle. It also means anyone who wants to use this setup should get going without any extra work.
{
description = "Dev environment for blog";
inputs.nixpkgs.url = "nixpkgs";
outputs = {self, nixpkgs}:
let
supportedSystems = [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ];
# Run a function that takes nixpkgs for a specific system
forEachSupportedSystem = f:
nixpkgs.lib.genAttrs supportedSystems (
system:
f {
pkgs = import nixpkgs {
inherit system;
};
}
);
in
{
# Add the current system's nixpkgs as an output so we can interrogate it
# in a repl.
#
# ```shell
# nix repl
# :lf .
# blogPkgs.x86_64-linux.foo.version
# ```
blogPkgs = forEachSupportedSystem (
{pkgs}: pkgs
);
devShells = forEachSupportedSystem (
{pkgs}:
{
default = pkgs.mkShellNoCC {
packages = [
pkgs.zola
pkgs.rclone
];
};
}
);
};
}
The only snag I hit here was that flakes are still considered an experimental
feature that users must opt into. To do that, I just had to create
~/.config/nix/nix.conf and add experimental-features = nix-command flakes
to the file. Once that was done and I started a new shell, I could do flakey
things and use the nix command. That meant I could now run nix develop to
enter a development environment that had Zola available and start building
this very blog.