21.02 Nix
my code is possible if people want it 😃 the real value of NixOS is hardware and OS config can be turned into libraries! (HN)
The nix is a package management system that enforces isolation and can work as a secondary package manager for any Linux without any risk.
It enforces everything is text, allowing easy switching of configurations with zero-efforts and zero-misconfigurations, formally defined as reproducibility.
With nix its impossible to have partially installed applications (closure). It makes development environment too easy, cross-compilation is as easy as choosing an attribute to build.
Basic terminology
The term 'nix' can refer to multiple things and documentation around is very chaotic, that's why basic terminology is essential:
Nix in general refers to a purely functional package manager, that came in 2003 along with the PhD Thesis by Eelco Dolstra.
Nix langauge is a DSL for writing system or home configuration, used directly by nix package manager.
NixOS is an OS built around nix as its only package manager which came later in 2007, nix can be used outside NixOS, and that's how I use it.
nixpkgs (search) is world's largest and freshest package repository known till date with over 80k packages.
https://cache.nixos.org is pre-built binary cache on top of nixpkgs, which stores all the versions of all the packages known till date, 425TiB in total as of May 2023.
Flakes is an experimental feature of nix. This enables version pinning and making modules completely pure.
This article by Julia Evans and all the links it leads to, are great starting point for anybody new to nix.
Important projects / features
1. Home Manager
nix-community/home-manager is a part of nix-community github org that provides various "Nix Modules" for installing & configuring user-level programs.
Nix Module System is really interesting, NixCon 2023 - Why choose Nix for configuration? dives deep into it.
2. Comma
nix-community/comma allows running binaries transiently/ephemerally, What if I don't have neofetch?
$ , neofetch
And that's it, I don't need to search the package that provides that binary, nor I have to install it, just run it!
3. DevShells
The numtide/devshell helps one to quickly bootstrap a project's build environment just by running nix develop
.
The devshell docs are really good, as well as this article.
Their statement is
It should not take more than 10 minutes from the time you clone a repo and can start contributing.
It prepares the shell with all the build dependencies, the environmental variables, the services (e.g. development database), and provides a handy menu for common commands for the newcomers to the project.
4. SnowfallLib
This snowfallorg/lib is a support library for giving a file structure to system/home configuration based flakes (NixOS, home-manager, and nix-darwin).
I personally prefer it to elliminate boilerplate in flake.nix
at root of project.
Links
- NixOS and Flakes book - A really good community-maintained book.
- Connecting Bash to Nix - A really good bottom-up (low-level) article.
- Zero to Nix by DeterminateSystems - Learn nix interactively.
- Nix std-lib and nixpkgs-lib docs in one place.
- noogle.dev - Google for nix library functions.
- nix-community/awesome-nix.
- Secret management schemes.
- Ancient collection of useful nix hacks.
- Nix Hour by Tweag (YT) - A series going deep into nix.
- NixCon 2023 (YT) - Talks on recent development and community projects.
- r13y.com - How much % of NixOS is reproducible?
- Nix by wiki.nikiv.dev - More nix resources.
- Public NixOS configs on nixos.wiki and also a few with comparision.
- rasendubi/dotfiles - A really extensive NixOS config.
- NixOS/rfcs - big changes on Nix or NixOS are tracked here.
- Build Systems Nov 2019 - Eelco Dolstra - Slides.
Related Links
- Nix/NixOS Discord (unofficial) - A community of really fast and helpful people.
- NixOS/patchelf - A binary patcher for modifying lookup paths of existing ELF binary.
- Tvix (HN) - A new nix implementation in rust, tvixbolt online interpreter is good for AST, Bytecode, Runtime Trace, and Output analysis of nix code.
- not-os and ZilchOS and NixNG.
- NUR - Nix User Repository, equivalent of Arch's AUR, any PR will be immediately merged without any checks.
- Guix - similar goals to nix, except enforces only free softwares. It is toxic to people mentioning nix in thier irc channels.
- GoboLinux (HN) - is an alternative Linux distribution which redefines the entire filesystem hierarchy.
- Distri - A linux distro to search fast package management.
Notes
1. Config Dump
nix show-config # Shows dump of $XDG_CONFIG_HOME/nix/nix.conf
2. [HM] Cleanup older generations
pushd ~/.local/state/nix/profiles && ls | awk "!/$(readlink home-manager)/ && /home-manager-/" | xargs rm && popd
nix-collect-garbage --delete-old
nix store gc --debug
Sometimes if a file is opened in any process it refuses to clean it up, rebooting and cleaning again may help.
3. Cross Compilation
Cross compilation is as easy as to expose package in a flake output or apply an overlay on nixpkgs and then choose flake path to build.
# Custom Flake
nix build '.#packages.x86_64-linux.pkgsCross.mingwW64.my_pkg'
# Pkg from nixpkgs, or your package overlayed on nixpkgs
nix build 'nixpkgs#pkgsCross.mingwW64.my_pkg'
[TODO] Expand on this into an article as this is not very well shown in any article AFAIK.
4. Ephemeral shell-scoped install
Examples:
nix-shell -p hello
nix shell nixpkgs#hello
nix-shell -p 'python3.withPackages(pp: [ packages.numpy ])' --pure
nix develop --impure --expr 'with import <nixpkgs> {}; mkShell { buildInputs = [ python3.withPackages(pp: [ packages.numpy ]) ]; }'
Misc info:
nix-shell -p
andnix shell
are alike.nix-shell
andnix develop
are alike, with no argument former works withshell.nix
latter works withoutputs.devShells.default
definition inflake.nix
.- The
nix-shell
invokes stdenv, whereasnix shell
doesn't.
5. Pining flake inputs
Its good to have consistent system with single nixpkgs pin across all the commands, and to not garbage-collect any of the flake inputs, atleast until the profile is activated.
{ inputs, ... }: {
nix.registry.nixpkgs.flake = inputs.nixpkgs; # pin for new command syntax
home.sessionVariables.NIX_PATH = "nixpkgs=${inputs.nixpkgs}"; # pin for old-command syntax
# prevent 'all' the flake inputs from being garbage-collected until this profile is activated
xdg.configFile."nix-flake-inputs".text = lib.concatStringsSep "\n" (map (ip: ip.outPath) (lib.attrValues inputs));
}
Troubleshooting
Cleaning up
Refer nix#6141, if even after rebooting and garbage collection paths aren't removed.
The steps for force removal, in case a path is blocked by a (unlikely to be happen) bug.
nix-store --query --referrers $path | xargs nix-store --delete
nix-store --query --referrers-closure $path | xargs nix-store --delete
sudo nix store delete $path --ignore-liveness