#+TITLE: Nix Selfhosting in the Age of LLMs #+DESCRIPTION: About me * My usecase I recently had to redo my homelab hosting suite. I run everything off a Raspberry Pi 4 8GB, and lately, it has been hardly chugging along. I don't know if it was system rot or just a buildup of dust, but my home run services were becoming a bit slow. I wanted to run maintenence on it, but I was sort of afraid to touch anything from what I built. I based all my work on Helm charts to be deployed on Kubernetes (k3s to be exact). I reasoned it was the cutting edge way to do so with high security, and that Helm made everything declarative. At least, so I thought. Yes, it is already better than deploying everything straight from chart files, this much is certain. However, the system would still get stuck mid-deployment, previous configuration options wouldn't always go away, services needed to be manually deleted. It always felt like a great beast I was trying to wrestle into submission, which is not how I want to feel about a service backing up pictures of my children. * Starting the migration It was time for a change. I wanted to restart my homelab and make it something very maintainable. This drove me to use two technologies that were new to me since my last attempt at self hosting: - _The NIX ecosystem_: I migrated my own laptop to NixOS over a year ago at this point. I migrated my work setup to Nix and now almost all of my projects use Nix to manage dependencies, builds and deployments. Now, I had an opportunity to manage my homelab using NixOS and declare everything. - _LLMs and Agentic Co-Programming_: A lot of the work I did in the past involved painstaking port definitions and reverse-proxy configurations. There was no reason to think this time would be different in this regard, but knowing I could partially rely on some form of coding agent made the process significantly less daunting. * Quick success story I started to make a migration plan - I wanted to keep relevant data from my old homelab and migrate it into my new. Within a day I had backups ready to be ported. Within two more days I had my initial services running, with some bugs. Took another day to iron it all out (keep in mind, my time spent working on this project was 10PM to 11PM only, so I was making very quick progress). Sure enough it all worked, backing up all my files and running my little suite of automations. It was working faster than ever before, and I felt more in control than ever, even though I delegated 50% of the coding work to a machine. * Why NIX is so good, even on its own ** Fully declarative The state of my homelab is set directly from my project. With the exception of some service specific settings that can't be set from files, everything can be changed by changing a file in the repo, and everything can be inferred from reading the repo itself. This means I am never in the dark about the state of my homelab, I can just see what should be running. ** Saving tools and commands Something I find myself doing for every one of my Nix projects is declaring a development shell with special commands for tooling. Every time I encounter myself writing long commands to do specific tasks (checking state of backups remotely, remote build and deploy, running commands inside podman hosted services), I just write a custom command that gets loaded into the shell. In the previous version, this was accomplished by writing a bunch of bash files. This does work and acheives the same thing, but this feels more approachable, and the commands feel more accessible. I find myself using this tool much more within the NIX ecosystem. * The extra benefit of the LLM Of course using an agentic coding agent helps with selfhosted and automating tasks. This is true also for a kubernetes based helm-charted repo like my previous setup. But there ARE some DEFINITE benefits of using this specific combination. For starters, the fact that it is fully declarative means the LLM has direct access to information about the state of the homelab. It doesn't have to hunt around and search for active processes - it knows the file layout and can infer immediately which services are running and how they are configured. Compare this to bloating your context by first reading a bunch of YAML files in the repo and then running a bunch fo commands to make sure everything exists in the repo and making sure it matches the YAML. For the rest, it has ready access to custom tools and commands that are useful for debugging and commanding the system. I create them because they are useful to me, and they are sure useful for the LLM as well. * How this looks in practice I dunno check later