NixOS Immutable Linux
Nix projects disambiguation…
| Project | Description |
|---|---|
| Nix (language) | Pure, lazy, functional declarative language used to express the composition declarations… |
| Nix (Package Manager) | Purely functional package manager …builds without side-effects (reproducible) |
| Nixpkgs | Standard package library for Nix …official definitions of a wide variety of software |
| NixOS | Linux distribution which is built upon the Nix package manager |
Nix language… just an executable…
- …~20MB program written in C++
- …programming language
- …package manager
- …method to compile software from source
- Nixpkgs…
- …a repository on GitHub
- …collection of Nix package derivations
- …90.000 plus reproducible software packages
- …uses Nix language and package manager
- …build from Nixpkgs collection
- …completely declerative
- …atomic system update …with rollback
- …configuration in a single file
/etc/nixos/configuration.nix - References…
- Package search nixos.org/packages
Use-cases…
- …reproducibility
- …software supply chain security
- …software bill of material (SBOM)
- …infrastructure as code
Install
Download NixOS and use the installer
Single user installation on any Linux distribution…
sudo mkdir /nix
sudo chown $USER:$USER /nix
sh <(curl -L https://nixos.org/nix/install) --no-daemon
source ~/.nix-profile/etc/profile.d/nix.sh
# unsinstall
rm -rf /nixNix Portable …Nix as a single binary…
- …permission-less …lives in
$HOME/.nix-portable - …installation-free …extracting archive on the release page
- …pre-configured …enable
flakesandnix-commandout of the box
Configuration
System configuration…
- …
/etc/nixos/configuration.nix - …NixOS manual configuration section
# ...build the new configuration, make it the default
sudo nixos-rebuild switchUpgrade…
# ...upgrade NixOS to the latest version
sudo nixos-rebuild switch --upgradenix.conf
Nix configuration…
/etc/nix/nix.conf…system defaults …modified withconfiguration.nix$HOME/.config/nix/nix.conffor users$NIX_CONFIGoverwrite by environment variable
Documentation in the Nix Reference Manual
nix-channels
nixpkgs …global default package repository
- …one big Nix expression including derivations
- …each package is a derivation
- …package dependencies recursive derivation calls
Manage channels (unstable by default) with nix-channel:
https://nixos.wiki/wiki/Nix_channels
https://nixos.org/manual/nix/stable/#sec-channels
- A “channel” is a name for the latest “verified” git commits in Nixpkgs.
- Channel user will benefit from both verified commits and binary packages from the binary cache.
https://nixos.org/channels/
https://status.nixos.org/
https://channels.nix.gsc.io/
stableconservative updates- only bug fixes and security patches
- release every six month
unstablelatest updates, rolling basis
~/.nix-channels # configuration
nix-channel --list # current channelTo update the channel run:
nix-channel --update
nix-env -u # upgrade all packages in the environment- Downloads the new Nix expressions (descriptions of the packages)
- Creates a new generation of the channels profile and unpack it under
~/.nix-defexpr/channels
Nix Store
Software is a graph of dependencies:
- …graphs typically implicit
- …Nix makes package graph explicit
/nix/store # (directed acyclic) graph (database)
/nix/store/* # nodes (immutable)- …(obviously) does not comply the Linux filesystem hierarchy standard (FHS)
- …packages can not conflict with one another
- …no package files across global directories like
/libor/usr/lib - …multiple versions of package coexist
Nodes
Nodes include references to paths in other nodes (edges).
- …each node is prefixed by a (unique) hash
- …for a given hash its contents is always identical across machines/platforms
- …can’t be modified after creation (immutable)
/nix/store/gv4rgr1p1dq5s4hx7ald6a7kli6p3xrz-firefox-85.0
| | |
| | `----------- name
`------------------------------`------------- hashGraph
Query the nix store like a graph database:
# list run-time dependencies for derivation (i.e. Firefox)
nix-store --query --references $(which firefox)
# ^ recursive as tree
nix-store --query --tree $(which firefox)
# plot a graph
nix-store --query --graph $(which firefox) | dot -Tsvg
# save space by hardlinking store files
nix-store --optimise
# clean up storage
nix-store --gc
# see which result files prevent garbage collection
nix-store --gc --print-rootsDerivations
- Derivations recipe how to build other paths in the Nix store
- Special entries in the nix store
/nix/store/*.drv - Includes references to all dependency nodes
- Creates one or more entries in the Nix Store
- Special entries in the nix store
- Derivation definition includes
outputs- What nodes can this buildinputDrvs- Other derivation that must be build beforeinputSrcs- Nodes already in the store on which this build dependsplatform- build platformbuilder- program to run for the buildargs- program argument listenv- build environment
- Only contents referenced in the derivation available during build
- No implicit dependencies possible
- All dependencies made explicit
- All dependencies codified in the output hash
- Nothing is machine dependent (good for binary caching)
Build a derivation with nix-build:
nix-build /nix/store/lzha201i0b0d52rjxqlxbrximwf9bjiv-firefox-85.0.drvAny software build/install can be a binary download with no other prerequisites except the nix platform.
nix
Nix package manager…
- …similar to projects like
rpmtree(used in Fedora Silverblue)
Needs to be enabled as experimental feature…
# ...for a user-space installation
>>> cat ~/.config/nix/nix.conf
experimental-features = nix-command flakes
# on a NixOS host-system
>>> cat /etc/nixos/configuration.nix
#...
nix.settings.experimental-features = "nix-command flakes"
#...
>>> sudo nixos-rebuld switchprofile
Manage nix profiles…
- …user default profile to
~/.nix-profile - …links to packages in the Nix store
# ...install a package into the default profile...
nix profile install nixpkgs#neovim nixpkgs#fzf nixpkgs#jq
# ...list installed packages
nix profile list
# ...upgrade all packages
nix profile upgrade '.*'Rollback package management commands…
# ...list versions
nix profile history
# ...back to previous version
nix profile rollback
nix profile rollback --to $version
# ...remove past versions of a profile
nix profile wipe-historyMultiple profiles…
nix profile --profile ~/.another-profile install nixpkgs#gitsearch
nix search …packages
nix search # flake in current cirectory
nix search nixpkgs # all available packages
nix search nixpkgs $name # specific packagenix-env
Nix user environments…
- …synthesised view to the Nix store
- …sets of packages available to a user
- …different users have different environments
- …individual users can switch between different environments
~/.nix-profile…default user profiles$NIX_PROFILE…overwrite by environment variablenix-env -S ~/my-profile…switch profile
Install and remove packages…
nix-env -q # list installed derivations
nix-env -q --out-path # ^ with absolute path
nix-env -qa 'name.*' # list available packages
nix-env -i $name # install package
nix-env -e $name # un-install package
nix-env -u # upgrade packages…rollback facilities rely on generations
nix-env --rollback
nix-env --list-generations
nix-env --switch-generation Install multiple packages…
cat > /tmp/packages.nix <<EOF
with import <nixpkgs>{};
[ htop moreutils ]
EOF
nix-env -if /tmp/packages.nixNix Language
- Very limited functionality except of executing derivations
- Lazy evaluated
- (Almost) free of side-effects
- no networking
- no user input
- no file writing
- no output (except traces)
- Builds done by other Nix tooling
A piece of Nix language code is a Nix expression…
- …evaluating a Nix expression produces a Nix value
- …content of a Nix file
*.nixis a Nix expression
nix repl …start interactive interpreter for testing
Data types…
1 # numbers
"a" # strings
[ "a" "b" ] # lists
./README.md # path literal (presence of / forward slash character)
{ a = 1; b = 2; } # setFunctions…
x = arg: { a = arg; }
x = { arg1, arg2 }: {a = arg1; b = arg2; }let expression …create a binding…
- …
;terminator …set definition - …values only available for a single expression after the
letkeyword
let x = 1; in x + x; # 2
let x = "abc"; y = "xyz"; in x + y; # "abcxyz"References
Media…
- What Nix Can Do, Matthew Croughan, SCaLE20x, 2023