Add some more content to Nix Blog post

This commit is contained in:
Danila Fedorin 2022-04-09 15:35:52 -07:00
parent 20be96253c
commit e778b8710d

View File

@ -61,7 +61,7 @@ me use flakes? Well, two things:
contains the hashes of the Git-based dependencies of a flake, and thus prevents builds from
accidentally pulling in something else. However, unlike my approach, which relies on custom
scripts and extra tools such as `jq`, the locking mechanism used by flakes is provided with
standard Nix tooling. Using Flakes also guarantees that my build process won't break with
standard Nix tooling. Using flakes also guarantees that my build process won't break with
updates to Hugo or Ruby, since the `nixpkgs` version is stored in `flake.lock`, too.
### The Final Result
@ -218,6 +218,60 @@ to configure the challenge path to be writeable. Click the `module.nix` link abo
to check out the full file.
#### Creating a Flake
We now have two "things" that handle the deployment of the blog:
the builder functions `english` and `russian` which help describe various
blog versions, and the NixOS module that configures the server's Nginx to
serve said versions. We now want to expose these to the NixOS system configuration,
which describes the entire server. I decided to do this using a flake.
[Yanik Sander](https://blog.ysndr.de/posts/internals/2021-01-01-flake-ification/index.html) wrote up
a pretty comprehensive explanation of how their blog is deployed using flakes, which I often consulted
while getting started -- check it out if you are looking for more details.
In brief, a Nix flake has _inputs_ and _outputs_. Inputs can be other flakes or source files that
the flake needs access to, and outputs are simply Nix expressions that the flake provides.
The nice thing about flakes' inputs is that they can reference other flakes via Git. This means
that, should I write a flake for my blog (as I am about to do) I will be able to reference its git URL
in another flake, and Nix will automatically clone and import it. This helps provide the __adding custom packages__
goal, since I can now easily write Nix expressions and reference them from my system configuration.
Importantly, flakes track the versions of their inputs in a `flake.lock` file; this means that, unless explicitly told to do otherwise,
they will use the same version of their inputs. This achieves the __versioning__ goal for my blog, too, since
now it will pull the pre-defined commit from Git until I tell it to fetch the updated site.
In addition to pinning the version of my blog, though, the flake also locks down the version of `nixpkgs` itself.
This means that the same packages will be used in the build process, instead of those found on the host
system at the time. This has the nice effect of preventing updates to dependencies from breaking the build;
it's a nice step towards purity and reproducibility.
Let's take a look at the inputs of my blog flake:
{{< codelines "Nix" "blog-static-flake/flake.nix" 2 19 >}}
Two of these inputs are my blog source code, pulled from its usual Git host. They are marked as
`flake = false` (my blog is just a Hugo project!), and both require submodules to be fetched. One
of them is set to the `localization` branch, once again because localization is not yet stabled
and thus not merged into my blog's `master` branch. The other three inputs are flakes, one of
which is just `nixpkgs`. The `flake-utils` flake provides some convenient functions for writing other
flakes, and `katex-html` is my own creation, a KaTeX-to-HTML conversion script that I use to post-process the blog.
So what outputs should this flake provide? Well, we've already defined a NixOS module for the blog, and we'd like
our flake to expose this module to the world. This is the exact purpose of the `outputs.nixosModule` attribute.
It's sufficient to simply import the module file:
{{< codelines "Nix" "blog-static-flake/flake.nix" 28 28 >}}
This is great, but it's not enough. Specifically, the module configuration requires a list of
packages created using our builders. But how should the NixOS configuration even reference these builders?
There's no "standard" way for exposing a pure function from a flake (as far as I know), but the good news is that
if you add a non-standard attribute to the flake, it will be accessible from wherever it is imported.
Thus, I simply provide a `buildersFor` function:
{{< codelines "Nix" "blog-static-flake/flake.nix" 23 27 >}}
The `nixpkgs` flake requires a `system` argument, which means that the builders themselves
(which depend on packages from `nixpkgs`) need to be aware of what system they're being used for.
This is why `buildersFor` is itself a function.
{{< todo >}} This needs to be done {{< /todo >}}
#### Using the Module