Hi likivik,
I’ve done exactly this myself by following:
For a more detailed working example, see my gist: NixOS ISO · GitHub
Build NixOS closure
What I do it is build a closure of the NixOS environment (see nixos.nix
), which is what will eventually be installed to hard-drive automatically:
nix-build --attr system "./nixos.nix" -o result-closure
It is comprised of a pinned version of nixpkgs and imports a configuration.nix
(which pulls in dependencies and configures the system).
Build ISO
Then I take this closure of my NixOS environment, and wrap it up into an NixOS installer ISO, which when you boot into it, automatically installs the closure to disk.
I create a NixOS environment for the NixOS installer ISO (see iso.nix
), which imports the NixOS Live CD derivation, and pulls in the pre-build closure and install script by linking them into /etc/.
{ config, pkgs, ... }:
{
imports = [
# https://nixos.wiki/wiki/Creating_a_NixOS_live_CD
<nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix>
<nixpkgs/nixos/modules/installer/cd-dvd/channel.nix>
];
# add the automated installation files
environment.etc = {
"install.sh" = {
source = ./install.sh;
mode = "0700";
};
"closure-nix-store-path.txt" = {
source = ./closure-nix-store-path.txt;
};
"system" = {
source = ./system;
};
};
I build the ISO, and take the result and dd
it onto a USB stick, then boot into.
nix-build '<nixpkgs/nixos>' -A config.system.build.isoImage -I nixos-config=iso.nix -o result-iso
Once booted, I run the install script. The key part of the install script is how it adds the imported closure into the nix store (which will be in memory when you’re booted into the ISO), and then runs nix-install
which writes it to disk.
echo "copy closure to nix store"
nix copy --from file:///etc/system $(cat /etc/closure-nix-store-path.txt) --option binary-caches "" --no-check-sigs
echo "install nix"
nixos-install --no-root-passwd --option binary-caches "" --system $(cat /etc/closure-nix-store-path.txt)
Note the /etc/closure-nix-store-path.txt
- this is my hack remembering the location of the closure that I built outside of the ISO, and passing it to the ISO.
I hope this helps!