How can one have a cache of built packages to decrease the time it takes to switch or upgrade a system at any given moment?
This has been my number one gripe with NixOS given how much time I’ve wasted waiting for packages to build on my system. From my understanding this is apparently only an issue for unfree packages, but I’ve still seen it with non-free packages taking long to build (or maybe I’m hallucinating…).
I’m still very new to this OS so please fill me in if I’m missing anything important. Any ideas/recommendations are welcome. I’m not against hosting a cache if thats the best route, but wondering if there are any other solutions. Maybe I don’t fully understand it.
So, what derivations are you spending significant time building? That’d be most important to know.
Building locally only happens if all configured binary caches don’t contain the desired paths.
Hydra builds all attributes of Nixpkgs that are reachable from pkgs (e.g. from sets that have recurseIntoAttrs = true) and aren’t broken, unavailable or unfree.
If your closure only contains derivations exactly as they are in pkgs and you don’t depend on unfree or broken stuff, you should face no significant local builds, only what I’d call “aggregator” builds; lightweight builds that just e.g. build a tree of symlinks out of all your packages.
There are common things you might do that would cause a package to differ from what it is in upstream Nixpkgs:
Overrides
Overlays
generator functions
Generally, anything that you customise causes a build of some sort. If you change what packages are in the global environment, that will only change the derivation containing the global environment and similar derivations depending on it up to the root of your closure.
If you modify a significant build such as a package, you’ll need to build the entire package. Changing a package that many others depend on via an overlay will cause all dependent packages to be rebuilt.
Please post your configuration, especially the overlays and overrides you apply.
Also, which channel are you using? *-small channels will not wait on Hydra to have built all packages for instance and using one would mean you’ll frequently have to build things locally that hydra would have built at some later point in time.
Sorry for the late response, a lot of the things you mention in your post are foreign concepts to me! I think I need to do a little more nix learning then. I’d also guess it builds packages that are non-free that take up most of the time. I’m not too sure, here’s my main config file.
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).
{ config, pkgs, ... }:
let
unstableTarball =
fetchTarball
https://github.com/NixOS/nixpkgs/archive/nixos-unstable.tar.gz;
in
{
imports =
[ # Include the results of the hardware scan.
/etc/nixos/hardware-configuration.nix
];
# Allow unstable for specific things
nixpkgs.config = {
packageOverrides = pkgs: {
unstable = import unstableTarball {
config = config.nixpkgs.config;
};
};
};
# Bootloader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# Mount SMB
# sudo mount -t cifs //IP/server-username/repos /home/username/repos -o username=username,password=password
fileSystems."/home/username/repos" = {
device = "//172.16.44.2/server-username/repos";
fsType = "cifs";
options = [ "username=username" "password=password" "x-systemd.automount" "noauto" "uid=1000" "gid=1000" "file_mode=0644" "dir_mode=0755" ];
};
networking.hostName = "hostname"; # Define your hostname.
#networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
# Configure network proxy if necessary
# networking.proxy.default = "http://user:password@proxy:port/";
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
# Enable networking
networking.networkmanager.enable = true;
# environment vars
nixpkgs.config.qt5 = {
enable = true;
platformTheme = "qt5ct";
style = {
package = pkgs.utterly-nord-plasma;
name = "Utterly Nord Plasma";
};
};
environment.variables.QT_QPA_PLATFORMTHEME="qt5ct";
# Set your time zone.
time.timeZone = "America/Chicago";
# Select internationalisation properties.
i18n.defaultLocale = "en_US.UTF-8";
i18n.supportedLocales = [
"en_US.UTF-8/UTF-8"
"ja_JP.UTF-8/UTF-8"
];
#i18n.inputMethod.enabled = "fcitx5";
#i18n.inputMethod.fcitx5.addons = [
# pkgs.fcitx5-mozc
# pkgs.fcitx5-gtk
# pkgs.fcitx5-configtool
#];
# environment.variables.GLFW_IM_MODULE = "ibus";
i18n.inputMethod.enabled = "ibus";
i18n.inputMethod.ibus.engines = with pkgs.ibus-engines; [mozc];
i18n.extraLocaleSettings = {
LC_ADDRESS = "en_US.UTF-8";
LC_IDENTIFICATION = "en_US.UTF-8";
LC_MEASUREMENT = "en_US.UTF-8";
LC_MONETARY = "en_US.UTF-8";
LC_NAME = "en_US.UTF-8";
LC_NUMERIC = "en_US.UTF-8";
LC_PAPER = "en_US.UTF-8";
LC_TELEPHONE = "en_US.UTF-8";
LC_TIME = "en_US.UTF-8";
};
services.xserver = {
enable = true;
displayManager.gdm.enable = true;
windowManager.i3.enable = true;
desktopManager.runXdgAutostartIfNone = true;
xkb.layout = "us";
#xkb.variant = "dvorak";
#xkb.options = "grp:win_space_toggle";
videoDrivers = [ "amdgpu" ];
#libinput.enable = true;
#libinput.touchpad.naturalScrolling = true;
};
systemd.timers."hello-world" = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "Tue *-*-01 10:00:00";
Persistent = true;
Unit = "hello-world.service";
};
};
systemd.services."hello-world" = {
script = ''
set -eu
XDG_RUNTIME_DIR=/run/user/1000 DISPLAY=:0 /run/current-system/sw/bin/notify-send 'Testing Sirens' 'Sirens are being tested, do not fret!' -u critical
'';
serviceConfig = {
Type = "oneshot";
User = "username";
};
};
services.xserver.deviceSection = ''Option "TearFree" "true"'';
services.picom = {
enable = false;
vSync = true;
};
# Enable CUPS to print documents.
services.printing.enable = true;
# Enable sound with pipewire.
hardware.pulseaudio.enable = false;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
# If you want to use JACK applications, uncomment this
#jack.enable = true;
};
hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = true;
services.blueman.enable = true;
#hardware.pulseaudio.extraConfig = "load-module module-combine-sink";
security.rtkit.enable = true;
#sound.mediaKeys = {
# enable = true;
# volumeStep = "5%";
#};
networking.extraHosts =
''
#redacted
'';
# Enable touchpad support (enabled default in most desktopManager).
# services.xserver.libinput.enable = true;
# Define a user account. Don't forget to set a password with ‘passwd’.
users.users.username = {
isNormalUser = true;
description = "User";
extraGroups = [ "networkmanager" "wheel" "docker" "dialout" "tty" "adbusers" "kvm"];
packages = with pkgs; [
firefox
thunderbird
];
};
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
# ADB
programs.adb.enable = true;
programs.nix-ld.enable = true;
# Experimental
nix.settings.experimental-features = [ "nix-command" "flakes" ];
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs;
let
polybar = pkgs.polybar.override {
i3Support = true;
};
in
[
unstable.zed-editor
just
polybar
vscode
tor-browser
tor
dos2unix
rpi-imager
gnome.gnome-keyring
gcr
calibre
snmpcheck
icu
anki-bin
ghidra
bcompare
binwalk
arp-scan
obs-studio
davinci-resolve
mediamtx
hplip
vlc
xwinwrap
wireshark
postman
fclones
fclones-gui
nfs-utils
jadx
apktool
bytecode-viewer
openjdk
dex2jar
cool-retro-term
ntfs3g
ffmpeg-full
frei0r
frida-tools
nodejs
unixtools.xxd
keepassxc
libsForQt5.kleopatra
pinentry
pinentry-curses
gnupg
net-snmp
frp
qemu-utils
nmap
mitmproxy
openssl
pkg-config
radamsa
tmux
avahi
filezilla
mitmproxy
python311Packages.mitmproxy-rs
vagrant
android-tools
gradle
scrcpy
gdb
ranger
lf
wget
neovim
gcc
clang
gnumake
desktop-file-utils
ripgrep
lazygit
bottom
polkit
polkit-kde-agent
gsimplecal
i3
x11vnc
tigervnc
alacritty
krita
figlet
kitty
kitty-themes
kitty-img
zsh
gnome.gdm
dunst
libnotify
bind
p7zip
ark
mpvScripts.mpris
cava
braa
qrencode
zbar
mpv
ani-cli
mpd
mpd-mpris
mpd-discord-rpc
playerctl
alsa-utils
pamixer
xbindkeys
xorg.xev
xvfb-run
xorg.xbacklight
sxiv
feh
xclip
flameshot
yt-dlp
imagemagick
zathura
cron
obsidian
neofetch
redshift
curl
jq
wget
libreoffice-still
arandr
xorg.xrandr
conda
git
git-lfs
sshfs
openssh
inetutils
rsync
meld
dolphin
samba
resvg
libsForQt5.ffmpegthumbs
libsForQt5.kio-extras
libsForQt5.kdegraphics-thumbnailers
kdePackages.kdegraphics-thumbnailers
ffmpeg
nufraw-thumbnailer
taglib
libsForQt5.qt5ct
python3
python311Packages.pip
networkmanagerapplet
wireguard-tools
polkit_gnome
picom
rofi
rofi-emoji
rofi-calc
usbutils
subversion
minicom
putty
screen
autorandr
killall
lxappearance
capitaine-cursors
libsForQt5.qt5ct
libsForQt5.breeze-icons
libsForQt5.ark
libsForQt5.qtstyleplugin-kvantum
libsForQt5.qt5ct
chromium
lm_sensors
i3lock-fancy-rapid
pavucontrol
cifs-utils
xlsfonts
materia-theme
pciutils
xorg.xf86videoamdgpu
vaapiVdpau
vdpauinfo
libvdpau-va-gl
libva-utils
btop
htop
cmatrix
asciiquarium-transparent
file
appimage-run
polkit
unetbootin
gparted
uuu
pv
cdrtools
cdrkit
exfatprogs
ntfs3g
gnome.nautilus
rdesktop
moonlight-qt
synergy
#logitech-udev-rules
gedit
bc
busybox
iperf3
freerdp
libsForQt5.qt5ct
unzip
];
fonts.packages = with pkgs; [
siji
nerdfonts
font-awesome
noto-fonts
noto-fonts-cjk-sans
noto-fonts-cjk-serif
noto-fonts-color-emoji
liberation_ttf
fira-code
fira-code-symbols
mplus-outline-fonts.githubRelease
dina-font
proggyfonts
fira-mono
fira-code
carlito
dejavu_fonts
ipafont
kochi-substitute
source-code-pro
ttf_bitstream_vera
];
# Set default fonts
fonts.fontconfig.defaultFonts = {
monospace = [
"Fira Mono"
"Noto Sans Mono CJK JP"
];
sansSerif = [
"Fira Mono"
"Noto Sans CJK JP"
];
serif = [
"Fira Mono"
"Noto Serif CJK JP"
];
};
nixpkgs.config.permittedInsecurePackages = [
"electron-25.9.0"
"python3.11-django-3.1.14"
];
programs.zsh.enable = true;
users.defaultUserShell = pkgs.zsh;
systemd = {
user.services.polkit-gnome-authentication-agent-1 = {
description = "polkit-gnome-authentication-agent-1";
wantedBy = [ "graphical-session.target" ];
wants = [ "graphical-session.target" ];
after = [ "graphical-session.target" ];
serviceConfig = {
Type = "simple";
ExecStart =
"${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1";
Restart = "on-failure";
RestartSec = 1;
TimeoutStopSec = 10;
};
};
};
# DOCKER
virtualisation.docker.rootless = {
enable = true;
setSocketVariable = true;
};
users.extraGroups.docker.members = [ "username" ];
# Enable the OpenSSH daemon.
services.openssh = {
enable = true;
ports = [ 22 ];
settings = {
PasswordAuthentication = true;
AllowUsers = [ "username" ];
UseDns = true;
X11Forwarding = true;
PermitRootLogin = "no"; # "yes", "without-password", "prohibit-password", "forced-commands-only", "no"
};
};
services.avahi = {
enable = true;
nssmdns4 = true;
openFirewall = true;
};
services.devmon.enable = true;
services.gvfs.enable = true;
services.udisks2.enable = true;
# Open ports in the firewall.
#networking.firewall.enable = false;
#networking.firewall.allowedTCPPorts = [ 22 80 443 5000 ];
#networking.firewall.allowedUDPPorts = [ 51820 69 ];
# DEFCON
networking.firewall.enable = false;
networking.firewall.allowedTCPPorts = [];
networking.firewall.allowedUDPPorts = [];
# Some programs need SUID wrappers, can be configured further or are
# started in user sessions.
# programs.mtr.enable = true;
# programs.gnupg.agent = {
# enable = true;
# enableSSHSupport = true;
# };
# This is using a rec (recursive) expression to set and access XDG_BIN_HOME within the expression
# For more on rec expressions see https://nix.dev/tutorials/first-steps/nix-language#recursive-attribute-set-rec
# List services that you want to enable:
# Enable the OpenSSH daemon.
# services.openssh.enable = true;
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. It‘s perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "23.11"; # Did you read the comment?
services.libinput.touchpad.naturalScrolling = true;
programs.light.enable = true;
services.actkbd = {
enable = true;
bindings = [
{ keys = [ 225 ]; events = [ "key" ]; command = "/run/current-system/sw/bin/light -A 10"; }
{ keys = [ 224 ]; events = [ "key" ]; command = "/run/current-system/sw/bin/light -U 10"; }
];
};
# For kleopatra
services.pcscd.enable = true;
programs.gnupg.agent = {
enable = true;
enableSSHSupport = true;
};
# udev rules for uuu
services.udev.extraRules = builtins.readFile ./uuu-udev;
nix.optimise.automatic = true;
nix.optimise.dates = [ "03:45" ]; # Optional; allows customizing optimisation schedule
# Newest kernel
boot.kernelPackages = pkgs.linuxPackages_latest;
# firefox save dialog
environment.sessionVariables = {
MOZ_USE_XINPUT2 = "1";
};
xdg.mime.defaultApplications = {
"text/html" = "firefox.desktop";
"x-scheme-handler/http" = "firefox.desktop";
"x-scheme-handler/https" = "firefox.desktop";
"x-scheme-handler/about" = "firefox.desktop";
"x-scheme-handler/unknown" = "firefox.desktop";
"application/pdf" = "org.pwmt.zathura-pdf-mupdf.desktop";
};
services.xserver.windowManager.i3.extraSessionCommands = ''
eval $(gnome-keyring-daemon --daemonize)
export SSH_AUTH_SOCK
'';
}
If I was crazy enough, and needed to use that version, would the best way to do this be to build it on a different server and cache the files that way? Using the binary cache?