Edit and public Nix Blog article
This commit is contained in:
parent
fe1c05fe46
commit
6145d9e804
|
@ -1,7 +1,6 @@
|
|||
---
|
||||
title: "Declaratively Deploying Multiple Blog Versions with NixOS and Flakes"
|
||||
date: 2022-04-10T00:24:58-07:00
|
||||
draft: true
|
||||
tags: ["Hugo", "Nix"]
|
||||
---
|
||||
|
||||
|
@ -40,21 +39,21 @@ I wanted to be able to represent all of this complexity in my NixOS configuratio
|
|||
that's what this post is about!
|
||||
|
||||
### Why Flakes
|
||||
This article is about using Nix flakes to manage my configuration. But what is it that made
|
||||
me use flakes? Well, two things:
|
||||
I decided to use Nix flakes to manage my configuration. But what is it that made
|
||||
me do so? Well, two things:
|
||||
|
||||
* __Adding custom packages__. The Nix code for my blog provides a package / derivation for each
|
||||
version of my website, and I want to use these packages in my `configuration.nix` so that
|
||||
I can point various Nginx virtual hosts to each of them. This is typically done using
|
||||
version of my website, and I want to use these packages in my `configuration.nix`. Adding
|
||||
custom packages is typically done using
|
||||
overlays; however, how should my system configuration get my overlay Nix expression? I would
|
||||
like to be able to separate my build-the-blog code from my describe-the-server code, and
|
||||
so I need a clean way to let my system access the former from the latter.
|
||||
flakes solve this issue by letting me specify a blog flake, and pull it in as one
|
||||
of the inputs.
|
||||
* __Versioning__. My process for deploying new versions of the site prior to flakes boiled down to fethcing
|
||||
Flakes solve this issue by letting me specify a blog flake, and pull it in as one
|
||||
of the system configuration's inputs.
|
||||
* __Versioning__. My process for deploying new versions of the site prior to flakes boiled down to fetching
|
||||
the latest commit from the `master` branch of my blog repository, and updating the `default.nix`
|
||||
file with that commit. This way, I could reliably fetch the version of my site that
|
||||
I want published. Flakes do the same thing: the `flake.lock` file
|
||||
file with the corresponding hash. This way, I could reliably fetch the version of my site that
|
||||
I wanted published. Flakes do the same thing: the `flake.lock` file
|
||||
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
|
||||
|
@ -71,7 +70,7 @@ it's very clear from the configuration what I want from my server:
|
|||
three virtual hosts, one with HTTPS, one with drafts, and one with drafts and
|
||||
_in Russian_. Second, there's plenty of code reuse. I'm using two builder functions,
|
||||
`english` and `russian`, but under the hood, the exact same code is being
|
||||
used to run Hugo and all the necessary post-processing. Finally, all of this can be
|
||||
used to run Hugo and perform all the necessary post-processing. Finally, all of this can be
|
||||
used pretty much immediately given my blog flake, which reduces the amount of glue
|
||||
code I have to write.
|
||||
|
||||
|
@ -90,7 +89,7 @@ There are a few things here:
|
|||
* On line 7, the settings `src`, `ssl`, and `host` are inherited into the derivation.
|
||||
The `src` setting provides a handle on the source code of the blog. I haven't had
|
||||
much time to test and fine-tune the changes enabling multi-language support on the site,
|
||||
so they reside on a separate branch. It's up to the caller to provide which version of the
|
||||
so they reside on a separate branch. It's up to the caller to specify which version of the
|
||||
source code should be used for building. The `host` and `ssl` settings are interesting
|
||||
because __they don't actually matter for the derivation itself__ -- they just aren't used
|
||||
in the builder. However, attributes given to a derivation are accessible from "outside",
|
||||
|
@ -98,15 +97,15 @@ There are a few things here:
|
|||
* Lines 10 through 14 deal with setting the base URL of the site. Hugo
|
||||
does not know how to interpret
|
||||
the `--baseURL` option when a blog has multiple languages. What this means is that in the end,
|
||||
it is impossible to configure the base URL used in links from the command line,
|
||||
and I need to apply some manual changes to the configuration file. I need to be able to adjust
|
||||
the base URL becasue each version of my website is hosted in a different place: the default (english)
|
||||
it is impossible to configure the base URL used in links from the command line.
|
||||
I need to apply some manual changes to the configuration file. It's necessary to adjust
|
||||
the base URL because each version of my website is hosted in a different place: the default (English)
|
||||
website is hosted on `danilafe.com`, the version with drafts on `drafts.danilafe.com`, and so on.
|
||||
However, the configuration file only knows one base URL per language, and so it _doesn't_ know
|
||||
when or when not to use the `drafts.` prefix. The `urlSub` variable is used in the builder.
|
||||
* On line 15, the `publicPath` variable is set; while single-language Hugo puts all the generated
|
||||
HTML into the `public` folder, the multi-language configuration places it into `public/[language-code]`.
|
||||
Thus, depending on the configuration, the builer needs to look in a different place for final output.
|
||||
Thus, depending on the configuration, the builder needs to look in a different place for final output.
|
||||
|
||||
This new `website` function is general enough to represent all my blog versions, but it's too low-level.
|
||||
Do I really want to specify the `publicPath` each time I want to describe a version of the site?
|
||||
|
@ -161,7 +160,7 @@ is the same as `replaceUrl.to` (since I'd want the Nginx virtual host for a blog
|
|||
version to handle links within that version). The `ssl` ghost parameter corresponds
|
||||
precisely to whether or not a virtual host will need SSL (and thus ACME, and thus
|
||||
the `systemd` setting). For each derivation built using `website`, I can access
|
||||
the attributes like `ssl` or `host` to generate the corresponding piece of the Nginx configuation.
|
||||
the attributes like `ssl` or `host` to generate the corresponding piece of the Nginx configuration.
|
||||
|
||||
To make this _really_ nice, I wanted all of this to be "just another section of my
|
||||
configuration file". That is, I wanted to control my site deployment via regular
|
||||
|
@ -220,7 +219,7 @@ 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.
|
||||
which describes the entire server. This is where flakes finally come in.
|
||||
[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.
|
||||
|
@ -263,8 +262,8 @@ The flake `output` schema provides a standard option for exposing modules, `nixo
|
|||
exposing my `module.nix` file from the flake is simply a matter of importing it, as on line 31.
|
||||
There is, however, no standard way for exposing a _function_. The good news is that any
|
||||
attribute defined on a flake is accessible from code that imports that flake. Thus, I simply
|
||||
added a `buildersFor` function, which, given an operating system, fetches the `nixpkgs` collection
|
||||
and LaTeX builder script for that system, and feeds them to the file that defines the `english`
|
||||
added a `buildersFor` function, which fetches the `nixpkgs` collection
|
||||
and LaTeX builder script for a given system, and feeds them to the file that defines the `english`
|
||||
and `russian` builders. This `buildersFor` function also provides the builders with the two
|
||||
different blog sources they reference, `blog-source` and `blog-source-localized`.
|
||||
|
||||
|
@ -276,7 +275,7 @@ Finally, the last little bit on lines 32 through 34 defines a default package fo
|
|||
is the package that is built if a user runs `nix build .#`. This isn't strictly necessary for my purposes,
|
||||
but it's nice to be able to test that the builders still work by running a test build. The
|
||||
`eachDefaultSystem` function generates a `defaultPackage` attribute for each of the "default"
|
||||
operating systems, so that the package is buildable on more than just my server architecture.
|
||||
systems, so that the package is buildable on more than just my server architecture.
|
||||
|
||||
And that's it for the blog flake! I simply push it to Git, and move on to actually _using_ it from elsewhere.
|
||||
|
||||
|
@ -293,12 +292,12 @@ this can be done using the `specialArgs` attribute. The whole `flake.nix` file i
|
|||
|
||||
{{< codeblock "Nix" "server-config/flake.nix" >}}
|
||||
|
||||
Finally, in `configuration.nix`, taking `builders` as one of the inputs, I finally write what you saw above:
|
||||
Finally, in `configuration.nix`, taking `builders` as one of the inputs, I write what you saw above:
|
||||
|
||||
{{< codelines "Nix" "server-config/configuration.nix" 42 59 >}}
|
||||
|
||||
### Wrapping Up
|
||||
So there you have it, a flake-based blog deployment written in a declarative style. You can
|
||||
So there you have it, a flake-based multi-version blog deployment written in a declarative style. You can
|
||||
check out both my [system configuration flake](https://dev.danilafe.com/Nix-Configs/server-config)
|
||||
and my [blog flake](https://dev.danilafe.com/Nix-Configs/blog-static-flake) on my Git server.
|
||||
If you want more, check out the articles by Xe and Yannik linked above. Thanks for reading!
|
||||
|
|
Loading…
Reference in New Issue
Block a user