Nix resources
This project is built entirely with Nix. If you are new to Nix — or find the ecosystem confusing — this page is the orientation. It also collects the external resources worth bookmarking.
Nix is not NixOS. Nix is a build tool and package manager that runs on Linux, macOS, and WSL. It builds packages reproducibly and manages dependencies without touching the rest of your system. NixOS is a Linux distribution that uses Nix as its system configuration layer. You do not need NixOS to use Nix, and you do not need NixOS to use this project.
What Nix actually is
Nix is three things layered on top of each other:
- A language. A purely functional, lazily evaluated expression language for describing how to build software. Every package is a function from inputs to outputs.
- A store.
/nix/store/— an immutable, content-addressed directory where every built output lives at a path derived from a cryptographic hash of everything that went into building it. - A package manager / build system. The
nixCLI that evaluates expressions, realises derivations, and manages the store.
Because every output path encodes its full dependency graph, two builds of the same derivation — on any machine — produce the same path and the same bits (given the same inputs). That is the property this project leans on for SLSA L3 attestation.
nixpkgs and NixOS
nixpkgs is the community package repository — a large Nix expression that
provides tens of thousands of packages and their build recipes. When a Nix
expression says nixpkgs#openssl, it is referring to a package defined in
nixpkgs.
NixOS is a Linux distribution that extends nixpkgs with a module system for whole-system configuration — services, users, file systems, and so on. NixOS modules are a nixpkgs concept, not a core-Nix concept. You can use nixpkgs (and therefore all its packages and build helpers) without ever running NixOS.
This project pins a specific revision of nixpkgs via flake.lock so that every
build uses the same exact package versions everywhere.
stdenv and build helpers
stdenv is nixpkgs’s standard build environment. It wraps the C toolchain,
make, bash, and a set of shell hooks into a baseline that most packages build
against. stdenv.mkDerivation is the lowest-level way to define a package build
in nixpkgs.
On top of stdenv, nixpkgs provides language-specific build helpers:
| Helper | What it builds |
|---|---|
buildGoModule | Go modules, vendoring go.sum |
buildRustPackage / craneLib | Rust crates with cargo |
bundlerEnv | Ruby gem environments |
buildPythonPackage | Python packages |
buildNpmPackage | Node / npm projects |
This project uses these helpers in pkgs/ to build individual GitLab service
binaries, and wraps the results in mkHardenedImage to produce OCI images.
Flakes
A flake is a directory with a flake.nix at the root. It declares:
inputs— other flakes or repositories this flake depends on.outputs— the packages, apps, devShells, checks, and NixOS modules this flake provides.
A flake.lock file pins every input to an exact revision and content hash.
This makes the whole dependency graph reproducible: anyone who checks out the
same commit and runs nix build gets the same store paths.
Flakes replaced the older nix-channel / nix-env workflow. They are now the
standard way to manage Nix projects.
Flakes, derivations, and source hashes: how they relate
The chain from a flake input to a built artifact involves three distinct reproducibility anchors.
Flake inputs (nixpkgs, other flakes, plain git repos) are pinned into
flake.lock — exact revisions and content hashes — for reproducibility.
flake.nix (declares inputs and outputs) and flake.lock together make up the
flake: a self-contained, reproducible project unit. The flake’s outputs are
Nix code: expressions and functions.
Evaluating that code produces a derivation (.drv) — the build recipe
describing what inputs are needed and what output path to produce.
A derivation’s inputs split into two kinds:
- Other derivations — build-time dependencies, chained recursively.
- Source projects, fetched and hash-verified — via
fetchurl,fetchGit, and similar. These are fixed-output derivations where the hash is the trust anchor, not the fetch method.
Hashes anchor trust at both layers: flake.lock pins the source revisions of
inputs, and fixed-output derivations pin the content hash of fetched
sources. Together they make the full build graph reproducible and auditable.
Learning resources
Official
- nix.dev tutorials — the recommended starting point. Covers the Nix language, derivations, the store, and flakes with worked examples.
- NixOS.org: Learn — the official hub for documentation, including the Nix manual, the nixpkgs manual, and NixOS options search.
Community
-
NixOS and Flakes Book — a well-structured community guide focused on the flakes workflow. Covers devShells, NixOS configuration, home-manager, and cross-compilation.
-
Nix Pills — a deep bottom-up walkthrough of how Nix works internally: the store, derivations, stdenv, and how nixpkgs is built up from first principles. Essential reading for understanding why things work the way they do, not just how to use them.
Reference
- Nix manual — language reference,
store semantics, and the
nixCLI. - nixpkgs manual — stdenv, build helpers, and how to write a derivation for your language.
- search.nixos.org — search every package in nixpkgs.