Nixos-rebuild triggers enormous rebuilds

Hello,

I’m fairly new to Nix OS, and I am having some trouble rebuilding my system. This has been an ongoing issue for me for months in various ways, and I suspect I’m just doing something altogether wrong. The general situation goes like this:

  • it’s been a month or so since I’ve updated my system, so I nix flake update and sudo nixos-rebuild switch –flake <my-flake-dir>.
  • the rebuild starts, and as I understand it, somewhere along the way a cache miss occurs, and my laptop starts trying to rebuild something (it’s often been librewolf, though it happened a bit ago for mpv. Most recently, I figured out it was triggering a build of python3 as well as numpy, pandas, and a handful of other python libraries all because I had services.pipewire.alsa.enable32bit set to true.
  • Over the course of several hours, my laptop gets extremely warm, freezes up completely (due to the memory and cpu’s being completely maxed out), and the whole thing crashes. No rebuild for me. Unfortunately, now that I’ve updated the flake.lock, even if I wanted to change something innocuous on my system (e.g. the timezone) any rebuild will now trigger this process and so can’t complete. As I understand it this can be rolled back somehow though I’ve not yet learned how to do so.
  • I clunkily figure out what package is causing the builds, say aloud "ugh…I guess I can live without that for a while?” remove it from my config, and pray that whenever I end up needing it whatever has been happening has been resolved.

What I’ve tried:

  • adding the community Cachix instance to my substituters. So far as I can tell, this did nothing.
  • EDIT: forgot to add these VV
  • adding different versions of the desired package (for example librewolf-unwrapped or librewolf-bin) to my permittedInsecurePackages.
  • the above-mentioned “just remove it for now and pray it is available later” strategy.

So, my questions:

  1. Is there some way I can blacklist packages from rebuilding on my system? Or even forbid builds entirely? I don’t think my laptop can handle them.
  2. Is all of this indicative of some misconfiguration in my system, or is this all intended behaviour? It seems very odd to me that a normal failure mode for a simple system rebuild is to, without prompting the user, take on an insane rebuild that your system cannot possibly complete.
  3. Why is the option services.pipewire.alsa.enable32bit alone (and not any of the other pipewire options I also have set) causing a rebuild?

Thanks for any help. Links are of course welcome, and I’ve tried my best to read around about these topics, but there are so many competing wikis, websites, blog posts, and books, many of which often give me erroneous information, I’m not sure what sources I can trust for learning Nix.

3 Likes

I’d guess you have some nvidia overlay or such, but share your config and we can identify it.

librewolf was uncached for a while, and browser builds are rough. It should be cached as of your next update, though.

Maintain your config in a git repo, and commit often. Then you can just revert a bad commit easily. Nix will not help you with this, it’s just a set of text files that you need to manage externally.

That’s not a failure mode, because nix is a build system and therefore designed to administer builds. The fact that there’s a huge cache run by/for NixOS is tangential to that. You can limit cores/jobs to reduce the load on your system and make it more likely to complete a build, at the cost of speed.

We don’t know what it’s rebuilding without seeing your config.

2 Likes

Thanks for your reply. I’ve attached my config here. As you’ll see I’ve commented out various things to try and single out the problem, and I’ve labelled the problem line, which is in conf.nix. To be clear, as of now the rebuild goes through just fine with that line commented out, but triggers a whole pile of python builds if I uncomment.

flake.nix
{
  inputs = {
    # nixpkgs-old.url = "github:NixOS/nixpkgs/nixos-24.05";
    # nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
  };

  outputs = { self, nixpkgs, ... } @ inputs: {
    nixosConfigurations = {
      laptop = nixpkgs.lib.nixosSystem {
        specialArgs = {
          inherit inputs;
        };
        system = "x86_64-linux";
        modules = [
          ./base.nix
          ./conf.nix
          ./hardware-conf.nix
        ];
      };
    };
  };
}
base.nix
{ stdenv, config, lib, pkgs, inputs, ... }:
# let 
#   mytex = pkgs.stdenvNoCC.mkDerivation {
#     name = "mytex";
#     src = ./latex;
#     installPhase = "mkdir -p $out/tex/latex; cp -r $src $out/tex/latex";
#     passthru.tlType = "run";
#   };
#   mytex-pkg = { pkgs = [ mytex ]; };
# in
{
  imports = [ ];

boot = {
  kernelParams = ["quiet"];
  initrd.systemd.enable = true;
  loader = {
    systemd-boot.enable = true;
    systemd-boot.configurationLimit = 10;
    # grub.enable = true;
    # grub.device = "nodev";
    # grub.configurationLimit = 10;
    efi.canTouchEfiVariables = true;
  };
  plymouth = {
    enable = true;
    themePackages = with pkgs; [ (adi1090x-plymouth-themes.override {selected_themes = [ "spinner_alt" ]; }) ];
    theme = "spinner_alt";
  };
};

nix.settings.experimental-features = ["nix-command" "flakes"];
nix.settings = {
  substituters = [
    "https://cache.nixos.org/"
    "https://nix-community.cachix.org"
    "https://hyprland.cachix.org"
  ];
  trusted-substituters = [
    "https://cache.nixos.org/"
    "https://nix-community.cachix.org"
    "https://hyprland.cachix.org"
  ];
  trusted-public-keys = [
    "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
    "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
    "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
  ];
  trusted-users = ["root" "@wheel"];
};

networking.networkmanager = {
  enable = true;
  plugins = with pkgs; [ networkmanager-openvpn ];
};

time.timeZone = "Europe/Amsterdam";
# time.timeZone = "America/New_York";
i18n.defaultLocale = "en_US.UTF-8";

programs = {
  zsh.enable = true;
  kdeconnect.enable = true;
  hyprland.enable = true;
  hyprland.withUWSM = true;
  hyprland.xwayland.enable = true;
  firefox = {
    enable = true;
    preferences = {
      "browser.startup.homepage" = "https://example.com";
      "privacy.resistFingerprinting" = true;
    };
    policies = {
      DisableTelemetry = true;
    };
  };
};

programs.gnupg.agent = {
  enable = true;
  pinentryPackage = with pkgs; pinentry-all;
  enableSSHSupport = true;
};

environment.sessionVariables = {
  # ... env vars ...
};

nixpkgs.config.allowUnfree = true;
# nixpkgs.config.permittedInsecurePackages = [
  # "librewolf-152.0-1"
  # "librewolf-unwrapped-152.0-1"
# ]; 

environment.systemPackages = with pkgs; [

  vim
  alacritty
  git
  rsync
  zsh
  emacs-pgtk ripgrep fd emacs-all-the-icons-fonts

  hyprpaper  # wallpaper
  hyprpicker # ezpz color picker
  hyprcursor # 
  hypridle   # idle daemon
  hyprlock   # screen lock
  hyprshade  # screen warm shading
  gromit-mpx # desktop annotation
  
  xdg-desktop-portal-hyprland
  xdg-desktop-portal-wlr
  xdg-desktop-portal-gnome
  fuzzel dmenu-bluetooth networkmanager_dmenu
  waybar # eww
  mako libnotify
  xdg-utils
  nomacs exiftool imagemagick # for images
  stc-cli
  gnuplot

  gcc clang gnumake
  zip unzip p7zip 
  gnupg
  which
  wget
  udisks udiskie
  exfatprogs
  qmk dos2unix # required for qmk now?
  openssl


  bluez
  htop-vim

  grim slurp
  brightnessctl playerctl pamixer pavucontrol
  clipman wl-clipboard
  dragon-drop

  syncthing
  finamp
  foliate
  mpv 
  obs-studio 

  telegram-desktop
  signal-desktop
  vesktop
  slack
  thunderbird

  adwaita-icon-theme gnome-icon-theme hicolor-icon-theme

  sbcl 
  ghc 
  idris2 
  zulu8 
  coq agda
  rustc cargo rust-analyzer
  cargo-flamegraph perf
  graphviz

  translate-shell
  pandoc
  evince
  pdftk # mupdf pdfpc
  diff-pdf
  poppler-utils

  qbittorrent
  mullvad
  eduvpn-client

  typst tinymist
  # typstPackages.fletcher typstPackages.marginalia

  # my latex packages
  # (pkgs.texlive.combine {
  #   inherit (pkgs.texlive)
  #   scheme-medium texdoc enumitem csquotes cjk biblatex biber cleveref silence
  #   orcidlink fancyqr qrcode pict2e
  #   # adding for fp lhs report
  #   datetime wrapfig mdframed fmtcount relsize needspace zref
  #   # quiver
  #   tikz-cd quiver spath3 tikzsymbols
  #   # want "dialogue"
  #   frankenstein
  #   # for algorithmicx
  #   fifo-stack varwidth tabto-ltx totcount algorithmicx
  #   # easier pseudocode
  #   pseudo tcolorbox tikzfill
  #   # todo notes
  #   todonotes xargs xcolor
  #   # publication formats
  #   llncs
  #   # tufte things
  #   tufte-latex
  #   # metropolis beamer theme
  #   beamertheme-metropolis
  #   # for focs notes
  #   pdfpc hyperxmp multirow tikzmark fontawesome hobby
  #   # fonts
  #   fontaxes iwona roboto fira twemojis bbm
  #   # helping sarah
  #   # xsim tasks datetime2 translations cancel forest
  #   ;
  #   inherit mytex-pkg;
  #   })
  
];

services = {
  pipewire = {
    enable = true;
    audio.enable = true;
    pulse.enable = true;
    alsa.enable = true;
    # alsa.support32Bit = true; # <---- THIS IS THE PROBLEMATIC LINE
    jack.enable = true;
  };
  dbus.implementation = "broker";
  openssh.enable = true;
  mullvad-vpn.enable = true;
  blueman.enable = true;
  udisks2.enable = true;
  getty.autologinUser = <USER>;
  udev.packages = [ pkgs.qmk-udev-rules ];
  printing.enable = true;
  avahi = {
    enable = true;
    nssmdns4 = true;
    openFirewall = true;
  };
  syncthing = {
      enable = true;
      user = <USER>;
  };
};
hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = true;

users.users.<USER> = {
  isNormalUser = true;
  home = "/home/<USER>";
  shell = pkgs.zsh;
  description = "<DESC>";
  extraGroups = [ "wheel" "networkmanager" "davfs2"];
};

fonts.packages = with pkgs; [
  # ... fonts ...
];

}
conf.nix
{ lib, pkgs, config, ... }:

{
  networking.hostName = <HOSTNAME>;

services.fwupd.enable = true;

boot.kernelParams = [
    "intel_idle.max_cstate=9"
    "i915.enable_psr=1"
    "pcie_aspm=force"
];

powerManagement.enable  = true;
powerManagement.powertop.enable = true;
powerManagement.cpuFreqGovernor = "schedutil";

hardware.system76.power-daemon.enable = true;

services.system76-scheduler.settings.cfsProfiles.enable = true;
services.thermald.enable = true;
services.upower.enable = true;

environment.systemPackages = with pkgs; [
  # for power management
  powertop
  kmonad
  # kmonad flake (from input)
  # inputs.monad.packages."${pkgs.system}".kmonad
];

# not working, maybe something to do with location services?
# services.automatic-timezoned.enable = true;

services.tlp = {
      enable = true;
      settings = {
          # ... settings ...
      };
};

systemd.services.kmonad = {
   enable = true;
   description = "Kmonad keyboard configuration";
   serviceConfig = {
     ExecStart = "/run/current-system/sw/bin/kmonad /home/<USER>/.config/kmonad.kbd";
   };
   wantedBy = [ "default.target" ];
};

system.stateVersion = "23.11"; # Did you read the comment?

}

The hyprland cachix isn’t doing you any good if you’re not using their flake. So you can remove that.

I also don’t see any overlay, but you also commented out all your packages, so hard to tell what would obviously get rebuilt.

Again, though, if the concern is librewolf then it will be cached soon, see Librewolf Marked as Insecure - #3 by mBornand. (Insecure packages are not cached by hydra, as a policy.)

2 Likes

Ok, I’ve edited my packages back in. Still, the problematic line is services.pipewire.alsa.support32Bit, which I figured had nothing to do with which packages were installed. It’s nice to see that librewolf will be cached soon, though at this point my concern is with this general issue as a pain point for nix as whole, because I’ve now experienced it for three seemingly unrelated packages, so I want to figure out what I can do if/when this happens again.

EDIT: on a related note, how do I check the status of caching and https://cache.nixos.org/? When I go there myself I only find a simple page describing the site, and https://status.nixos.org/ takes me to commits for the channel I choose, but that doesn’t seem to give any package-specific information.

1 Like

An aspect of configuring an OS with a programming language is that it pushes you to develop compsci/dev skills in order to do so effectively. (Whether or not this is a desirable aspect is user-specific and best left to discuss in a different thread if so desired)

It turns out that this option does relate to which packages your system profile depends on (“install” has no coherent meaning in NixOS). For services.pipewire.alsa.support32Bit, it’s best to lookup the option source.

  1. There are many ways to find the source, but man configuration.nix will tell you that this option is declared in <nixpkgs/nixos/modules/services/desktops/pipewire/pipewire.nix>.
  2. Going to github:NixOS/nixpkgs/…/pipewire.nix you can see that ultimately this option is simply adding lines to /etc/alsa/conf.d/49-pipewire-modules.conf
  3. However, those lines depend on ${pkgs.pkgsi686Linux.pipewire}.
  4. Therefore, the build system (nix) will need pkgs.pipewire built for i686 as a dependency when you enable this option.

i686 support was announced to be more significantly curtailed a year and a half ago, but according to comments in that thread i686 was effectively broken for much longer. You can also confirm that the last successful hydra build for nixos-26.05 does not include an i686 build of nixpkgs.pipewire.

The result of this investigation is that enabling this option is expected to force you to compile packages at this time due to infra limitation on the ability to support i686.

One method is to request <cache-uri>/<store-hash>.narinfo to check on whether a store path is cached by a specific cache.

For the most recent build of nixpkgs.pipewire.x86_64-linux, the output store path for out is /nix/store/6y2b9qs1npwsvcsl9m66hjarzj0yagb4-pipewire-1.6.5. You can check https://cache.nixos.org/6y2b9qs1npwsvcsl9m66hjarzj0yagb4.narinfo to see that it is cached by that particular binary cache.

Because nix is input-addressed, you can know the output store path before the derivation is actually built. Practically speaking, since the build system already knows the output store path, it can then use this store path as the key for a cache lookup and simply substitute it rather than build.

1 Like

It’s nice to see that librewolf will be cached soon, though at this point my concern is with this general issue as a pain point for nix as whole, because I’ve now experienced it for three seemingly unrelated packages, so I want to figure out what I can do if/when this happens again.

Something you could do if you encounter a package that has caching issues, but you still want to update the rest of your system, is add another input to your flake that points to the commit that you were using before the update, and then create an overlay so that you can refer to it in your configuration. I wish i could share an example, but i don’t have it on hand right now since haven’t had the need to do this for a while. plus i’m mainly using Guix right now, which handles it differently, but you should be able to find some examples online (or maybe someone else can chime in).

Not really reasonable for something like a browser that’s security sensitive.

perhaps not, depends on how old your previous generation is. If you don’t want to or can’t build it yourself, you’re still running an outdated browser if you don’t update at all.

1 Like

See below for context:

But you maybe able to simply disable the option permnanently, ALSA is barely in use and a 32-bit app is even rarer.

1 Like

You should probably remove that entire block, not just the cachix substituter. This is:

  • Giving all your wheel users passwordless sudo with zero logging or asserting that an actual human is performing the task
  • Hard-coding a key for the NixOS cache that would best be invalidated through upstream definitions, not your own manual edits
  • Trusting two extra keys you clearly don’t actually have to trust because you’re not intentionally using packages from their associated caches
  • Slowing down almost everything you do with nix by adding additional http queries to extra caches you don’t need

Generally, you’re almost always better off using the nixpkgs versions of nix-community packages than using their flakes + the community caches.

Even if you insist on using the flakes (why are people so obsessed with auto updates for bleeding edge? You probably don’t even know what features are added, let alone make use of them, and you are gaining like a week or two at best), adding the community caches will slow down your overall builds, often sufficiently that any gain from avoiding a (typically pretty small) package build once every few weeks is outweighed by the extra http queries.

5 Likes

I just checked and i’ve had "@wheel” inside my config for the longest time now. What is the recommended way to go about this? should i just add my specific user to trusted-users instead?

@juipeltje NO!

it gives root without password

instead, edit root /etc/nix/nix.conf or from nixos settings and

  • add binary cache public key to trusted-public-keys
  • add binary cache url to trusted-substituters (used only if additionally enabled via flake or user nix conf) or substituters (used every time, slows down lookup a bit)
1 Like

CAUTION! Remove everything but root from trusted-users! It allows arbitrary code execution as root sometimes even in nix build, like that random flake you used last week.

1 Like

@thain here are some tips to make builds go easier on your machine:

  • reduce max-jobs in nix.conf - fewer concurrent jobs, less ram and cpu
  • make sure to have regular swap. this results in slowdowns rather than freezes when ram is very low, and it comes later
  • enable zram swap to slightly reduce memory pressure
  • reduce nix daemon cpu scheduler priority
    nix = { daemonCPUSchedPolicy = "idle";daemonIOSchedClass = "idle";};
  • remote builder eg. home pc or cloud machine, may be used on demand

Don’t set trusted-users at all, frankly - that just gives a user (and programs running as that user) passwordless and non-interactive root. That’s the easiest way to add a malicious cache, among other things.

https://nix.dev/manual/nix/2.34/command-ref/conf-file.html#conf-trusted-users

The default is already root, so you don’t need to set it.

2 Likes

Swap increases I/O thrashing and zram increases memory pressure as it reduces available ram (needing CPU cycles to flip back and forth between ram and zram). Just don’t use these at all, especially for a browser build.

Reducing jobs and cores is fine - see Tuning Cores and Jobs - Nix 2.34.8 Reference Manual; obviously this will make builds take longer.

You can also use systemd’s resource allocation to limit how much the nix daemon gets, e.g. by setting services.nix-daemon.serviceConfig.CPUQuota to set max cpu usage (note that the max is (# cores) * 100%), or services.nix-daemon.serviceConfig.OOMScoreAdjust to make it more likely to kill the nix daemon than other processes when under memory pressure. earlyoom may also be of interest.

Yeah, as @waffle8946 says, use sudo if you need to do something that can only be done by a trusted user. You don’t need to be a trusted user for most things you might want to do with nix.

I think there are two notable situations in which people set that setting:

  • If you use a flake that asks for permissions to toggle features that can only be toggled by trusted users through the nix-settings output, it tells you that you need to be a trusted user, so people add this without thinking.
    • Just… Don’t do that. It’s horrible UX that nix recommends such poor practice without telling you exactly what it implies.
    • The only use case for this feature is temporarily adding community caches, which again, you should probably not be using to begin with. People largely do this only because it’s possible; the only sensible use of that option is enabling additional experimental features.
  • Deploying to a remote with --target-host requires either trusting the ssh-ing user or for the derivations to be signed.
    • This is a kinda legit use case, but you can just sign your derivations instead to avoid having a second root user.
2 Likes

Hmm, i see, well i definitely removed my trusted-users stuff now that i know this, but @brainrake mentioned i could put my additional caches inside the system-wide nix config instead, but if i’m understanding correctly, you’re saying i shouldn’t use additional caches at all? At the moment i’m only using a cache from nix-community, which i think i added for NUR, but i’m not sure anymore tbh lol.