This is a demo NixOS config, with optional flakes support. Along with notes on why flakes is useful and worth adopting.
Nix
180
24 commits
updated May 31, 2021
WARNING: You should understand that:
there is currently no path to flakes being stable
we can't even experiment with flakes alternatives without committing to pure-eval as a stepping stone
the people that CARE about the problems solved by flakes seem to care about solving this problem
the people using impurity everywhere don't seem very motivated to dive into this problem-space
as a result, the tooling is completely fractured and stagnant
besides some UX fixes, bugfixes, and other feature-work in Nix, this has more or less been the case for years
I'm tired of seeing (often self-proclaimed, repeated-from-others) FUD by non-flakes users
Anyway, now you know. Proceed at your own caution.
NOTE: nixflk is a better example repo for a full NixOS config layout, this repo is mostly to provide more context+examples around flakes, and to show that you can produce the same EXACT system with flakes as with nix-build, if you know what to do.
This readme starts out with an attempt to explain and justify flakes. It also contains
some examples of nix cli flakes syntax and tips for adopting flakes in your project.
Finally, at the end of the readme
is an example NixOS config with a supporting flake.nix,
and instructions to build it with and without flakes support at the same time.
Flakes is a few things:
flake.nix: a Nix file, with a specific structure to describe inputs and outputs for a Nix project
flake.lock: a manifest that "locks" inputs and records the exact versions in useThis ultimately enables:
This removes the need for:
niv or other tooling to lock dependenciesNIX_PATH is set consistently for your teamnix and nix-daemonboot.isContainer = true; on configuration.nix (as the article suggests) if you want to use nixos-rebuild rather than nixos-containerNix is in flakes mode when:
--flake is used with the nixos-rebuild commandnix build is used with an argument like '.#something' (the hash symbol separates the flake source from the attribute to build)When in this mode:
flake.nix insidenix build '.#something', the . means current directory, and #something means to build the something output attributenixos-rebuild build --flake '.#'
flake.nix in . (current dir)nixos-rebuild, it automatically tries to build:
#nixosConfigurations.{hostname}.config.system.build.toplevelnixos-rebuild build --flake '/code/nixos-config#mysystem'
flake.nix in /code/nixos-confignixos-rebuild, it automatically tries to build:
#nixosConfigurations.mysystem.config.system.build.toplevelmysystem config)nix build 'github:colemickens/nixpkgs-wayland#obs-studio'
flake.nix in (a checkout of github.com/colemickens/nixpkgs-wayland)#obs-studio#packages.{currentSystem}.obs-studionix flake update --recreate-lock-file
flake.locknix flake update --update-input nixpkgs
flake.lockNix CLI will try to be ... smart and auto-coerce some output attribute paths for you.
nix build '/some/path#obs-studio':
/some/path#obs-studio/some/path#packages.x86_64-linux.obs-studio/some/path#legacyPackages.x86_64-linux.obs-studioRemove Impurities - Since nix flakes does a 'pure' build by default,
NIX_PATH is ignored<nixpkgs> imports do not work, and explicitly error~/.config/{nix,nixpkgs}) are ignorefetchTarball without a pinned rev+sha256) are forbiddenTo fix these:
flake.nix instead of using fetchTarball
nixpkgs-wayland.getFlake vs passing inputs in specialArgsConsider the nixos configuration in this repo:
These represent an example, minimal NixOS system configuration.
The easiest way to build it, without cloning this repo:
nix build 'github:colemickens/nixos-flake-example#nixosConfigurations.mysystem.config.system.build.toplevel'
Let's prove that we can build this config, with and without flakes:
Using nixos-rebuild:
# with flakes
unset NIX_PATH
nixos-rebuild build --flake '.#mysystem'
readlink -f ./result
/nix/store/gg1jhmzqndqa0rfnwfdbnzrn8f74ckr6-nixos-system-mysystem-21.03pre-git
# !! for this next step, match the git SHA1 to what the flake.lock uses
# otherwise you'll have a hash mismatch due to different nixpkgs
# without flakes
export NIX_PATH=nixpkgs=https://github.com/nixos/nixpkgs/archive/007126eef72271480cb7670e19e501a1ad2c1ff2.tar.gz:nixos-config=/home/cole/code/nixos-flake-example/configuration.nix
nixos-rebuild build
readlink -f ./result
/nix/store/gg1jhmzqndqa0rfnwfdbnzrn8f74ckr6-nixos-system-mysystem-21.03pre-git
Using nix build:
# with flakes
unset NIX_PATH
nix build '.#nixosConfigurations.mysystem.config.system.build.toplevel
readlink -f ./result
/nix/store/gg1jhmzqndqa0rfnwfdbnzrn8f74ckr6-nixos-system-mysystem-21.03pre-git
# without flakes
export NIX_PATH=nixpkgs=https://github.com/nixos/nixpkgs/archive/007126eef72271480cb7670e19e501a1ad2c1ff2.tar.gz:nixos-config=/home/cole/code/nixos-flake-example/configuration.nix
nix-build '<nixos/nixpkgs>' -A config.system.build.toplevel
readlink -f ./result
/nix/store/gg1jhmzqndqa0rfnwfdbnzrn8f74ckr6-nixos-system-mysystem-21.03pre-git
The ./check.sh script automates this process:
cole@slynux ~/code/nixos-flake-example master* 7s
❯ ./check.sh
:: Updating the 'nixpkgs' input in flake.nix
+ nix flake update --update-input nixpkgs
+ set +x
:: Using 'nixos-rebuild' to build the 'mysystem' toplevel
+ nixos-rebuild build --flake '.#mysystem'
warning: Git tree '/home/cole/code/nixos-flake-example' is dirty
building the system configuration...
warning: Git tree '/home/cole/code/nixos-flake-example' is dirty
+ set +x
:: Using rev=007126eef72271480cb7670e19e501a1ad2c1ff2 for <nixpkgs> (extracted from flake.nix)
:: Setting NIX_PATH to the same values flakes is using
+ NIX_PATH=nixpkgs=https://github.com/nixos/nixpkgs/archive/007126eef72271480cb7670e19e501a1ad2c1ff2.tar.gz:nixos-config=/home/cole/code/nixos-flake-example/configuration.nix
+ nix-build '<nixpkgs/nixos>' -A config.system.build.toplevel
/nix/store/gg1jhmzqndqa0rfnwfdbnzrn8f74ckr6-nixos-system-mysystem-21.03pre-git
+ set +x
flake: /nix/store/gg1jhmzqndqa0rfnwfdbnzrn8f74ckr6-nixos-system-mysystem-21.03pre-git
clssc: /nix/store/gg1jhmzqndqa0rfnwfdbnzrn8f74ckr6-nixos-system-mysystem-21.03pre-git
Is the hash tag syntax really worth it?
nix build 'github:colemickens/nixpkgs-wayland#obs-studio'nix build --flake 'github:colemickens/nixpkgs-wayland' 'obs-studio' ?Are the auto-coercion rules for attribute paths worth it? They definitely add some mental overhead...
Nix
63.8%
Shell
36.2%
This is a demo NixOS config, with optional flakes support. Along with notes on why flakes is useful and worth adopting.
Nix
180
24 commits
updated May 31, 2021
WARNING: You should understand that:
there is currently no path to flakes being stable
we can't even experiment with flakes alternatives without committing to pure-eval as a stepping stone
the people that CARE about the problems solved by flakes seem to care about solving this problem
the people using impurity everywhere don't seem very motivated to dive into this problem-space
as a result, the tooling is completely fractured and stagnant
besides some UX fixes, bugfixes, and other feature-work in Nix, this has more or less been the case for years
I'm tired of seeing (often self-proclaimed, repeated-from-others) FUD by non-flakes users
Anyway, now you know. Proceed at your own caution.
NOTE: nixflk is a better example repo for a full NixOS config layout, this repo is mostly to provide more context+examples around flakes, and to show that you can produce the same EXACT system with flakes as with nix-build, if you know what to do.
This readme starts out with an attempt to explain and justify flakes. It also contains
some examples of nix cli flakes syntax and tips for adopting flakes in your project.
Finally, at the end of the readme
is an example NixOS config with a supporting flake.nix,
and instructions to build it with and without flakes support at the same time.
Flakes is a few things:
flake.nix: a Nix file, with a specific structure to describe inputs and outputs for a Nix project
flake.lock: a manifest that "locks" inputs and records the exact versions in useThis ultimately enables:
This removes the need for:
niv or other tooling to lock dependenciesNIX_PATH is set consistently for your teamnix and nix-daemonboot.isContainer = true; on configuration.nix (as the article suggests) if you want to use nixos-rebuild rather than nixos-containerNix is in flakes mode when:
--flake is used with the nixos-rebuild commandnix build is used with an argument like '.#something' (the hash symbol separates the flake source from the attribute to build)When in this mode:
flake.nix insidenix build '.#something', the . means current directory, and #something means to build the something output attributenixos-rebuild build --flake '.#'
flake.nix in . (current dir)nixos-rebuild, it automatically tries to build:
#nixosConfigurations.{hostname}.config.system.build.toplevelnixos-rebuild build --flake '/code/nixos-config#mysystem'
flake.nix in /code/nixos-confignixos-rebuild, it automatically tries to build:
#nixosConfigurations.mysystem.config.system.build.toplevelmysystem config)nix build 'github:colemickens/nixpkgs-wayland#obs-studio'
flake.nix in (a checkout of github.com/colemickens/nixpkgs-wayland)#obs-studio#packages.{currentSystem}.obs-studionix flake update --recreate-lock-file
flake.locknix flake update --update-input nixpkgs
flake.lockNix CLI will try to be ... smart and auto-coerce some output attribute paths for you.
nix build '/some/path#obs-studio':
/some/path#obs-studio/some/path#packages.x86_64-linux.obs-studio/some/path#legacyPackages.x86_64-linux.obs-studioRemove Impurities - Since nix flakes does a 'pure' build by default,
NIX_PATH is ignored<nixpkgs> imports do not work, and explicitly error~/.config/{nix,nixpkgs}) are ignorefetchTarball without a pinned rev+sha256) are forbiddenTo fix these:
flake.nix instead of using fetchTarball
nixpkgs-wayland.getFlake vs passing inputs in specialArgsConsider the nixos configuration in this repo:
These represent an example, minimal NixOS system configuration.
The easiest way to build it, without cloning this repo:
nix build 'github:colemickens/nixos-flake-example#nixosConfigurations.mysystem.config.system.build.toplevel'
Let's prove that we can build this config, with and without flakes:
Using nixos-rebuild:
# with flakes
unset NIX_PATH
nixos-rebuild build --flake '.#mysystem'
readlink -f ./result
/nix/store/gg1jhmzqndqa0rfnwfdbnzrn8f74ckr6-nixos-system-mysystem-21.03pre-git
# !! for this next step, match the git SHA1 to what the flake.lock uses
# otherwise you'll have a hash mismatch due to different nixpkgs
# without flakes
export NIX_PATH=nixpkgs=https://github.com/nixos/nixpkgs/archive/007126eef72271480cb7670e19e501a1ad2c1ff2.tar.gz:nixos-config=/home/cole/code/nixos-flake-example/configuration.nix
nixos-rebuild build
readlink -f ./result
/nix/store/gg1jhmzqndqa0rfnwfdbnzrn8f74ckr6-nixos-system-mysystem-21.03pre-git
Using nix build:
# with flakes
unset NIX_PATH
nix build '.#nixosConfigurations.mysystem.config.system.build.toplevel
readlink -f ./result
/nix/store/gg1jhmzqndqa0rfnwfdbnzrn8f74ckr6-nixos-system-mysystem-21.03pre-git
# without flakes
export NIX_PATH=nixpkgs=https://github.com/nixos/nixpkgs/archive/007126eef72271480cb7670e19e501a1ad2c1ff2.tar.gz:nixos-config=/home/cole/code/nixos-flake-example/configuration.nix
nix-build '<nixos/nixpkgs>' -A config.system.build.toplevel
readlink -f ./result
/nix/store/gg1jhmzqndqa0rfnwfdbnzrn8f74ckr6-nixos-system-mysystem-21.03pre-git
The ./check.sh script automates this process:
cole@slynux ~/code/nixos-flake-example master* 7s
❯ ./check.sh
:: Updating the 'nixpkgs' input in flake.nix
+ nix flake update --update-input nixpkgs
+ set +x
:: Using 'nixos-rebuild' to build the 'mysystem' toplevel
+ nixos-rebuild build --flake '.#mysystem'
warning: Git tree '/home/cole/code/nixos-flake-example' is dirty
building the system configuration...
warning: Git tree '/home/cole/code/nixos-flake-example' is dirty
+ set +x
:: Using rev=007126eef72271480cb7670e19e501a1ad2c1ff2 for <nixpkgs> (extracted from flake.nix)
:: Setting NIX_PATH to the same values flakes is using
+ NIX_PATH=nixpkgs=https://github.com/nixos/nixpkgs/archive/007126eef72271480cb7670e19e501a1ad2c1ff2.tar.gz:nixos-config=/home/cole/code/nixos-flake-example/configuration.nix
+ nix-build '<nixpkgs/nixos>' -A config.system.build.toplevel
/nix/store/gg1jhmzqndqa0rfnwfdbnzrn8f74ckr6-nixos-system-mysystem-21.03pre-git
+ set +x
flake: /nix/store/gg1jhmzqndqa0rfnwfdbnzrn8f74ckr6-nixos-system-mysystem-21.03pre-git
clssc: /nix/store/gg1jhmzqndqa0rfnwfdbnzrn8f74ckr6-nixos-system-mysystem-21.03pre-git
Is the hash tag syntax really worth it?
nix build 'github:colemickens/nixpkgs-wayland#obs-studio'nix build --flake 'github:colemickens/nixpkgs-wayland' 'obs-studio' ?Are the auto-coercion rules for attribute paths worth it? They definitely add some mental overhead...
Nix
63.8%
Shell
36.2%