One Week of NixOS

Dec 6, 2020 19:40 · 712 words · 4 minute read

Before trying NixOS I had vowed to stop hoping between OS’s and stay with Arch Linux, I’m glad I didn’t. Arch Linux, the AUR, and it’s online documentation are all you need to essentially run any software you can shake a stick at. The reason I’m happy I tried NixOS is because it solves a couple issues I’ve been dealing with on every Linux distro I’ve ever ran.

Things break. Nothing is perfect. Software is far from perfect. But I’ve been seeing a number of blog posts about Nix talking and one phrase that stuck out was describing Nix as being git but for your entire system. This immediately caught my attention as I’ve had to deal with things breaking before but having the ability to instantly rollback sounded like a dream come true. I decided to install and run it and I’ll just lay out how it’s going for anyone else who might be curious on switching.

The Bad

It’s hard to compare documentation after you read Arch Linux’s documentation. NixOS/Nix has quite a bit of documentation and there are Nix Pills but it’s not the same caliber as Arch. That’s not something I expected, Arch has been around a long time, you’ll just have to adjust your expectations on how easy it will be to find the answers you want. The learning curve can be daunting.

Not every single package/library is ported over yet. Some of them have internal issues with the way nix is setup, like py3status. The other issue is some of the programs I use are just compiled binaries which no longer work. But if you check out repology you can see that Nix stable and unstable aren’t very far behind the AUR in terms of number of packages. They’ve made good progress.

The Good

Declarative package management is a no brainer. Every Linux user with more than a handful of servers knows this. But what’s the best one? SaltStack? Ansible? Chef? Vagrant? Terraform? Bash Scripts? CFEngine? Nix allows you to do that right at the package manager level. This was a huge win for me. I’ve tried other methods but I eventually come to a point where it seems like the configuration manager is taking more than it’s giving. Not the case with Nix.

environment.systemPackages = with pkgs; 
let
  my-python-packages = python-packages: with python-packages; [
    pyperclip
    selenium
    i3-py
  ]; 
  python-with-my-packages = python3.withPackages my-python-packages;
in
[
  python-with-my-packages
];

You can install python on your system with the pip packages you want. Lots of my scripts and utilities require packages but it’s usually just 1. I don’t want to set up virtual environments for each one. I could make a requirements file and install with that but that’s just one more thing to deal with, I’d rather the package manager take care of that.

systemd.user.services."minute-cron" = {
  serviceConfig.Type = "oneshot";
  script = ''
    DUNSTIFY=${pkgs.dunst}/bin/dunstify
    "$DUNSTIFY" "hello from your script"
  '';
};

systemd.user.timers."minute-cron-timer" = {
  wantedBy = [ "timers.target" ];
  partOf = [ "minute-cron.service" ];
  timerConfig.OnCalendar = "minutely";
  timerConfig.Unit = "minute-cron.service";
};

Note: These are systemd.user.xxx instead of systemd.xxx which means they are installed to the user. This is important specifically for this example because dunstify won’t be able to send messages if you install them at the global level

Nix will automatically set up systemd services for you. Again not something that was particularly hard to do before but it’s another step that doesn’t have to be remembered when setting things up.

environment.systemPackages = with pkgs; [
  (st.overrideAttrs (oldAttrs: rec {
    patches = [
      # You can specify local patches
      ./path/to/local.diff
    ];
  }))
];

Nix allows you to patch packages you install which is essential for the suckless set of tools since that’s how change your settings.

Conclusion

None of these things I’ve mentioned so far are extremely complicated or unsolved issues. I have workarounds for all these currently. The part that gets me really excited about NixOS is that it’s less lines of code I have to manage once I get things working the way nix expects and it’s a single command. I’ve also had a lot of fun with nix-shell for just trying out quick environments of languages I’m not familiar with. If you aren’t put off by the bad part I’d recommend checking it out.