Flake managed NIX config -- update vs build vs switching

Hi folks, I’ve grown to the following config in my nix flake below for configuring both my OS and home-manager, and I’m seeking some experienced hands to help me understand upgrading and building. For example:

  1. When I upgrade, I do nix flake update – do I also need to do sudo nix-channel --update as well?
  2. Do I need to do a nixos-rebuild after the nix flake update?
  3. Anybody have suggestions as to a better way to do this? Things I’m missing?
      devShells = forAllSystems (system:
          pkgs = import nixpkgs { inherit system overlays; };
          PRE_CMDS = "statix check && nix fmt && git add .";
          FLAKE = "--flake .#xps15 --impure";
          FLAKEUSER = "--flake .#mcrowe@xps15 --impure";
          COMMIT = "git diff | sgpt 'Generate git commit message, for my changes' > /tmp/gitmsg && git add . && git commit -F /tmp/gitmsg";
          default = pkgs.mkShell {
            name = "flakeShell";
            buildInputs = with pkgs; [ git stylua nixfmt shfmt shellcheck statix ];
            shellHook = ''
              alias nix-rebuild-home="${PRE_CMDS}; home-manager switch -b backup ${FLAKEUSER} && ${COMMIT}"
              alias nix-rebuild-test="${PRE_CMDS}; sudo sh -c \"NIXPKGS_ALLOW_UNFREE=1 nixos-rebuild test ${FLAKE}\""
              alias nix-rebuild="${PRE_CMDS}; nix flake update && nixos-rebuild build ${FLAKE}"
              alias nix-rebuild-system="${PRE_CMDS}; sudo sh -c \"NIXPKGS_ALLOW_UNFREE=1 nixos-rebuild switch ${FLAKE}\" && ${COMMIT}"
              alias nix-upgrade="${PRE_CMDS}; nix flake update && nixos-rebuild build ${FLAKE}"

nix flake update only updates your flake.lockfile. Chanels are independent and if you are using channels in parallel, you have to update them with nix-channel --update.

Yes, the nixos-rebuild is used to create a new generation of your system config based on the state in your lockfile.

  1. Part of the purpose of flakes is to supersede channels - your flake shouldn’t be dependent on channels at all. Although I’m not sure about that since you’re using --impure.

  2. nix flake update just recreates the lock file flake.lock, which determines the versions of your flake inputs, probably most saliently nixpkgs. Assuming your nixos configuration is in your flake, yes you’ll need to do nixos-rebuild switch to see updates to flake inputs in your new lock file reflected in your system configuration. It’s the same for home-manager, you need do a home-manager switch after you recreate your lockfile to see changes reflected in your user environment.

  3. Highly opinionated and matter of taste opinions incoming, take with a grain of salt: Personally I’d pare down those aliases a lot - I feel like you can eliminate most of the extra typing that motivates their creation in the first place:

    • I rarely get file-conflicts for home-manager switch which would require -b, and when I do it generally requires manual intervention anyway, so I’d just re-run with -b and fix the conflict.
    • I don’t want to commit immediately after switching, in case I decide that the config is bad, or I forgot something. So I prefer to commit manually, when I’m sure I’m done with the change.
    • if the flake is symlinked to the default locations for nixos and home-manager, and your configurations are named hostname and user@hostname, you don’t need to specify the flake and flake output, they can be inferred
    • you can set nixpkgs.config.allowUnfree = true; in nixos config to eliminate NIXPKGS_ALLOW_UNFREE=1
    • nix flake update upgrades most packages you’ll use. It’s a pretty big decision; I only do it once every couple months to avoid downloading a bunch of packages too frequently. That’s still relatively bleeding edge! You don’t need to update every time. So that’s something I’d prefer to do manually and occasionally rather than mixed in with an alias as a routine operation.
    • I’d be interested to know why you need --impure, maybe that can be eliminated somehow as well.

    I think PRE_CMDS is a great idea.

Personally I have home-manager aliased to hm, so I just run hm switch when I want to switch, no extra flags or pre or post operations. If I used nixos regularly, I’d probably alias nixos-rebuild to nr or something.

@sullyj3 – can you explain this a bit more?

Yeah, I quite agree. I tend to do it whenever VSCode starts nagging about an upgrade

1 Like


From man nixos-rebuild

--flake flake-uri[#name]
Build the NixOS system from the specified flake. It defaults to the directory containing the target of the symlink /etc/nixos/flake.nix, if it exists. The flake must contain an output named nixosConfigurations.name. If name is omitted, it default to the current host name.

later in the manual:

If this file exists, then nixos-rebuild will use it as if the --flake option was given. This file may be a symlink to a flake.nix in an actual flake; thus /etc/nixos need not be a flake.

These taken together mean that if you have an /etc/nixos/flake.nix which exposes an output nixosConfigurations.<your computer's hostname>, that configuration will be automatically used by nixos-rebuild switch and related commands, without you having to specify it using the --flake flag.

Additionally, if you need more than a single file of configuration, you can have /etc/nixos/flake.nix be a symlink to the flake.nix in your actual configuration repository, and it will just work.

The same concept applies to home-manager, only the exposed home configuration should be called homeConfigurations.<username here>@<hostname here>

From man home-manager:

       This command updates the user environment so that it corresponds to the configuration specified in $XDG_CONFIG_HOME/home-manager/home.nix or $XDG_CONFIG_HOME/home-manager/flake.nix.
        --flake flake-uri[#name]
           Build Home Manager configuration from the flake, which must contain the output homeConfigurations.name. If no name is specified it will first try username@hostname and then username.

So you can have your single flake repository containing both your nixos and home-manager configs, exposing your configurations at the expected output names. You symlink both /etc/nixos/flake.nix and ~/.config/home-manager/flake.nix to the flake.nix from your config repository. Then you won’t have to specify the --flake flag for either home-manager or nixos-rebuild.