nix
a quick intro
Problem
What we need
- make builds exactly the same every time
- run the builds with deps it needs
- replicate it on other machines
We need the ability to...
Solution we have...
- installs deps in isolation
- easy to reproduce env
- easy to replicate
the goods about it...
Solutions we have...
- it is too isolated
- layered architecture
easy to reproduce env- image contains unwanted stuff
- no concept of multiple image inheritance
the bads about it...
lets discuss
FROM node:16.16.0-slim
RUN node -v
# but i need `python` as well...
...but one year later
debian decided to replace python 2.7 with 3.11... 😬
its not so reproducible after all
FROM node:16.16.0-slim
RUN node -v
RUN apt update && apt install -y python
RUN python --version
# good, i got `python` now!
unwanted stuff can caused bigger images
FROM node:16.16.0-slim
RUN node -v
RUN apt update && apt install -y python git
RUN python --version
RUN git -v
# good, i got `python` and `git` now!
# but hey, why do i have `ssh`?
RUN ssh
wouldn't it be nice if I could do this instead?
FROM node:16.16.0, python:2.7, git:x.y.z
RUN node -v
RUN python --version
RUN git -v
nix
presenting you...
A build tool, package manager, and programming language
Software is a graph of dependencies.
Normally, this graph is implicit.
Nix makes is explicit.
Nix Store
Derivations
Sandbox
Language
Nix Store
/nix/store graph /nix/store/* immutable nodes
Sample Node
/nix/store/4qnmjqc4z7wc058bj79gc2ppbs1dj1cx-nodejs-18.12.1
Derivations
- Special entry in Nix Store
- Describes how to build other entries in Nix Store
$ cat /nix/store/ynzfmamryf61rybjy1zqp1x19015yiy5-demo.drv <-- note .drv
Derive([("out","/nix/store/76gxh82dqh6gcppm58ppbsi0h5hahj07-demo","","")],
[],[],"x86_64-darwin","/bin/sh",["-c","echo 'hello world'" > $out"],
[("builder","/nix/store/5arhyyfgnfs01n1cgaf7s82ckzys3vbg-bash-4.4-p23/bin/bash"),
("name","demo"),("out","/nix/store/76gxh82dqh6gcppm58ppbsi0h5hahj07-demo"),
("system","x86_64-darwin")])
All inputs/outputs are mentioned in a Derivation
Derivations
$ cat /nix/store/ynzfmamryf61rybjy1zqp1x19015yiy5-demo.drv
Derive(
### outputs
[
("out","/nix/store/76gxh82dqh6gcppm58ppbsi0h5hahj07-demo","","")
],
### inputDrvs
[],
### inputSrcs
[],
### platform
"x86_64-darwin",
### builder
"/bin/sh",
### args
["-c","echo 'hello world'" > $out"],
### env
[
("builder","/nix/store/5arhyyfgnfs01n1cgaf7s82ckzys3vbg-bash-4.4-p23/bin/bash"),
("name","demo"),
("out","/nix/store/76gxh82dqh6gcppm58ppbsi0h5hahj07-demo"),
("system","x86_64-darwin")
]
)
Derivations
$ nix-build /nix/store/ynzfmamryf61rybjy1zqp1x19015yiy5-demo.drv
/nix/store/76gxh82dqh6gcppm58ppbsi0h5hahj07-demo
$ cat /nix/store/76gxh82dqh6gcppm58ppbsi0h5hahj07-demo
hello world
Sandbox
Content from Derivation:
- outputs
- inputDrvs
- inputSrcs
- platform
- builder
- args
- env
Anything that is needed to build, must be explicit
and must come from Nix Store!
Sandbox
Things either work
everywhere and always
or
nowhere and never
Language
- lazy
- pure
- functional
let
data = {
a = 1;
b = functionThatTakesNMinutesToRun 3;
};
in data.a => 1 (instantly)
Language
Use of Nix Language
- Setup development environments
- Create Derivations
derivation {
name = "demo";
builder = "${bash}/bin/bash";
args = [ "-c" "echo neat > $out" ];
system = "x86_64-darwin";
}
# creates /nix/store/ynzfmamryf61rybjy1zqp1x19015yiy5-demo.drv
It won't replace
Docker 🙈
but can make the two, better together
Questions?
nix
By Ali Yousuf
nix
- 70