# Show & Tell: Nix und NixOS
###### tags: `Show & Tell`
---
> Nix is a powerful package manager for Linux and other Unix systems that makes package management reliable and reproducible. It provides atomic upgrades and rollbacks, side-by-side installation of multiple versions of a package, multi-user package management and easy setup of build environments.
---
> NixOS is a Linux distribution with a unique approach to package and configuration management. Built on top of the Nix package manager.
---
## Packet-Management und Abhängigkeiten
Abhängigkeiten sind (aus sicht der Entwickler) ein transitiver gerichtet azyklischer Graph
----
## Das Hier und Jetzt
* `apt`, `rpm`, `pacman` verändern den globalen Status des Systems
* Updates passieren in-place
* Nur eine Version von Software (Danke, dynamisches Linking)
* Bei laufender Anwendung greift manchmal File-Handle-Trick - aber nicht immer
* Kein Management für Konfiguration, Assets, Umgebung
----
### Nein, Docker ist nicht dis Lösung
Layer helfen nur bedingt weiter:
* Layer sind viel größer als Paket-Abhängigkeiten
* Keine funktionierende Versionierung
* Docker-File ist zu generisch für Packaging
---
## *Nix* - Die tolle neue Welt
Der Nix-Store enthält alle installierten Packete (aka Derivations)
----
## *Nix* - Die tolle neue Welt
* `/nix/store/${hash}-${name}`
* Der Hash entsteht aus der Definition des Packets plus seiner Abhängigkeiten
* > `which bash`
* > `ldd $(which bash)`
----
## *Nix* - Die tolle neue Welt
* Der Nix-Store ist read-only
* Wenn sich eine Abhängigkeit ändert, ändert sich auch das Packet
---
## `nix` - die Sprache
Nix ist voll funktional, stark typisiert, lazy
* `nix repl` zum testen von Ausdrücken
----
## `nix` - die Sprache
* Funktionen und imports
```
myfunc = name: { foo, bar }: ...
import ./lib.nix
```
----
## `nix` - die Sprache
* Nativer support für Pfade
```
/etc + /nixos + "/store"
```
----
## `nix` - die Sprache
* Multiline-Strings und Templating
```
builtins.toFile hello \'\'
#!${pkgs.bash}/bin/bash
echo "Hello, World!"
\'\'
```
----
## `nix` - die Sprache
Und natürlich Listen, Maps und den ganzen Kram...
----
## `nix` - eine eigene Sprache
```
let
lib = import ./lib.nix;
pkgs = import (builtins.fetchTarball
(with import ./nixpkgs.nix; {
url = "https://github.com/${owner}/${repo}/archive/${rev}.tar.gz";
})) {};
buildMachine = name: { config, pkgs, ...} :
let
machine = "${name}";
machinePath = lib.path machine;
machineConfig = lib.config machine;
in {
deployment = {
targetHost = machineConfig.target.host;
targetUser = machineConfig.target.user;
};
imports = [
./common.nix
machinePath
];
};
in
builtins.listToAttrs (builtins.map
(name: { name = name; value = buildMachine name; })
(builtins.attrNames (builtins.readDir ./machines))
)
```
---
## NixOS (und nixpkgs)
* nixpkgs ist eine Sammlung von Packeten
* https://github.com/NixOS/nixpkgs
* nixos ist das Betriebssystem und ein paar (viele) Funktionen in nixpkgs
---
## Aber was soll das ganze jetzt?
* Alle Derivations (Resource, Config, Pakete) liegt im Nix-Store und ist versioniert
* Das aktuelle Profile (aka das laufende System) ist auch "nur" eine Derivation
* `nixos-rebuild switch` baut neues Profile
* `nixos-rebuild --rolback switch` wechselt wieder zurück
----
## Aber was soll das ganze jetzt?
> `nixos-rebuild build && ls -l ./result`
---
## Genug Schabernack
* Packet installieren
* SSHd aktivieren
---
## Saltstack / Ansible / Puppet adé
* Dinge werden wieder sauber entfernt
* Derivations kann man überall bauen und Abhängikeiten passen trotzdem
* Push-Deployments mit `nix-copy-closure`
* Verteilung auf Builder möglich
* `morph` macht das einfach
---
![](https://imgs.xkcd.com/comics/college_athletes.png)