How and why I use NixOS

It's not very easy to explain what NixOS is, because there are very few similar systems to compare with. I can only sort of compare it with the concept of Terraform, but applied to the operating system itself and not to the "cloud".

NixOS, and home-manager in particular apply the concept of of a purely functional programming language in order to configure all aspects of the operating system, and tie the configuration of individual apps together.

What led me to finally try out NixOS is the constant struggle to maintain PGP and other security configurations. If you've ever tried to set up git commit signing, together with a security key, you know that it's a pain. GnuPG is not exactly the most user-friendly app out there: it looks like the approach for its development can be summarized as "don't fix it if it aint broken".

Some aspects of PGP complexities are of course due to PGP as a standard being "frozen" in time. There are proposed alternatives, but we are very, very far away from it being replaced.

If you want a more specific example, here's how I set up a few encryption/signing-related configurations in NixOS:


programs.gpg = {
  enable = true;
  package = pkgs.gnupg;
  publicKeys = [{source = ./gpg_public_key.asc; trust="ultimate"; }];
  settings = {
    default-key = "0x0560020C9C577C1B";
  };
  mutableKeys = false;
  mutableTrust = false;
};

programs.git = {
  enable = true;
  userName = "Konstantin Nazarov";
  userEmail = "mail@knazarov.com";
  signing = {
    gpgPath = "${pkgs.gnupg}/bin/gpg2";
    key = "0x0560020C9C577C1B";
    signByDefault = true;
  };
};

accounts.email = {
  maildirBasePath = "${config.users.users.knazarov.home}/Maildir";
  accounts = {
    personal = let account = "mail@knazarov.com"; in {
      primary = true;
      flavor = "fastmail.com";
      address = account;
      userName = account;
      realName = "Konstantin Nazarov";
      passwordCommand = "cat /run/secrets/fastmail_password";
      gpg = {
        key = "0x0560020C9C577C1B";
        signByDefault = true;
      };
      mu.enable = true;
      msmtp.enable = true;
      mbsync = {
        enable = true;
        # Folders existing on the server, but not locally, will be created.
        create = "maildir";
      };
    };
  };
};

It reads almost plain English, doesn't it? This is due to most of the existing software in NixOS being wrapped into library "modules" which you can pass parameters to.

And best of all, NixOS has good integration with sops that allows you to store secrets in an encrypted form in a git repository, and easily reference them in the configuration.

If you're interested, my NixOS configuration can be found here.