`nixos-rebuild build-image` error option `system.build.images` no value defined

Disclaimer: this is almost certainly an issue with my system, not with nixos-rebuild itself - but I’m new and can’t solve it, I thought asking on discourse would be more appropriate than opening an issue.

Context: I’m switching to nixos and am currently writing the flake on a non-NixOS linux system.

I’m trying the new nixos-rebuild build-image command instead of nixos-generators.

  • I entered a shell with nix shell nixpkgs#nixos-rebuild
  • Ran nixos-rebuild build-image --flake .#iso
  • Got the error:
error: The option `system.build.images' was accessed but has no value defined. Try setting the option.

My files:

{
  inputs = {
    nixpkgs.follows = "unstable";
    unstable.url = "nixpkgs/nixos-unstable";
  };

  outputs = inputs:
    let
      system = "x86_64-linux";
      specialArgs = { inherit inputs; };
    in {
      nixosConfigurations = {
        iso = inputs.nixpkgs.lib.nixosSystem {
          inherit system specialArgs;
          modules = [ ./configurations/iso/configuration.nix ];
        };
      };
    };
}
{ inputs, ... }:
let
  inherit (inputs) nixpkgs;
in {
  imports =
    [ "${nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix" ];
}
  • Is it because I’m not on nixos? Maybe nixos-rebuild won’t work here
  • Is it because nix shell pulls a different nixpkgs than the latest with the build-image related commits? I also tried nix shell github:NixOS/nixpkgs#nixos-rebuild though…

PS: Regarding the last question: how can I run nix shell nixpkgs#package but specify nixpkgs to be from the current flake inputs instead of from the global registry? (I searched for this in the nix flake references manual, but couldn’t find it. maybe I need to add a packages output that forwards legacyPackages and then nix shell .#package)

Yesterday I posted this link to a repo showing how I make an image for a RaspberryPi: Eric Gundrum / rpi-wap · GitLab. I then run nix build .#image.rpi1911 to make the OS and image.

I suspect the key problem is with how to identify the build target. In my case, it is nixosConfigurations.rpi1911.config.system.build.sdImage.

I think what you are trying to do is similar enough that you could craft your flake in a similar way. Note that for this I use nix build, not nixos-rebuild.

Maybe even try running nix build .#nixosConfigurations.iso.config.system.build.sdImage.

It seems nix shell has been renamed to nix env shell, probably to avoid conflict with nix-shell. nix shell --help describes options, basically what is posted in nix env shell - Nix Reference Manual

One of these days I will figure out how to make my OS build configuration entirely do away with the flake registry. I find the registry concept in direct conflict with managing reproducible builds. I already configure my OS to set nixPath = [ "nixpkgs=" "nixos-config="] for the same reasons.

1 Like

This works, I had already seen it before, because from what I understand nixos-generator is a “wrapper” around it.

The new nixos-rebuild build-image looks like something different to me

It introduces an additional images attribute:

config.system.build.images.IMAGEFORMAT instead of config.system.build.IMAGEFORMAT

I don’t know, I’m trying to learn.

What you gave me achieves my intent, so thank you @ericgundrum.

Thank you for this. So you basically override the global registry and assign blanks, right?

Also thank you for this. Completes what I was wondering:

Still I need to learn flakes packages better because I get

error: flake does not provide attribute 'packages.x86_64-linux.default' or 'defaultPackage.x86_64-linux'

but I don’t know what to put here

packages.${system}.default = ???;

to pass all the flake inputs to the default package.

Author of that particular sub-command, nixos-rebuild build-image here. Thanks for posting and sorry for your experience.

So, as you said the feature is pretty new - debuting in 25.05 - and definitely needs a bit more documentation.

The confusing thing here, triggering the error is that you are configuring too much :smiley:

nixos-rebuild build-image assumes that you pass it a “normal” or “full” nixos configurations and the name of a “variant” - i.e. in your case an installation iso. It will then merge the image “variant” specific options (here: installation-cd-minimal.nix) with the rest of your configuration and builds an image from that.
The problem here is that you are already one of the “variants”, the installer iso in the toplevel which currently fails with an awful error.

But to proceed and do what you are trying to do you can either:

  • Just remove the import of installation-cd-minimal.nix alltogether and use nixos-rebuild build-image --flake .#iso --image-variant iso-installer to build a customized installer iso (with all the options from your config).
  • Keep the import, but use the conventional way to build the iso: nix build .#nixosConfigurations.iso.config.system.build.isoImage.

Both should work, so hope that helps!

2 Likes

Not quite. My assignment to nixPath overrides the environment variables. To affect the registry, I use something like

    registry = {
      nixpkgs = {
        from.type = "indirect";
        from.id = "nixpkgs";
        to.type = "git";
        to.url = "file:///nix/nixpkgs";
      };
      nixos-hardware = {
        from.type = "indirect";
        from.id = "nixos-hardware";
        to.type = "git";
        to.url = "file:///nix/flake-cache/nixos-hardware.git";
      };
    };

This adds registry entries such as system flake:nixpkgs git+file:///nix/nixpkgs which overrides the global entries that always are present. Someday I will figure out how to eliminate the global entries, but for now I work around it, which requires that I specify inputs.nixpkgs.url in the flake.

I think also there are circumstances where some packages insist on other versions of nixpkgs, and how they do that may involve the registry. I haven’t encountered this enough to delve into it yet.

I went down this path almost entirely because I found pulling the nixpkgs tar file annoyingly slow. Doing a git remote update on my local nixpkgs took much less time. I use this only for my primary machine, which wants nixos-unstable. My various others just use the global registry entry for nixpkgs despite the slow tar download.

I have a separate flake to manage packages for my desktop environment. The relevant part looks something like

    packages.${system}.default = self.pkgs.buildEnv {
      name = "desk_default";
      paths = [
        self.tomb
        self.pkgs.unzip
        self.pkgs.zip
        ...
      ];
      pathsToLink = ["/share" "/bin"];
      extraOutputsToInstall = ["man" "doc"];
    };

A line like self.pkgs.zip is just pulling the unmodified package from nixpkgs.

A line like self.tomb is using a custom attribute defined at the same level as packages.${system}.default. For example

    tomb = self.pkgs.buildEnv {
      name = "tomb";
      paths = with self.pkgs; [tomb pinentry-curses lsof zsh];
      pathsToLink = ["/share" "/bin"];
      extraOutputsToInstall = ["man" "doc"];
    };

This is where I get to modify the target package. Different packages need modification in different ways, such as

    vscode = self.pkgs.vscode-with-extensions.override {
      vscodeExtensions = with self.pkgs.vscode-extensions; [
        ...
    ];};
    neovim = self.neovim-nix.extendConfiguration {
      modules = [{...}];};
    nixvim = nixvim.legacyPackages.${system}.makeNixvimWithModule {
      module.config = {...};};

However, I’ve been getting away from this desk_default and nix profile – moving the packages I want into the OS config. (Or, in individual flakes imported into the OS config.)

I suspect the nix profile approach might make more sense for use on a system where I do not control the OS (such as on a Mac). Eventually I may go there, but for now, running nixos-rebuild is less work. (And, I gave it a wrapper so I can simply run nixos build instead of the verbose nixos-rebuild <whatever>.)

Worked like a charm, thank you!

I’ll leave just a few thoughts for improving documentation

I’d like to contribute myself, but don’t know the system well enough and I actually don’t even know how documentation works in nixos since nix repl -> :lf . -> :doc anything never shows me the docs.

I got to my problem because I had a nixos-generators “config” and was trying to switch to your command: maybe the tip might be added to nixos-generators, if it’s ever archived, as a migration step (i.e. remove installation-cd... because bla bla).

Alternatively just explaining the inner workings was easy to understand for a newbie like me, so maybe the docs may say “this systems imports the necessary expression from the nixos installer modules so you don’t have to”.

Or even, I don’t know if it’s possible, throwing an exception for the double import (?).

This made me dig deeper, I’m liking the vibe of both the language and the community, I appreciate your work.

1 Like

Thank you, you explained it very well.

Wow the fact the global entries are always present is interesting, there seem to be a few of such inner workings that conflict with reproducibility, I definitely need to keep notes!

The slow download always bugged me too I’ll definitely try your “eric trick” when I have the system up and running.

That was clear and in depth, nice! I managed to write a few derivation now thanks to you.

Yeah aliases are great, I myself like the nish package trick!

Have a nice day, was fun chatting with you!

Thank you for the clear feedback on how to improve docs.

I think catching this scenario with an assertion during evaluation to set a more helpful error message should be feasible. I’ll do so first, then will add it to nixos-generators docs either way.

There’s an yet unpublished draft for some additional documentation, explaining how it works internally for nixpkgs docs. Maybe that’s a good start, I hope to push it next week.

1 Like