Caution
This workshop is currently under development and is not yet complete.
This workshop is structured in 2 parts
-
Part 1: Learn what a Nix DevShell is and how to extend it. It is designed to provide a minimal, hands-on introduction to how Nix works. While explanations are concise, they aim to be precise enough to help you grasp the objectives of this part.
- Gain a basic understanding of the Nix language.
- Learn what a
flake.nix
file is. - Understand what a Nix derivation is and how it materializes.
-
Part 2: Building and running a basic NixOS system.
- Requires Part 1.
- Configure and build a NixOS system.
- Deploy it to a cloud VM.
Tip
Due to the lack of well-structured and centralized official documentation on Nix topics, many external links to additional reading materials and videos are provided. Learning Nix can be challenging, but we prioritize linking to official documentation whenever relevant. Some useful resources include:
Ensure that you have installed
Nix
and
direnv
.
The basic requirements for working with this repository are:
just
nix
A NixOS derivation is created by a function inputs.nixpkgs.lib.nixosSystem
which comes from the Nixpkgs Flake. The
nixpkgs
repository is the mono-repository which maintains more than 130'000
software packages. These packages are defined - by nothing more than (you
guessed it) - Nix functions which return derivations.
The inputs.nixpkgs.lib.nixosSystem
function will produce a derivation which
you can evaluate. For example - in this repository's
flake.nix
- the attribute
nixosConfigurations.x86_64-linux.vm-simple
is such a function invocation and
to evaluate it you can run:
nix eval ".#nixosConfigurations.vm-simple.config.system.build.toplevel"
or you better build it with
nix build ".#nixosConfigurations.vm-simple.config.system.build.toplevel"
which will take some time and the resulting Nix store path linked by ./result
then contains the built OS:
tree -L 2 ./result
> ./result
> ├── activate
> ├── append-initrd-secrets -> /nix/store/ccyny0nr3a4dn5f864caj1nmvhkyz938-append-initrd-secrets/bin/append-initrd-secrets
> ├── bin
> │ └── switch-to-configuration
> ├── boot.json
> ├── configuration-name
> ├── dry-activate
> ├── etc -> /nix/store/34f7cw087r9js5c1f3snwra466p03rjv-etc/etc
> ├── extra-dependencies
> ├── firmware -> /nix/store/28a2j3qirvnzjrzwahgqpl6d83p4dibb-firmware/lib/firmware
> ├── init
> ├── init-interface-version
> ├── initrd -> /nix/store/rhk5xymxhaap08abmvy8fspcfm3ghyf1-initrd-linux-6.6.82/initrd
> ├── kernel -> /nix/store/7c8qjbmxyyyscapv46cprwg3h1i0ry8b-linux-6.6.82/bzImage
> ├── kernel-modules -> /nix/store/5r9yn7mgianbqlqdn649k647v7zn6k9w-linux-6.6.82-modules
> ├── kernel-params
> ├── nixos-version
> ├── specialisation
> ├── sw -> /nix/store/v71rhhllsl7av7nrkzb58snsb2c7fal1-system-path
> ├── system
> └── systemd -> /nix/store/w9qcpyhjrxsqrps91wkz8r4mqvg9zrxc-systemd-256.10
The above (to my best knowledge) in simple terms contains everything needed to
boot into this NixOS system. An
activation script activate
prepares symlinks into the immutable /nix/store
on folders like
/boot
(kernel and bootloader),/etc
(system configuration files), -/var
(variable data) ,/run
(ephemeral runtime data),/home
(home directories)- etc.
switch-to-configuration
script also takes care to switch to the new system on a running system and
restart the appropriate systemd
services.
The next section explains how to build/run & understand a simple NixOS VM setup.
First familiar yourself with the commands on the justfile
with
by running just
. The build
and repl
commands, we have covered in the
introduction.
In this example we are going to build a simple VM with just a user nixos
and
without a graphical desktop environment.
cp ./.env.tmpl .env
## Modify the .env file to have `NIXOS_HOST=vm-simple`
The ./nixos/hosts/vm-simple/default.nix
contains one function which returns the NixOS system:
{ inputs, outputs, ... }:
inputs.nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./hosts/vm/configuration.nix
];
specialArgs = {
inherit inputs outputs;
};
}
The function call inputs.nixpkgs.lib.nixosSystem {...}
is a function defined
in nixpgs
which will generate a Nix
derivation.
When we instruct Nix to build this derivation, the derivation gets realized in
the Nix store (e.g. in /nix/store
).