update hello

This commit is contained in:
Audrey 2025-04-20 15:14:20 -07:00
parent eb251b9980
commit b63106e77b
3 changed files with 127 additions and 7 deletions

View File

@ -12,10 +12,14 @@
path = "index.html";
title = "Home";
head = ''
<meta http-equiv="Refresh" content="0; url='/posts'" />
body.markdown = ''
Webster's dictionary defines "blog" as "a website that contains online personal reflections, comments, and often hyperlinks, videos, and photographs provided by the writer".
This is mine.
You will find mostly longform technical writing here.
<templates-posts-navigation />
'';
body.html = "";
}
];
}

View File

@ -1,3 +1,119 @@
Hello world! This is a test post.
As you know if you're part of my life, I have been going pretty hard on nixing my workstations and servers lately.
This post is to commemorate the creation of this blog being run through nix, but also the workflow I've established to get here.
There will be a real post here soon.
Since the year is 2025 and attention span is in short supply, here's the punchline:
- I ran `nix run .#sunflower.deploy` to update my server, including deploying this blog
- I will run `nix run .#sunflower.deploy.blog-rhelmot-io` to update the blog without updating the system profile
- ...but I can still roll the blog forward and back without rolling the system forward and back, because the blog is its own nix profile!
Let's break it down.
# Part 1: Static Site Generation
What a hotly contentious topic. I could probably stand to care a little bit less, but the caring I do care isn't much.
I started this journey trying to use Jekyll, but quickly found that the Ruby-isms were too much for me.
I did at one point succeed at getting [a flake output which could build a whole Jekyll site](https://git.lain.faith/rhelmot/blog.rhelmot.io/commit/5e24401e67b613c7d81abcec8aed14fdf04a4159), but it was too much of a hack for me to deign to put it upon my domain.
I eventually found [Coricamu](https://github.com/danth/coricamu), which is exactly what I want, though it seems to be abandoned.
It's small enough that I feel comfortable carrying it on my shoulders, so I forked it and did the one small fix necessary to get it to work with current nixpkgs.
I may mess around with theming later, but it provides exactly what I want and not much more.
The source for this blog can be found [here](https://git.lain.faith/rhelmot/blog.rhelmot.io).
Coricamu lets you build a site through a NixOS-style module system.
I constructed my flake.nix such that it runs module evaluation with two modules:
- the `blog.nix` file, defining the site metadata
- a module constructed automatically by slapping each entry of `/posts/*/post.nix` into a post directive
```nix
let
posts = let
listingMap = builtins.readDir ./posts;
listing = builtins.attrNames listingMap;
getPostFile = post: (import ./posts/${post}/post.nix) // { slug = post; };
in builtins.map getPostFile listing;
in
coricamu.lib.generateFlakeOutputs {
outputName = "blog";
modules = [ ./blog.nix { inherit posts; }];
};
```
Then I just write some posts in markdown, put some quick metadata into a .nix file which references the markdown file, and build: `nix build .#blog`.
I can also `nix run .#blog-preview` if I want a fancy server.
Truly, we stand on the shoulders of giants.
# Part 2: Managing Multiple Machines
I have several machines I manage with a [central NixOS configuration repository](https://git.lain.faith/rhelmot/nixos-config) - some workstations and some servers.
This flake.nix also does a directory scan in order to populate its outputs, this time scanning `sites` in order to populate `packages.${buildSystem}.nixosConfigurations.${site}`.
Yes, `nixos-rebuild` will automatically search `packages.${buildSystem}` in order to build a system, allowing for cross compilation.
This fact is particularly useful seeing as I work on [NixBSD](https://github.com/nixos-bsd/nixbsd) and am constantly cross compiling entire systems.
There are various accoutrements in this repository which make it reasonable for me to use it for both NixOS and NixBSD systems, but that's a story for another time.
Now, I can deploy any of these systems with `nixos-rebuild .#$HOST --remote-target $HOST --use-remote-sudo switch`, ideally with `--use-substitutes` since my home internet uplink is dogshit.
There is a problem though - if I want to have my blog as a nix derivation, this means that I have to run a full system rebuild every time I publish a new post.
It is very easy to simply drop the derivation output into the nginx configuration, but suddenly rollbacks are tied together with both the system and blog. Can we do better?
# Part 3: Profiles and Deployment
Yes, we can, with the power of [Nix Profiles](https://nix.dev/manual/nix/2.24/command-ref/files/profiles)!
We won't be linking the typical kind of derivation output you would usually be putting in a user profile, with the system path and applications and such.
Instead, our profile will simply be the static site build output derivation!
I may in the future decide to standardize some sort of "nginx site derivation" layout so I can link non-static sites this way, but for now I just point the root of the site at `/nix/var/nix/profiles/blog-rhelmot-io`, and deploy as follows:
```shell
nix-copy-closure --to $SITE $DRV
ssh $SITE sudo nix-env --set -p /nix/var/nix/profiles/blog-rhelmot-io $DRV
```
This can be automated! Check [deploy.nix](https://git.lain.faith/rhelmot/nixos-config/src/branch/main/deploy.nix) in my NixOS configuration for the final product.
I define a list of deployments, each of which sets a profile name, a site to deploy on, and the package to deploy:
```nix
deployments = builtins.map mkDeploy [
{
profileName = "blog-rhelmot-io";
site = "sunflower";
targetPkg = flakeInputs."blog-rhelmot-io".packages.${platform}.blog;
}
];
```
`mkDeploy` simply templates the previously-mentioned script with these parameters.
We can then combine each script for a given site into a unified deploy script, along with a system profile rebuild for good measure:
```nix
filteredDeployments = builtins.filter (deployment: deployment.site == site) deployments;
targetSystem = flakeInputs.self.packages.${platform}.${site}.system;
deployAll = pkgs.writeShellScriptBin "deploy-all-${site}" (''
set -ex
# TODO take advantage of the nixos-rebuild infrastructure
nix-copy-closure --to ${site} ${targetSystem}
ssh ${site} 'sudo nix-env --set -p /nix/var/nix/profiles/system ${targetSystem} && sudo ${targetSystem}/bin/switch-to-configuration switch'
set +e
'' + lib.concatStringsSep "\n" filteredDeployments);
```
It is annoying that `nixos-rebuild` proper doesn't support this use-case - that is, deploying a pre-built system profile.
I have made the requisite change to enable this behavior in the [NixBSD fork of nixos-rebuild](https://github.com/nixos-bsd/nixbsd/blob/main/modules/installer/tools/nixos-rebuild.sh), but this script is obviously only appropriate for building BSD targets.
Finally, we can deploy just the blog with a sub-attribute, `nix run .#sunflower.deploy.blog-rhelmot-io`:
```nix
filteredDeploymentsAttrs = builtins.listToAttrs (builtins.map (value: { name = value.profileName; inherit value; }) filteredDeployments);
final = deployAll // filteredDeploymentsAttrs;
```
I believe this is the best of both worlds.
# Conclusion
Yippee woo hoo ya ha ha
You too can take control of your systems like this. Go forth and nixify!

View File

@ -1,6 +1,6 @@
{
authors = [ "Audrey Dutcher" ];
datetime = "2025-04-20 03:20-0700";
title = "First post!!1!";
datetime = "2025-04-20 00:00-0700";
title = "Hello Blog - How I streamlined my application management with Nix";
body.markdownFile = ./body.md;
}