Why is `nix-env` freezing when the "unstable" channel is added?

I added the unstable channel because I want the latest packages:

❯ nix-channel --list
nixos https://nixos.org/channels/nixos-unstable
❯ nix-channel --update
unpacking channels...
❯ nix-channel --list
nixos https://nixos.org/channels/nixos-unstable

And then I proceeded to install the packages I want:

❯ nix-env -i discord
fish: “nix-env -i discord” terminated by signal SIGKILL (Forced quit)

It just started using all the memory and CPU power in my potato PC. But then after 30mins it’s killed by my shell.

I successfully installed discord before adding the unstable channel.

Edit: I am on Debian Stable not NixOS.

Hrm, well, it depends on how potato we’re speaking. It might be running out of memory and swapping for 30 minutes, until the kernel finally kills it.

You’re using nix-env -i, which is a terrible mistake of an API and extremely slow and memory hungry, see the first heading on this website: https://stop-using-nix-env.privatevoid.net/

My guess is that with unstable added it just ends up being too much and your computer can’t handle it.

As suggested, --attr/-A can “fix” this by not evaluating by package name. Try nix-env -iA nixos-unstable.discord maybe. At least I think that was how nix-env works with channels, even that is a bit of wonky logic. Of course, you will still run into all the other problems documented on that website, and possibly more.

Or just stop using nix-env altogether, I would not recommend it, especially to newcomers. Are you on NixOS, home-manager, nix-darwin or none of the above?

I should have mentioned it earlier. I am on Debian.

What is the best way to install (latest) packages from Nix repo? I would love to ditch nix-env and use a config file (declarative package management) to manage all my apps if it is possible. But how? I am a n00b to Nix way of things so I would very much appreciate as much detail as possible.

Sure! Sadly you’ve hit one of the rough edges of the ecosystem very early. People are working on this, but this won’t be the best initial experience for you.

There are two ways:

  1. You could use GitHub - nix-community/home-manager: Manage a user environment using Nix [maintainer=@rycee]
  • This would allow you to create a nice, declarative configuration file, store it in a git repository and then cleanly track and install your configuration. Much like NixOS, but independent of host OS!
  • The downside is that this doesn’t always mesh very well with what your host does. Gnome may disagree with you replacing some configuration files it likes creating (e.g. mimeapps), and graphical applications may utterly fail because of graphics driver mismatches.
  • You’ll also have to learn using nix as an actual language for this.
  1. Start using nix profile from the experimental 3.0 CLI
  • This does what you want nix-env to do, but isn’t utterly broken.
  • The documentation for it is here: nix profile install
  • To enable it, unfortunately you need to configure nix to allow the experimental CLI. This page documents how: Nix command - NixOS Wiki
  • You can extend this a little bit for a declarative list of packages to install, which is probably a nice way to get an initial taste of nix, but I don’t have any good guides for this. Feel free to ask if you’re interested.

My personal preference is the former, despite the caveats. You don’t really gain all that much from nix if you don’t use a declarative config, after all for a user it’s not much more than a second package manager if you don’t use those features. Except for nix-shell and the whole reproducible builds thing, which are neat of course, but you can use those without using nix as a package manager.

On the other hand, nix profile is a far more tame way of starting to use nix for something. home-manager can be quite a time sink and is definitely harder to pick up initially, as fun as it is.

Whatever you do, if you switch away from nix-env you will want to uninstall any packages you previously installed with nix-env. They have a habit of coming back to haunt you otherwise. You can list packages installed with nix-env using nix-env -q.

For the record, nix profile does not use channels. The 3.0 CLI has done away with that concept completely, and instead just uses upstream git branches. So if you switch to this, you will probably also want to remove your channels. This is much less magic and easier to understand IMO, but if you just started learning about channels may cause a bit of whiplash.

So feel free to come back if you have more questions! Sorry the newcomer story is in such a sorry state, everyone’s aware of it and it’s slowly improving.

1 Like

Thank you for taking time to paint a clear picture on how to approach Nix for a newbie!

I have chosen to go the home-manager route. I have successfully set it up and configured the home.nix to my liking.

But I ran into something: How do I install packages that are in a different channel?

For example I want to install nixGL but it is in a channel of it’s own.

The recommendation is to install using nix-env:

$ nix-channel --add https://github.com/guibou/nixGL/archive/main.tar.gz nixgl && nix-channel --update
$ nix-env -iA nixgl.auto.nixGLDefault   # or replace `nixGLDefault` with your desired wrapper

But after adding the channel if I try this in my home configuration…

  home.packages = [
    pkgs.helix
    pkgs.wezterm
    pkgs.discord
    pkgs.nixGLDefault
  ];

…the following error occurs:

$ home-manager build
error: attribute 'nixGLDefault' missing

       at /home/user/.config/nixpkgs/home.nix:14:5:

           13|     pkgs.discord
           14|     pkgs.nixGLDefault
             |     ^
           15|   ];
(use '--show-trace' to show detailed location information)

Unless I misremember, nix channels will be placed in the NIX_PATH, and can then be accessed using import <channel-name>.

So in your case, I would do something like:

{
  pkgs,
  nixgl ? import <nixgl> { },
  ...
}: {
  home.packages = [
    pkgs.helix
    pkgs.wezterm
    pkgs.discord
    nixgl.auto.nixGLDefault
  ];
}

To spell out what’s happening explicitly, the stuff in { pkgs, ...}: are function arguments, which nixos-rebuild will automatically fill with some things, specifically the variables defined in _module.args (actually, I’m lying, it sets the variables defined by home-manager, but the NixOS docs are much nicer to read on this topic and mostly accurate).

I’m adding an argument called nixgl, and using the ? syntax to mark it as an optional argument, which if not specified will be given the default value of import <nixgl> {}.

import <nixgl> {} in turn will look for where nixgl is using NIX_PATH, substitute its path, and then evaluate the default.nix file in the resulting directory, which is this file: nixGL/default.nix at 7165ffbccbd2cf4379b6cd6d2edd1620a427e5ae · guibou/nixGL · GitHub

That should then give you access to the packages in the nixgl variable.

The added benefit of defining it as an argument is that you can, if you like, pass in an actual value with _module.args, which may be helpful if you switch to flakes in the future or want to use some other mechanism to avoid having to run nix-channel first on every computer you want to evaluate this config on.

It’s still throwing an error:

$ home-manager build
error: attribute 'nixgl' missing

I am using the following config:

moss@pc0:~/.config/nixpkgs$ cat home.nix 
{
  config,
  pkgs,
  nixgl ? import <nixgl> { },
  ... 
}: {
  # Home Manager needs a bit of information about you and the
  # paths it should manage.
  home.username = "moss";
  home.homeDirectory = "/home/moss";

  # Packages that should be installed to the user profile.
  home.packages = [
    pkgs.helix
    pkgs.wezterm
    pkgs.discord
    nixgl.auto.nixGLDefault
  ];


  # This value determines the Home Manager release that your
  # configuration is compatible with. This helps avoid breakage
  # when a new Home Manager release introduces backwards
  # incompatible changes.
  #
  # You can update Home Manager without changing this value. See
  # the Home Manager release notes for a list of state version
  # changes in each release.
  home.stateVersion = "22.05";

  # Let Home Manager install and manage itself.
  programs.home-manager.enable = true;
}

The nixGL channel is indeed added:

$ nix-channel --list
home-manager https://github.com/nix-community/home-manager/archive/master.tar.gz

The NIX_PATH:

$ echo $NIX_PATH
/home/moss/.nix-defexpr/channels:/nix/var/nix/profiles/per-user/root/channels

$ ls /home/moss/.nix-defexpr/channels/nixgl
all.nix  default.nix  flake.lock  flake.nix  nixGL.nix  nixpkgs.nix  README.md  Test.hs

The expression import <nixgl> {} will look for nixgl in the NIX_PATH. Prob’ly by default this will include ~/.nix-defexpr/channels. i.e. it’s expecting ~/.nix-defexpr/channels/nixgl to exist.

So you would need to run at least:

nix-channel --add https://github.com/guibou/nixGL/archive/main.tar.gz nixgl && nix-channel --update

to add the nixgl channel. (& nix-channel --list should show nixgl).

Even then the issue persists:

$ nix-channel --list
home-manager https://github.com/nix-community/home-manager/archive/release-22.05.tar.gz
nixgl https://github.com/guibou/nixGL/archive/main.tar.gz
nixos https://nixos.org/channels/nixos-unstable


$ home-manager build
error: attribute 'nixgl' missing

       at /nix/store/7k44hk59f8irq4b292kfbwhycmxk7f4g-nixpkgs/nixpkgs/lib/modules.nix:467:28:

          466|         builtins.addErrorContext (context name)
          467|           (args.${name} or config._module.args.${name})
             |                            ^
          468|       ) (lib.functionArgs f);
(use '--show-trace' to show detailed location information)

I think I have better luck with “flakes”. This worked:

~/.config/nixpkgs$ nix --extra-experimental-features nix-command --extra-experimental-features flakes run --impure github:guibou/nixGL -- wezterm

But how can I tweak my config.nix so I don’t have to pass the “extra-experimental-features” flags n number of times?

This doesn’t seem to work:

moss@pc0:~/.config/nixpkgs$ cat config.nix 
{
  allowUnfree = true;
  nix.settings.experimental-features = "nix-command flakes";
}

Just add:

nix.settings.experimental-features = [ "nix-command" "flakes" ];

to your home.nix, then home-manager switch again.

For reference, ~/.config/nixpkgs/config.nix configures nixpkgs, which is exclusively about the package definitions, so it defines whether you can use unfree packages and such. It won’t be able to change nix configuration.

~/.config/nix/nix.conf is where nix configuration is supposed to go, and it uses a key-value configuration syntax. With that change to your home.nix home-manager will be creating that file for you, so you can instead just put that configuration in home-manager.

If you want to enable unfree packages using home-manager as well, you can do that as documented in this option: nixpkgs.config .

It will then create config.nix for you as well, and you can just keep it all in home.nix instead of having three subtly different configuration files.


Also to satisfy my curiousity and perhaps resolve your channels issue, would you mind trying:

{
  config,
  pkgs,
  ... 
}: let
  nixgl = import <nixgl> { };
in {

The error context suggests something about argument resolution is just not working as I expect it to. I wonder if that’s a change to unstable I’m just unaware of, I tend to use stable for everything.

This totally worked! nixGL is now installed without using any flakes.


nix.settings.experimental-features = [ "nix-command" "flakes" ];

Where exactly should I add that line in the home.nix?

I tried this…

moss@pc0:~/.config/nixpkgs$ cat home.nix
{
  config,
  pkgs,
  ...
}: let nixgl = import <nixgl> { };
in {
  home.username = "moss";
  home.homeDirectory = "/home/moss";

  home.packages = [
    pkgs.helix
    pkgs.wezterm
    pkgs.discord
    nixgl.auto.nixGLNvidia
  ];

  home.stateVersion = "22.05";

  programs.home-manager.enable = true;

  nix.settings.experimental-features = [ "nix-command" "flakes" ];
}

but it resulted in errors…

$ home-manager build
error:
       Failed assertions:
       - A corresponding Nix package must be specified via `nix.package` for generating
       nix.conf.
(use '--show-trace' to show detailed location information)

Ah, right. Annoying that they don’t document that. You need to do what the error message says and also specify nix.package:

{
  config,
  pkgs,
  ...
}: let nixgl = import <nixgl> { };
in {
  home.username = "moss";
  home.homeDirectory = "/home/moss";

  home.packages = [
    pkgs.helix
    pkgs.wezterm
    pkgs.discord
    nixgl.auto.nixGLNvidia

    # To ensure we have the correct version of nix installed
    config.nix.package
  ];

  home.stateVersion = "22.05";

  programs.home-manager.enable = true;

  nix = {
    package = pkgs.nix;
    settings.experimental-features = [ "nix-command" "flakes" ];
  };
}

This is probably anyway a good idea, it will make home-manager update nix for you whenever you rebuild with an updated channel.

1 Like

Yep, it’s working!

home-manager update nix for you whenever you rebuild with an updated channel

Bonus!

Thank you so much for your help. When I first heard about Nix I absolutely loved the idea.

But before going all in (installing NixOS), I decided to learn about it a bit, as in, syntax and how things work. In that regard what is a good place to start? Maybe this “Getting started” section? Or is there something better (more current)?


And for the record this is my current home.nix:

{
  config,
  pkgs,
  ... 
}: let nixgl = import <nixgl> { };
in {
  # Home Manager needs a bit of information about you and the
  # paths it should manage.
  home.username = "moss";
  home.homeDirectory = "/home/moss";

  # Packages that should be installed to the user profile.
  home.packages = [
    pkgs.helix
    pkgs.wezterm
    pkgs.discord
    pkgs.remnote
    pkgs.veracrypt
    nixgl.auto.nixGLNvidia
    
    # To ensure we have the correct version of nix installed
    config.nix.package
  ];


  # This value determines the Home Manager release that your
  # configuration is compatible with. This helps avoid breakage
  # when a new Home Manager release introduces backwards
  # incompatible changes.
  #
  # You can update Home Manager without changing this value. See
  # the Home Manager release notes for a list of state version
  # changes in each release.
  home.stateVersion = "22.05";

  # Let Home Manager install and manage itself.
  programs.home-manager.enable = true;
  
  # enable non-free software
  nixpkgs.config.allowUnfree = true;

  nix = {
    package = pkgs.nix;
    settings.experimental-features = [ "nix-command" "flakes" ];
  };  
}

That’s the million dollar question :stuck_out_tongue: The nix ecosystem is still quite lacking here. There are some awesome people running around in the community doing their best to improve that. As I said, newcomer experience isn’t the best yet. There’s also just so much in this ecosystem, and so much of it is useful at any scale.

The nixos wiki is of wildly varying quality. It’s full of outdated information, and sometimes outright poor practice. It also has a few incredibly useful pages, like the one on flakes or nvidia GPUs. Take what you read there with a grain of salt.

A slightly more curated page is on https://nix.dev/. Unfortunately for you, it focuses on using nix for development, not managing a distro. That said, notably, it has the semi-official, and very recent, nix language tutorial here: Nix language basics — nix.dev documentation

Though looking through it, some of the tutorials feel a bit dated to me, too. I’d take the notes on reproducibility/niv (being replaced by flakes) and anti-patterns with a grain of salt. The anti-patterns are nice to know about though, even if you should often still use them. They explain some edge cases that can be confusing.

My favorites are the nix, nixos and nixpkgs manuals. They are reference works, but once you start feeling comfortable with the language, the information from them is invaluable. They’re also the most accurate and up-to-date documents you’ll find.

Don’t underestimate reading the nixpkgs source either. I personally learned how nixos modules work and how to use them properly this way. search.nixos.org links to specific files there, which makes this much more doable than you’d think.

Finally, I recommend xe’s blog and all the awesome things @Solene has been putting in #links lately for more specific topics. I think every nix user should know about erase your darlings as well.

1 Like

Thank you for your suggestions. They are helpful.

A slightly more curated page is on https://nix.dev/. Unfortunately for you, it focuses on using nix for development, not managing a distro. That said, notably, it has the semi-official, and very recent, nix language tutorial here: Nix language basics — nix.dev documentation

Using nix for development is actually on my list so this is just awesome!