I cannot make sense of flakes

The flake location “doesn’t really matter”, but of all places /etc/nixos is bad advice. And you definitely should not link the flake somewhere else than any files the flake.nix refers to.

If you want to make your life easy, follow the above advice to put the flake.nix and everything that belongs to it in a project git repository. You cannot refer to any file from within the flake that is outside of the directory tree the flake.nix itself is in.

What’s more, last time I checked flakes can only be built when they are staged (git add .), nobody seems to mention this crucial detail.

Follow these conventions and at least you have the basic foundations right, then you can focus on actual problems.

You can also just not-use a git repo, but then you really want some way to be able to be able to revert changes and track old changes, which is the whole point of VCSes. We didn’t mention it because OP never mentioned using git.

1 Like

The last time I tried git was more than 6 months ago and I was having issues getting the authentication to work, I was trying to push my dotfiles to a git repo to pull them back down on a different machine. I haven’t tried using git since because the only reason I saw to using it at the time was to easily backup/ move files. Instead I have a USB I upload the new files to when I change something and it works as I need it to.

I can use git if that’s the best way, but I don’t intend to change this flake after it works and I was only even going through all of this to use a bloody browser (Zen) and I wanted to follow the declarative NixOS philosophy instead of using a flatpak.

I’m not currently using git repos anywhere, and I back all my files up manually onto external drives the slow and clunky way

Don’t worry with git then. Place everything under the same directory somewhere in your home folder, let’s say /home/anakin/dotfiles, and then run sudo nixos-rebuild switch --flake /home/anakin/dotfiles#anakin. Ignore all files under /etc and only rebuild your system specifying your flake directory.

As others have said, if you dont specify #anakin it will fill in the current hostname of your system, so pay atention to that.

This is currently where all of my NixOS configuration is, in /home/anakin/Nixos/.

When I attempt to rebuild I run the command sudo nixos-rebuild switch --flake /home/anakin/Nixos#anakin I get this output:

[sudo] password for anakin: 
building the system configuration...
evaluation warning: The option `hardware.pulseaudio' defined in `/nix/store/9lgvy0blk1gx1f96hjrwwb469qypzavc-source/multimedia.nix' has been renamed to `services.pulseaudio'.
error:
       … while calling the 'head' builtin
         at /nix/store/jk6xpbfh10gz6q5cqw8b2f7xk0pl7hkv-source/lib/attrsets.nix:1574:11:
         1573|         || pred here (elemAt values 1) (head values) then
         1574|           head values
             |           ^
         1575|         else

       … while evaluating the attribute 'value'
         at /nix/store/jk6xpbfh10gz6q5cqw8b2f7xk0pl7hkv-source/lib/modules.nix:927:9:
          926|     in warnDeprecation opt //
          927|       { value = addErrorContext "while evaluating the option `${showOption loc}':" value;
             |         ^
          928|         inherit (res.defsFinal') highestPrio;

       … while evaluating the option `system.build.toplevel':

       … while evaluating definitions from `/nix/store/jk6xpbfh10gz6q5cqw8b2f7xk0pl7hkv-source/nixos/modules/system/activation/top-level.nix':

       … while evaluating the option `system.systemBuilderArgs':

       … while evaluating definitions from `/nix/store/jk6xpbfh10gz6q5cqw8b2f7xk0pl7hkv-source/nixos/modules/system/activation/activatable-system.nix':

       … while evaluating the option `system.activationScripts.etc.text':

       … while evaluating definitions from `/nix/store/jk6xpbfh10gz6q5cqw8b2f7xk0pl7hkv-source/nixos/modules/system/etc/etc-activation.nix':

       … while evaluating definitions from `/nix/store/jk6xpbfh10gz6q5cqw8b2f7xk0pl7hkv-source/nixos/modules/system/etc/etc.nix':

       … while evaluating the option `environment.etc."lightdm/lightdm-gtk-greeter.conf".source':

       … while evaluating definitions from `/nix/store/jk6xpbfh10gz6q5cqw8b2f7xk0pl7hkv-source/nixos/modules/services/x11/display-managers/lightdm-greeters/gtk.nix':

       (stack trace truncated; use '--show-trace' to show the full, detailed trace)

       error: access to absolute path '/home' is forbidden in pure evaluation mode (use '--impure' to override)

I appreciate all of your help, I am sorry that I am clearly misunderstanding something

rename hardware.pulseaudio in multimedia.nix to services.pulseaudio.

Your lock file is in a revision that has renamed the option you are trying to set. When looking for options in NixOS Search, remember to select the appropriate channel (unstable or 24.11 as of today) matching the input in your flake.nix.

Done. The error looks otherwise identical

# multimedia.nix
# this file is for configuring various audio and video settings 

{ config, pkgs, ... }:
{
  services.pulseaudio.enable = false;
  services.pipewire = {
    enable = true;
    alsa.enable = true;
    alsa.support32Bit = true;
    pulse.enable = true;
    jack.enable = true;
  };
 # services.xserver.displayManager.sessionCommands = ''
 #     ${lib.getBin pkgs.xorg.xrandr}/bin/xrandr --setprovideroutputsource 2 0
 # '';

}
[anakin@nixos:~/Nixos]$ sudo nixos-rebuild switch --flake /home/anakin/Nixos#anakin
building the system configuration...
error:
       … while calling the 'head' builtin
         at /nix/store/jk6xpbfh10gz6q5cqw8b2f7xk0pl7hkv-source/lib/attrsets.nix:1574:11:
         1573|         || pred here (elemAt values 1) (head values) then
         1574|           head values
             |           ^
         1575|         else

       … while evaluating the attribute 'value'
         at /nix/store/jk6xpbfh10gz6q5cqw8b2f7xk0pl7hkv-source/lib/modules.nix:927:9:
          926|     in warnDeprecation opt //
          927|       { value = addErrorContext "while evaluating the option `${showOption loc}':" value;
             |         ^
          928|         inherit (res.defsFinal') highestPrio;

       … while evaluating the option `system.build.toplevel':

       … while evaluating definitions from `/nix/store/jk6xpbfh10gz6q5cqw8b2f7xk0pl7hkv-source/nixos/modules/system/activation/top-level.nix':

       … while evaluating the option `system.systemBuilderArgs':

       … while evaluating definitions from `/nix/store/jk6xpbfh10gz6q5cqw8b2f7xk0pl7hkv-source/nixos/modules/system/activation/activatable-system.nix':

       … while evaluating the option `system.activationScripts.etc.text':

       … while evaluating definitions from `/nix/store/jk6xpbfh10gz6q5cqw8b2f7xk0pl7hkv-source/nixos/modules/system/etc/etc-activation.nix':

       … while evaluating definitions from `/nix/store/jk6xpbfh10gz6q5cqw8b2f7xk0pl7hkv-source/nixos/modules/system/etc/etc.nix':

       … while evaluating the option `environment.etc."lightdm/lightdm-gtk-greeter.conf".source':

       … while evaluating definitions from `/nix/store/jk6xpbfh10gz6q5cqw8b2f7xk0pl7hkv-source/nixos/modules/services/x11/display-managers/lightdm-greeters/gtk.nix':

       (stack trace truncated; use '--show-trace' to show the full, detailed trace)

       error: access to absolute path '/home' is forbidden in pure evaluation mode (use '--impure' to override)

I had been leaving the error in multimedia.nix because it was happening last week, but the system was rebuilding properly otherwise so I thought it was ok

Are you referencing /home instead of ./home.nix anywhere in your code? Are you setting any options related to your X11 or display with a /home argument?

I looked through most of the files when someone else mentioned I can’t use /home anywhere but I’ll cat them all out and copy them below, if I find one I’ll try to update it.

# configuration.nix
# The main configuration for the NixOS system

{ inputs, config, pkgs, ... }:

{
  imports =
    [ 
      ./hardware-configuration.nix
      ./locale.nix
      ./packages.nix
      ./display.nix
      ./network.nix
      ./multimedia.nix
      ./system.nix
      ./services.nix
      inputs.home-manager.nixosModules.home-manager
    ];
  home-manager = {
    extraSpecialArgs = { inherit inputs; };
    users = {
      anakin = import ./home.nix;
    };
  };
  nix.settings.experimental-features = [ "nix-command" "flakes" ];
}
# display.nix
# this is the configuration for the display server settings for the NixOS system

{ config, pkgs, ... }:
{
  services.xserver.enable = true;
  services.xserver.videoDrivers = [ "amdgpu" "displaylink" "modesetting"]; # For AMD graphics
  hardware.firmware = [ pkgs.linux-firmware ]; # Correctly specifying firmware package

  services.xserver.displayManager.lightdm.enable = true;
  services.xserver.displayManager.lightdm.background = /home/anakin/Wallpapers/Untitled_Artwork.jpeg;
  services.xserver.windowManager.qtile.enable = true;

  services.xserver.xkb = {
    layout = "us";
    variant = "";
  };

  services.libinput.enable = true;
}
{
  description = "my NixOS flake";

  inputs = {
    nixpkgs.url = "nixpkgs/nixos-unstable";
    zen-browser.url = "github:0xc000022070/zen-browser-flake";
    home-manager = {
      url = "github:nix-community/home-manager";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = {self, nixpkgs, home-manager, ...}@inputs:
  let
    system = "x86_64-linux";
    pkgs = import nixpkgs {
      inherit system;
      config = {
        allowUnfree = true;
      };
    };
  in
  {
  nixosConfigurations = {
    anakin = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      specialArgs = {inherit inputs system; };
      modules = [
        ./configuration.nix
        { home-manager.users.anakin = ./home.nix; }
        ];
      };
    };
    };
  }
#home.nix
{ config, pkgs, inputs, ... }:
{
  home.username = "anakin";
  home.homeDirectory = "/home/anakin";
  home.stateVersion = "23.11"; 
  
  programs.home-manager.enable = true;
}

There is a /home/anakin here, and I also pasted this file above. I assume it’s proper as it defines the home directory but I can change it

# locale.nix
# the configuration for locale and timezone information in the NixOS system

{ config, pkgs, ... }:
{
  time.timeZone = "America/New_York"; # Set your time zone.

  i18n.defaultLocale = "en_US.UTF-8";

  i18n.extraLocaleSettings = {
    LC_ADDRESS = "en_US.UTF-8";
    LC_IDENTIFICATION = "en_US.UTF-8";
    LC_MEASUREMENT = "en_US.UTF-8";
    LC_MONETARY = "en_US.UTF-8";
    LC_NAME = "en_US.UTF-8";
    LC_NUMERIC = "en_US.UTF-8";
    LC_PAPER = "en_US.UTF-8";
    LC_TELEPHONE = "en_US.UTF-8";
    LC_TIME = "en_US.UTF-8";
  };
}
# multimedia.nix
# this file is for configuring various audio and video settings 

{ config, pkgs, ... }:
{
  services.pulseaudio.enable = false;
  services.pipewire = {
    enable = true;
    alsa.enable = true;
    alsa.support32Bit = true;
    pulse.enable = true;
    jack.enable = true;
  };
 # services.xserver.displayManager.sessionCommands = ''
 #     ${lib.getBin pkgs.xorg.xrandr}/bin/xrandr --setprovideroutputsource 2 0
 # '';

}
# network.nix
# this file is for configuring network and firewall settings

{ config, pkgs, lib, ... }:
{
  networking.hostName = "nixos"; # Define your hostname.
  networking.networkmanager.enable = true;

  # Enable CUPS to print documents.
  services.printing.enable = true;

  # Example of additional networking settings:
  networking.firewall.enable = true;
  networking.firewall.allowedTCPPorts = [ 22 ];
  # networking.firewall.allowedUDPPorts = [ ... ];
  services.openssh.enable = true;

  # Enable resolvconf for DNS management
  networking.resolvconf = {
    enable = true;
    package = lib.mkForce pkgs.openresolv;
  };
  # Setting up Rapsberry Pi router; comment out after set up is complete
  #networking.interfaces.etho.ipv4.addresses = [ {
  #  address = "192.168.1.10";
  #  prefixLength = 24;
  #} ];
  #networking.defaultGateway = "192.168.1.1";
  #networking.nameservers = [ "1.1.1.1" ];
}

I was trying to set up raspberry pi router with OpenWRT a while ago, which is what all the comments at the bottom are about. Additionally, I didn’t think the hostname mattered, and I ran sudo nixos-rebuild switch --flake /home/anakin/Nixos#nixos out of curiosity because I don’t know if I was jsut that dumb this whole time and that doesn’t get anywhere.

# packages.nix
# this is for adding and removing packages from the NixOS system

{ config, pkgs, inputs, ... }:
{
  environment.systemPackages = with pkgs; [
      bash
      blueman
      brightnessctl
      cryptsetup
      displaylink
      firmwareLinuxNonfree
      home-manager
      pavucontrol
      pulseaudioFull
      python3
      python3Packages.qtile-extras
      python3Packages.pip
      python3Packages.pillow
      python3Packages.psutil
      udev
      unzip
      vim
      wget
      wg-netmanager
      wireguard-tools
      xorg.libxcb
      xorg.libXext
      xorg.libX11
      inputs.zen-browser.packages."${system}".default 
      inputs.zen-browser.packages."${system}".beta
      inputs.zen-browser.packages."${system}".twilight 
      inputs.zen-browser.packages."${system}".twilight-official 
  ];

  users.users.anakin = {
    isNormalUser = true;
    description = "anakin";
    extraGroups = [ "networkmanager" "wheel" ];
    packages = with pkgs; [
      arandr
      brave
      discord
      dosfstools
      drm_info 
      dunst
      emacs
      eza
      exfatprogs
      fastfetch
      file
      fzf
      flameshot
      gimp
      git
      ghostscript
      ghostty
      graphicsmagick
      htop
      jellyfin-ffmpeg
      kitty
      kmonad
      #localsend
      mpv
      nitrogen
      neovim
      picom
      #protonvpn-gui
      #protonmail-desktop
      python3Packages.qtile-extras
      python3Packages.pywal
      tldr
      ripgrep
      rofi
      rpi-imager
      spotify
      spotify-player
      udiskie
      ueberzug
      usbutils
      vieb
      viu
      vlc
      yazi
      #zellij
      zoxide
    ];
  };

  programs.firefox.enable = true;

  nixpkgs.config.allowUnfree = true;
}

This file is full of junk because I was playing around with some stuff when I was trying to learn what sort of programs I wanted to use, as well as the inputs for trying to make the Zen browser work (The reason I am trying to do flake things at all).

# Services.nix
{ config, pkgs, ... }:

{
  # Enabling battery management through tlp
  services.tlp.enable = true;
  
  services.tlp.settings = {
    START_CHARGE_THRESH_BAT0 = 50;
    STOP_CHARGE_THRESH_BAT0 = 85;
    RUNTIME_PM_ALL = "auto";
    #DISK_APM_LEVEL_ON_AC= "254";
    #DISK_APM_LEVEL_ON_BAT= "128";
    DEVICES_TO_DISABLE_ON_AC="bluetooth";
    DEVICES_TO_DISABLE_ON_BAT="bluetooth";
    CPU_SCALING_GOVERNOR_ON_AC = "performance";
    CPU_SCALING_GOVERNOR_ON_BAT = "powersave";
    SOUND_POWER_SAVE_ON_BAT = 5;
    SOUND_POWER_SAVE_CONTROLLER = "Y";
    MEM_SLEEP_ON_AC= "s2idle";
    MEM_SLEEP_ON_BAT= "deep";
  };

  # Running the emacs background daemon
  systemd.services.emacs = {
    description = "Emacs: the extensible, self-documenting text editor";
    after = [ "network.target" ];  # Adjust dependencies as needed
    wantedBy = [ "multi-user.target" ];

    serviceConfig = {
      Type = "forking";
      ExecStart = "${pkgs.emacs}/bin/emacs --daemon";
      ExecStop = "${pkgs.emacs}/bin/emacsclient --eval '(kill-emacs)'";
      Restart = "always";
      User = "anakin";  # Replace with your actual username
    };
  };
  
  # Systemd-resolved service
  services.resolved.enable = true;

  #Enables bletooth connection
  services.blueman.enable = true;
}

There’s some stuff in here I was trying to use to help prolong my battery life away from the wall, as well as I was trying some emacs before deciding I prefer vim

# system.nix
# This is the file for boot laoder, system version, and other system information

# system.nix
{ config, pkgs, ... }:

{
  boot.loader.systemd-boot.enable = true;
  boot.loader.efi.canTouchEfiVariables = true;

  swapDevices = [
     { device = "/swap"; }
  ];
  
  boot.kernelParams = [ "resume=/swap" ];

  hardware.firmware = [ pkgs.linux-firmware ];

  hardware.bluetooth.enable = true;

  # This value determines the NixOS release from which the default
  # settings for stateful data, like file locations and database versions
  # on your system were taken. It‘s perfectly fine and recommended to leave
  # this value at the release version of the first install of this system.
  # Before changing this value read the documentation for this option
  # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
  system.stateVersion = "24.05"; # Did you read the comment?
}

I’m not seeing any problematic /home references here, but I have been staring at my terminal for a while now, and absolutley could have missed it. Or I have some other error I’m totally overlooking, Apologies for basically pasting a wall of text but i’m not sure of an esaier way

remove this and see if it builds

1 Like

This seems to have worked! Thank you kindly, but is there someway to define the lightdm background differently? It was nice seeing my login manager go straight into my wallpaper.

I was also trying to get DisplayLink working for my external monitor and I think that also should be working now. Thanks so much!

Edit 2: the external monitor does not work, but the build did so that’s the intent here

Move it in with your config and use a relative path that stays within your flake to refer to it.
(The path is relative to the file that you define that option in.)

Happy to help!

Unfortunately, I don’t use lightdm so don’t know much about it’s options. But if look into the option documentation here, you see that it can be an absolute path indeed or what it seems to be a RGB color string from that regex.

If the option accepted a relative path, I believe you would be able to move your desired wallpaper anywhere inside your /home/anakin/NixOS directory and reference it as a relative path. But the option only allows a absolute path, so since the result of the rebuild will be copied into the nix store (/nix/store/<result>), any absolute path you put there will be treated as impure (cuz it’s outside the nix store and you don’t know the resulting derivation dir upfront).

I believe there could be a way to place the file inside the flake directory and use some kind of nix variable to create a string interpolation ("${someVar}/YourWallpaper.jpeg) that results in a absolute path to the resulting derivation. But I don’t know much about those types of approaches. Maybe @waffle8946 can help you with this.

I think you’ve misunderstood paths vs path strings.

https://nix.dev/manual/nix/2.24/language/string-interpolation#interpolated-expression

A path in an interpolated expression is first copied into the Nix store, and the resulting string is the store path of the newly created store object.

And this path is in fact interpolated into a string (line 29):

So a relative path (not a path string) is fine here.

Thank you for the explanation! I guess the terms can be a bit misleading if you don’t think about the NixOS internals.

So, yeah, copy the wallpaper into the flake directory and reference it as a relative path of the file you’re editing, @MrClean

I don’t even think it’s necessary to think about the NixOS internals - I generally don’t. I’d just use the relative path and assuming it’ll get copied and turned into a store path string. In fact I can’t even think of a way it’d actually be possible to use any path option productively if it wasn’t turned into a path string when a path was provided. I think you can always assume a relative path will work (though whether you want to use a path instead of a string depends on whether you want that file in the store or not).

I moved the image to a new directory in ~/Nixos/Wallpapers.nix/ for now, referenced it from there and it built with seemingly no issues.

I don’t think this is really the best way to do it, but it’s the easiest way and the flake even building is a win to me right now, thank you all again