NixOS Immutable Linux

Linux
Published

March 21, 2020

Modified

March 14, 2024

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…

NixOS

Use-cases…

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 /nix

Nix Portable …Nix as a single binary…

  • …permission-less …lives in $HOME/.nix-portable
  • …installation-free …extracting archive on the release page
  • …pre-configured …enable flakes and nix-command out 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 switch

Upgrade…

# ...upgrade NixOS to the latest version
sudo nixos-rebuild switch --upgrade

nix.conf

Nix configuration…

  • /etc/nix/nix.conf …system defaults …modified with configuration.nix
  • $HOME/.config/nix/nix.conf for users
  • $NIX_CONFIG overwrite 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/

  • stable conservative updates
    • only bug fixes and security patches
    • release every six month
  • unstable latest updates, rolling basis
~/.nix-channels           # configuration
nix-channel --list        # current channel

To 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 /lib or /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
           `------------------------------`------------- hash

Graph

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-roots

Derivations

  • 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
  • Derivation definition includes
    • outputs - What nodes can this build
    • inputDrvs - Other derivation that must be build before
    • inputSrcs - Nodes already in the store on which this build depends
    • platform - build platform
    • builder - program to run for the build
    • args - program argument list
    • env - 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.drv

Any 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 switch

profile

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-history

Multiple profiles…

nix profile --profile ~/.another-profile install nixpkgs#git

nix-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 variable
    • nix-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.nix

Nix 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 *.nix is 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; }   # set

Functions…

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 let keyword
let x = 1; in x + x; # 2
let x = "abc"; y = "xyz"; in x + y; # "abcxyz"

References

Media…