A functional GNU/Linux distro
Robert Helgesson <robert@rycee.net>
Backend programmer
Nix user and contributor since ~2014
The Nix package manager
The Nix expression language
The NixOS GNU/Linux distribution
Demo
A purely functional package manager
Set of files in a file hierarchy
Built using a build recipe, e.g.
source code
other packages it depends on
build instructions
etc.
Once built a package never changes
Nix treats building a package as a function
build : recipe → package
and building a recipe always gives the same result
Allows identifying a package by hashing its recipe!
Built Nix packages are kept in the Nix store
Key is the hashed recipe
Value is the built recipe
/nix/store/mkk5m2kflfrc5w5pl50f88rhdj9vwsdf-cowsay-3.03
├── bin
│ ├── cowsay
│ └── cowthink -> cowsay
└── share
├── cows
│ ├── beavis.zen.cow
┆ ┆
│ └── www.cow
└── man
└── man1
├── cowsay.1.gz
└── cowthink.1.gz -> cowsay.1.gz
$ /nix/store/mkk5…-cowsay-3.03/bin/cowsay 'Hello, BornHack!'
__________________
< Hello, BornHack! >
------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
$ find /nix/store -maxdepth 1 -name '*-cowsay-3.03'
/nix/store/igk92axpn6gdj232j802sdsc1fm8nj25-cowsay-3.03
/nix/store/mkk5m2kflfrc5w5pl50f88rhdj9vwsdf-cowsay-3.03
/nix/store/cd4i6g0h3ns4xqg1ac4mnhzigcnzy7cm-cowsay-3.03
/nix/store/mhfaj4miflqz1abn60nnkrpaxcg310i9-cowsay-3.03
Non-privileged users can install packages accessible in only their $PATH
[simon:~]$ nix-env -f '<nixpkgs>' -iA cowsay
…
[simon:~]$ which cowsay
/home/simon/.nix-profile/bin/cowsay
[simon:~]$ readlink $(which cowsay)
/nix/store/mkk5…wsdf-cowsay-3.03/bin/cowsay
[jane:~]$ which cowsay
which: no cowsay in (…:/home/jane/.nix-profile/bin:…)
Install
$ nix-env -f '<nixpkgs>' -iA cowsay
Uninstall
$ nix-env -e cowsay
Used, for example, to describe Nix packages
A pure, lazy, functional language
{ stdenv, fetchurl, pkgconfig, libav, libxslt }:
stdenv.mkDerivation rec {
name = "unpaper-6.1";
src = fetchurl {
url = "https://www.flameeyes.eu/files/${name}.tar.xz";
sha256 = "0c5rbkxbmy9k8vxjh4cv0bgnqd3wqc99yzw215vkyjslvbsq8z13";
};
nativeBuildInputs = [ pkgconfig ];
buildInputs = [ libav libxslt ];
meta = {
homepage = "https://www.flameeyes.eu/projects/unpaper";
description = "Post-processing tool for scanned sheets of paper";
license = stdenv.lib.licenses.gpl2;
maintainers = [ stdenv.lib.maintainers.rycee ];
};
}
A GNU/Linux distribution built on Nix
Describe system using the Nix expression language
Create build recipe that builds the system files
$ cat /nix/store/i5si…20jx-sysconf/etc/fstab
/dev/sda2 / btrfs defaults 0 0
/dev/sda1 /boot ext2 defaults 0 2
$ cat /nix/store/i5si…20jx-sysconf/etc/hosts
127.0.0.1 localhost
192.36.125.18 ping.sunet.se ping
Create a boot loader entry that populates /etc
when loading the OS
/etc/fstab ⟶ /nix/store/i5si…20jx-sysconf/etc/fstab
/etc/hosts ⟶ /nix/store/i5si…20jx-sysconf/etc/hosts
⋮
Reboot and hope it works
If it didn’t, tell GRUB to boot the old configuration
🤯
after nixos-rebuild switch
:
$ which cowsay
/run/current-system/sw/bin/cowsay
$ which tree
/run/current-system/sw/bin/tree
after nixos-rebuild switch
:
$ type hello
hello is aliased to `cowsay Hello, Bornhack!'
$ redis-cli
127.0.0.1:6379> CONFIG GET databases
1) "databases"
2) "8"
127.0.0.1:6379> CONFIG GET maxclients
1) "maxclients"
2) "500"
man pages
$ man configuration.nix
HTML
$ nixos-help
A project directory can contain a file default.nix
with build instructions. Inside the directory run
nix-build
to build the project
nix-shell
to open a shell with all build dependencies
Deployments
Declarative configuration language
Reproducible
Atomicity
Fearless upgrades thanks to rollback
Steep learning curve
Tricky to package software that assumes a “standard system”
Relatively small user base
Proceed with caution
“NixOS for $HOME
”
programs.msmtp.enable = true;
programs.mbsync.enable = true;
accounts.email.accounts.test-account = {
primary = true;
address = "john.doe@example.org";
userName = "john.doe";
realName = "John Doe";
passwordCommand = "getpass john.doe@example.org";
imap.host = "imap.example.org";
smtp.host = "smtp.example.org";
msmtp.enable = true;
mbsync.enable = true;
};