Compare commits
2 Commits
d601a28f5c
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| f9478b133f | |||
| 009cb0d31f |
@@ -8,7 +8,7 @@ categories: [
|
|||||||
meta
|
meta
|
||||||
]
|
]
|
||||||
created: 2026-03-21T11:29:19+00:00
|
created: 2026-03-21T11:29:19+00:00
|
||||||
updated: 2026-03-21T11:31:37+0100
|
updated: 2026-03-23T20:55:01+0100
|
||||||
draft: false
|
draft: false
|
||||||
layout: home
|
layout: home
|
||||||
version: 1.1.1
|
version: 1.1.1
|
||||||
@@ -21,4 +21,4 @@ version: 1.1.1
|
|||||||
|
|
||||||
If you can read this, server02 hasn't crashed (yet) :)
|
If you can read this, server02 hasn't crashed (yet) :)
|
||||||
|
|
||||||
test for webhook
|
Email always open: admin@voidarc.co.uk (if my mailserver is up, which is sometimes)
|
||||||
|
|||||||
167
posts/nix.norg
Normal file
167
posts/nix.norg
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
@document.meta
|
||||||
|
title: Why Nixos is the Coolest Operating System
|
||||||
|
description: I really like Nix
|
||||||
|
authors: [
|
||||||
|
Adumh00man
|
||||||
|
]
|
||||||
|
categories: [
|
||||||
|
linux
|
||||||
|
blog
|
||||||
|
nix
|
||||||
|
]
|
||||||
|
created: 2026-03-22T19:35:56+00:00
|
||||||
|
updated: 2026-03-22T19:43:25+0100
|
||||||
|
draft: false
|
||||||
|
layout: post
|
||||||
|
version: 1.1.1
|
||||||
|
@end
|
||||||
|
|
||||||
|
* The Nixos Philosophy
|
||||||
|
Nix is the all in one solution to every problem you could have with Linux. It prides itself on being a fully declarative way to install
|
||||||
|
and manage system packages, and It (mostly) achieves those goals. Before trying to involve oneself in such matters, though, an important
|
||||||
|
distinction to make is that Nix as a concept, and a package manager, is seperate from Nixos as a system. Nix can, and should, in some
|
||||||
|
cases, exist outside of Nixos. But, let's get onto that later.
|
||||||
|
|
||||||
|
** Origins
|
||||||
|
If you wanted a full rundown on how nix came about, then you're in the wrong place. Go read wikipedia or something. The main thing that
|
||||||
|
you need to know is that the nix language, and therefore the packaging system, was made on a whim for a university dissertation. First
|
||||||
|
of all, that's pretty insane. Making an entire programming language for the sake of it, and I wouldn't even be surprised if he didn't
|
||||||
|
get full credit. It quickly caught the attention of all the linux nerds out there, and before long it had evolved into the nix project
|
||||||
|
that we know and love today.
|
||||||
|
|
||||||
|
** Reasoning and Methodology
|
||||||
|
The main draw of nix as a concept is it's reproducability. It works similarly, and often in tandem with, Git. The git working tree is a
|
||||||
|
simple concept. A long ledger of changes (more commonly called diffs), that when put together results in a full codebase. Nix uses this
|
||||||
|
principle to its advantage, and I will demonstrate this by comparing nixpkgs with another common package repo, the AUR.
|
||||||
|
|
||||||
|
*** The AUR
|
||||||
|
The AUR is the Arch User Repository, a gigantic collection of packages uploaded by anyone that can be asked to figure out how PKGBUILDS
|
||||||
|
work. PKGBUILDS are a form of makefile, that is used as a standard way of declaring dependancies, versions wherein, and how to build
|
||||||
|
a given app. These PKGBUILDS are stored within the repos they are associated with, and are therefore versioned alongside the app.
|
||||||
|
When you upload an app to the AUR, and it is approved, a static version of your app, ie one commit, is hosted on the aur domain. This
|
||||||
|
url is read only, and cannot be viewed like something hosted on github. To install the app, you clone the repo and use `makepkg -si` to
|
||||||
|
compile.
|
||||||
|
|
||||||
|
The key part of all of that is that only one commit is hosted at a time. Because arch is a "rolling release" distro, they
|
||||||
|
see no need to waste storage on older versions of apps. This is an issue, when there is a breaking change and you cannot roll back
|
||||||
|
to an older version of a package, because it no longer exists. This is remedied slightly by the pacman cache, but that only goes for
|
||||||
|
your local machine. If you need a specific version of an app, then either compile from source or give up.
|
||||||
|
|
||||||
|
But, I hear you ask, what happened to git versioning? Can't you just roll back to an older commit and use the PKGBUILD from there?
|
||||||
|
This, my friend, is where Nix comes in.
|
||||||
|
|
||||||
|
*** Nixpkgs
|
||||||
|
Nixpkgs is, without exxageration, a git repository. Every time you install a package, the entire repo is pulled to your local machine.
|
||||||
|
Despite the fact that, at the time of writing, it has over 200,000 packages, it is still small enough, because of how diffs work, to
|
||||||
|
be downloaded every time you need to update an app. The reason for this is that it leverages git histories to their maximum potential.
|
||||||
|
|
||||||
|
Git, as I said, is just a long ledger of changes. All diffs are stored in the .git folder, along with some other stuff that might be
|
||||||
|
important to someone someday. Every time you make a commit, a new hash is generated. It isn't important how the hash is generated,
|
||||||
|
just that every commit has a unique hash associated with it. This gives rise to revisions. With this hash, you can address a specific
|
||||||
|
state of the ecode at that commit, and this is what nix uses to stay so small.
|
||||||
|
|
||||||
|
Every package has a .nix file, that details its build process. This can be as simple as compiling one file to a binary, all the
|
||||||
|
way up to compiling the whole linux kernel. Nix in of itself is a wrapper for every other build system, which means that any app
|
||||||
|
that can be built can be run on nix. Hence, when enough apps are compiled, nixpkgs becomes completely self sufficient. For an app
|
||||||
|
to be built with nix, all of its dependancies, and the builder itself, must also be built with nix. This means that, instead of using
|
||||||
|
a manner of different build systems, and rolling release nonsense, that means that you can never be sure if you're getting the same
|
||||||
|
version of a dependancy an app was developed with, you simply call another nix file, at a specific rev, or commit.
|
||||||
|
|
||||||
|
This leads to what is known as a dependancy chain. Because you call every dependancy with a specific rev, you can make sure that you
|
||||||
|
are getting the right version. When you get down to the actual source code, that isn't nix, you download the specified rev of the third
|
||||||
|
party repo, and compile that. If an app compiles once, it will always compile, because the git ledger should never be changed manually.
|
||||||
|
|
||||||
|
** In practice
|
||||||
|
Due to the existence of flakes, something that I'll get to later, this is made much easier. No more "it works on my machine", because,
|
||||||
|
for all intents and purposes, all machines are identical when running nix. There are no outside dependancies, so there is no way
|
||||||
|
for an app to fail to compile. Nix as a package manager can be used on other systems, being monolithically configured with one file,
|
||||||
|
that can be shared and rebuilt on any other machine with (almost) exactly the same functionality.
|
||||||
|
|
||||||
|
Hang on, this sounds awfully familiar. Like a problem that system integrators have been trying to solve for years, but could only come
|
||||||
|
so close. And so, the quest for a system built with Nix began.
|
||||||
|
|
||||||
|
** Nixos, the coolest operating system
|
||||||
|
Nixos is what came of that endeavour. A system fully defined by code. A system that could be rebuilt over and over, with exactly the
|
||||||
|
same result, on multiple machines. This had the added benefit of the same git methodology that nixpkgs was based on. No more updates
|
||||||
|
that rendered your computer unusable! You could simply revert back to a previous revision of your system, using the same diff structure
|
||||||
|
that git uses, but with boot entries and packages instead of just code.
|
||||||
|
|
||||||
|
Nixos is the pinnacle of stability. By definition, there can't be a more stable system. By virtue of the fact that It can be rolled back,
|
||||||
|
it cannot be defeated in that regard. It is impossible to have conflicting packages, because, in theory, all packages can be installed
|
||||||
|
alongside eachother. If you want to install 50 different versions of the linux kernel at once, then go ahead! If you want to run 10
|
||||||
|
different versions of firefox on the same machine, there's nothing stopping you! You get all of the benefits of rolling release, while
|
||||||
|
also having the option of installing a 5 year old version of onlyoffice in the same breath.
|
||||||
|
|
||||||
|
And the best part? Your system config, in of itself, can be controlled by git! It's git all the way down! I can instantly have the same
|
||||||
|
system I did 6 months ago if I wanted to, the only difference being the user files, of course. Ah, the user files.
|
||||||
|
|
||||||
|
** Home Manager: An attempt was made
|
||||||
|
Home manager is the logical extension of Nixos. A way to control dotfiles, or really any file, through nix. Revisions, versioning, etc.
|
||||||
|
It seems like a good idea on paper, until you try to use it.
|
||||||
|
|
||||||
|
First of all, the way that home manager works is exactly the same as the nix store. It creates a load of read only folders, and then
|
||||||
|
generates the immutable config files within. Seems reasonable, why would you want to change them in the first place? Two words: Lock
|
||||||
|
File. Nvim is the main culprit when it comes to issues like this. The Lazy.lock file can't update, because presumably the entire
|
||||||
|
`.config/nvim` folder was created by home-manager, meaning that updating packages is nearly impossible. All home manager leads to is a
|
||||||
|
massive headache at the end of the day. Especially when you come across some unsupported app, where you have to paste in the non-nix
|
||||||
|
config so that home-manager can copy and paste it into a read only file somewhere else in your home directory.
|
||||||
|
|
||||||
|
Because of these issues, I have taken a different approach, which I will now go on a tangent about.
|
||||||
|
|
||||||
|
** The Better way to manage dotfiles
|
||||||
|
Stow is an old GNU utility. It calls itself a "symlink farm", which is fancy speak for "it takes files in a directory and links them to
|
||||||
|
another place". The idea is that you have a folder with all of your dotfiles in, the ones that you actually care about, and stow links
|
||||||
|
them to your actual .config directory. I used this for a while, in order to manage my hyprland and nvim configs more nicely.
|
||||||
|
|
||||||
|
Due to the fact it's a GNU utility, however, it's really old. And doesn't have nice features. It was never intended to be a dotfiles
|
||||||
|
manager, so didn't have the killer feature that I would need to make a proper nix config. Multiple host support.
|
||||||
|
|
||||||
|
I have 2 machines that I have nix on. My laptop and my desktop. I want a similar experience between the two, but some things I want to be
|
||||||
|
different. Nixos thought of this, and made it so that you could have different outputs in a flake, that represented different systems.
|
||||||
|
But what about all my other nonsense? My monitor names are different between the two machines, and I had different keyboard styles, so
|
||||||
|
wanted different modifiers too! This could be remedied by loads of scripts, but that was boring. I needed something new. Something...
|
||||||
|
Intuitive.
|
||||||
|
|
||||||
|
** Doot: The Fast, Intuitive dotfiles manager
|
||||||
|
[Doot]{https://github.com/pol-rivero/doot} is my choice for a dotfiles manager. It's fast(ish), configurable, and, most importantly,
|
||||||
|
was built with multiple hosts in mind. If you want to see how it works more closeley, click the link at the start of this paragraph,
|
||||||
|
or have a look at my [Dotfiles]{https://git.voidarc.co.uk/voidarc/config}, which I think are pretty cool. For those of you that can't be
|
||||||
|
asked to have a look, though, I'll explain the concept as simply as I can be bothered.
|
||||||
|
|
||||||
|
Your doot repo is located in the `.dotfiles` directory, next to .config. When you run `doot install`, the folders in your repo are mapped
|
||||||
|
to your home directory in the same structure as they were in the repo. Eg, if you put a .zshrc in the root of the repo, it will end up
|
||||||
|
in the right place. So far, this is exactly the same as stow, the only difference being where stow would link a whole folder, doot
|
||||||
|
creates the structure in place and only symlinks files.
|
||||||
|
|
||||||
|
Doot can be configured in the doot folder, in the root of the repo, that will not be mapped to the home directory. The doot config
|
||||||
|
contains things like exclude files (like .gitignores and licences), the diff viewer you want to use to see file changes, and your
|
||||||
|
different hosts. Doot manages hosts intelligently, using the hostname of the machine as an indicator. Here is my host config:
|
||||||
|
@code toml
|
||||||
|
[hosts]
|
||||||
|
"HACKSTATION" = "pc-files"
|
||||||
|
"mobile02" = "laptop-files"
|
||||||
|
@end
|
||||||
|
|
||||||
|
The keys on the right correspond to the different hostnames, and the keys on the right correspond to the folders that contain the
|
||||||
|
dotfiles specific to that machine. These folders are located in the root of the repo, and within them, contain another structure
|
||||||
|
that is relative to your home directory. Eg, in the pc-files directory, there is also a `.config` directory, with some specific hyprland
|
||||||
|
configs that only work on my PC.
|
||||||
|
|
||||||
|
** What was I talking about again?
|
||||||
|
You could, of course, version every single file on your disk using this method, but that sounds like a waste of time. There will never
|
||||||
|
be a world where 100% of a system is always generated by nix, because there will always be some random app that only compiles to an
|
||||||
|
appimage and uses proprietary config locations or something. Nevermind how you would manage something like a download folder.
|
||||||
|
|
||||||
|
I believe that Nix, and Nixpkgs, is the gold standard when it comes to software development. There are genuine, real world uses for stuff
|
||||||
|
like this. Sites like replit are fully managed and distributed using nix, because of how stupidly stable it is. You can define whole
|
||||||
|
Kubernetes clusters on nix, and then update them in place with 0 downtime. Pretty impressive. However, as tends to happen with nerds
|
||||||
|
on the internet (me included), the concept and utility that comes along with something like nix is buried under who can make the lightest
|
||||||
|
or best looking config.
|
||||||
|
|
||||||
|
** Moral of the story (or something)
|
||||||
|
Nix isn't for everyone. If you don't care about versioning everything in your entire life, then you're probably better off sticking with
|
||||||
|
something like arch. If you don't mind that you have slightly different configs across different machines, then there's no need for you
|
||||||
|
to learn how to use flakes so that you can make sure that you have identical packages on all of your systems.
|
||||||
|
|
||||||
|
But, It sure is fun to mess around with. If you're on the fence about trying nix, then this is your indicator to switch. It will make
|
||||||
|
you feel a great deal of things, but regret will not be one of those feelings.
|
||||||
Reference in New Issue
Block a user