• 0 Posts
  • 3 Comments
Joined 1 year ago
cake
Cake day: June 4th, 2025

help-circle


  • I’ve been using NixOS for years now (the 1st commit is from 2020). The benefits I particularly enjoy:

    • mostly-atomic updates and rollbacks
    • versioned configuration, with history in Git
    • uniformity of configuration across machines - my allowed SSH pubkeys are in NixOS config, so I only have one source-of-truth to update if I want to add or revoke one (and then rebuild every machine, of course (maybe I should invent an automated provisioning/deploy system)).
    • (advanced, but not complex) composable configuration - NixOS has modules.
      • I enable my user and Wireguard in every machine, along with the Prometheus host exporter
      • I enable more Prometheus exporters in servers - nginx, and whatnot.
    • (advanced, complex) programmable config
    • (advanced) overlays - easily change your OS

    If a software update goes south, just reboot into the last known good one, until you have time to figure out what broke. This only applies to OS config, it doesn’t apply to data, so if you need to migrate your Postgres to a new on-disk format, or such, you still need a snapshot or backup of some sort.

    It’s very easy to keep config in Git - I’m aware of etckeeper, but NixOS treats your Git repo as the primary source of truth, not a tacked-on addition.

    It’s possible to write parametric configurations, to loop over machines, etc. For example, here’s how I import the module that enables and unfirewalls Prometheus exporters, in one particular machine:

    (import ../modules/wireguard-prometheus-exporters.nix { exporters = [ "knot" "nginx" "nginxlog" "node" "postgres" "redis" "systemd" "wireguard" ]; })  
    

    Other machines don’t have knot or redis, so I just omit them from the list.
    Here’s a simplified snippet of the implementation:

    { exporters, }:  # this is a lambda taking a parameter, the list of Prometheus exporters per host  
    { config, lib, ... }:  
    {  
          services.prometheus.exporters = lib.genAttrs exporters (  
          exporter: { enable = true; }  
          # ... etc. There's more stuff here, but this is the gist.  
    }  
    

    This thing above produces approximately this NixOS config:

    services.prometheus.exporters.knot = { enable = true; };  
    services.prometheus.exporters.nginx = { enable = true; };  
    services.prometheus.exporters.nginxlog = { enable = true; };  
    # ... etc  
    

    Edit: I forgot about overlays. You can patch software, or switch to forks, much more easily with NixOS. For example, here I’m applying some mods to my laptop:

      nixpkgs.overlays = [  
        (import ../overlays/wlvncc-overlay.nix) # add clipboard support  
      ];  
    

    and here’s its definition - nothing could be simpler.

    final: prev: {  
      wlvncc = prev.wlvncc.overrideAttrs (old: {  
        patches = (old.patches or [ ]) ++ [ ./wlvncc-clipboard-sync.patch ];  
      });  
    }  
    

    The patch itself is generated by git diff in the source of wlvncc. Alternatively, I could have switched to a fork, here’s how: https://wiki.nixos.org/wiki/Overlays#Overriding_a_version