Self-host your own digital island
1
2# Nix
3
4Nix is a software deployment system that uses cryptographic hashes to compute unique paths for components (i.e., packages) that are stored in a read-only directory: the Nix store, at `/nix/store/<hash>-<name>`.
5This provides several benefits, including concurrent installation of multiple versions of a package, atomic upgrades, and multiple user environments.
6
7Nix uses a declarative domain-specific language (DSL), also called Nix, to build and configure software.
8The Nix DSL is a functional language with a syntax Turing complete but lacks a type system.
9We use the DSL to write derivations for software, which describe how to build said software with input components and a build script.
10This Nix expression is then 'instantiated' to create 'store derivations' (`.drv` files), which is the low-level representation of how to build a single component.
11This store derivation is 'realised' into a built artefact, hereafter referred to as 'building'.
12
13Possibly the simplest Nix derivation uses `bash` to create a single file containing `Hello, World!`:
14```nix
15{ pkgs ? import <nixpkgs> { } }:
16
17builtins.derivation {
18 name = "hello";
19 system = builtins.currentSystem;
20 builder = "${nixpkgs.bash}/bin/bash";
21 args = [ "-c" ''echo "Hello, World!" > $out'' ];
22}
23```
24Note that `derivation` is a function that we're calling with one argument, which is a set of attributes.
25
26We can instantiate this Nix derivation to create a store derivation:
27```
28$ nix-instantiate default.nix
29/nix/store/5d4il3h1q4cw08l6fnk4j04a19dsv71k-hello.drv
30$ nix show-derivation /nix/store/5d4il3h1q4cw08l6fnk4j04a19dsv71k-hello.drv
31{
32 "/nix/store/5d4il3h1q4cw08l6fnk4j04a19dsv71k-hello.drv": {
33 "outputs": {
34 "out": {
35 "path": "/nix/store/4v1dx6qaamakjy5jzii6lcmfiks57mhl-hello"
36 }
37 },
38 "inputSrcs": [],
39 "inputDrvs": {
40 "/nix/store/mnyhjzyk43raa3f44pn77aif738prd2m-bash-5.1-p16.drv": [
41 "out"
42 ]
43 },
44 "system": "x86_64-linux",
45 "builder": "/nix/store/2r9n7fz1rxq088j6mi5s7izxdria6d5f-bash-5.1-p16/bin/bash",
46 "args": [ "-c", "echo \"Hello, World!\" > $out" ],
47 "env": {
48 "builder": "/nix/store/2r9n7fz1rxq088j6mi5s7izxdria6d5f-bash-5.1-p16/bin/bash",
49 "name": "hello",
50 "out": "/nix/store/4v1dx6qaamakjy5jzii6lcmfiks57mhl-hello",
51 "system": "x86_64-linux"
52 }
53 }
54}
55```
56
57And build the store derivation:
58```sh
59$ nix-store --realise /nix/store/5d4il3h1q4cw08l6fnk4j04a19dsv71k-hello.drv
60/nix/store/4v1dx6qaamakjy5jzii6lcmfiks57mhl-hello
61$ cat /nix/store/4v1dx6qaamakjy5jzii6lcmfiks57mhl-hello
62Hello, World!
63```
64
65Most Nix tooling does these two steps together:
66```
67nix-build default.nix
68this derivation will be built:
69 /nix/store/q5hg3vqby8a9c8pchhjal3la9n7g1m0z-hello.drv
70building '/nix/store/q5hg3vqby8a9c8pchhjal3la9n7g1m0z-hello.drv'...
71/nix/store/zyrki2hd49am36jwcyjh3xvxvn5j5wml-hello
72```
73
74Nix realisations (hereafter referred to as 'builds') are done in isolation to ensure reproducibility.
75Projects often rely on interacting with package managers to make sure all dependencies are available and may implicitly rely on system configuration at build time.
76To prevent this, every Nix derivation is built in isolation (without network access or access to the global file system) with only other Nix derivations as inputs.
77
78> The name Nix is derived from the Dutch word *niks*, meaning nothing; build actions do not see anything that has not been explicitly declared as an input.
79
80For more information, see:
81- The Nix paper: https://edolstra.github.io/pubs/nspfssd-lisa2004-final.pdf
82- The Nix PhD thesis: https://edolstra.github.io/pubs/phd-thesis.pdf
83