Question Regarding configuration.nix

relatively new NixOS user here, so… My strategy is simple: anything
MUST go in configuration not done by hand, simply because doing so
let you reinstall/replicate your complete setup anywhere simply
copying your config. IMO the ability to install stuff via CLI have to
considered harmful…

In general, of course, one can do some things via configuration and some
things via separate expressions for use with nix-shell or just
nix-build.

The reason for that might be that different subsets of things take
different time to rebuild and have different freshness requirements, so
rebuilding Chromium (used only for testing) doesn’t hold up the update
of Firefox (which I actually care about).

nix-env … well, it has a lot of useful applications, but I am not sure
plain nix-env -i package (and even nix-env -iA package) are
something to use if you already want to use NixOS.

1 Like

I agree that installing packages through nix-env is an antipattern. I go so far as to having an activation script that deletes ~/.nix-profile so that I can’t use it, because otherwise things would collect in there that I would come to depend on, forget to update, and be stuck without if I rebuilt my system from scratch.

5 Likes

Thanks for the replies. So as I understand it, many of you do not use nix-env to install software? What about “unFree” things like Google Chrome (which is my preferred browser)? Can those things be installed via configuration.nix along with the normal free stuff?

I appreciate your patience in answering my questions. I’m a long time Linux user but NixOS is a different animal entirely LOL.

The suggestion to create a separate file for packages makes a lot of sense to me.

Can those things be installed via configuration.nix along with the normal free stuff?

Yup! You just have to set an option in configuration.nix. I think it’s nixpkgs.config.allowUnfree = true.

qyliss ok, thanks. I added that line but to actually install using nix-env I had to use NIXPKGS_ALLOW_UNFREE=1 nix-env -i to get them to install, so I assumed it wouldn’t work automatically via a nixos-rebuild.

I suppose I assumed incorrectly. I’ll give it a try.

In your configuration.nix, you can allow all unfree packages with

nixpkgs.config.allowUnfree = true;

or allow specific packages with

nixpkgs.config.allowUnfreePredicate = (pkg: builtins.elem (builtins.parseDrvName pkg.name).name
  [
    "chromium"
  ]);

. You also need to add the package in environment.systemPackages.

3 Likes

Ok, I’m listing stuff in configuration.nix and attempting to rebuild, but it keeps saying that cheese is an undefined variable. I keep looking at this and don’t see anything wrong, but perhaps I’m missing something obvious?

# List packages installed in system profile. To search, run:
  # $ nix search wget
 environment.systemPackages = with pkgs; [
   wget nano mc vlc ffmpeg gstreamer libdvdcss hplip git libreoffice handbrake pavucontrol gimp-with-plugins neofetch thunderbird transmission virtualbox weechat google-chrome skypeforlinux cheese ];

Some packages are organised in separate sets, so they don’t pollute the root namespace.

In this case, cheese is supposed to be gnome3.cheese. You can find this out on this site or by running nix search cheese.

2 Likes

erictapen thank you! I saw that gnome3 prefix but didn’t realize it needed to be part of the name listed in configuration.nix.

I appreciate the help. I’m learning.

Yep, that did the trick

Oh, I didn’t know about allowUnfreePredicate. That’s really useful!

1 Like

I still wish nix-env was gone and we had a simple nix install command to add a package to project/home/system Nix file. In addition, having a lock file that pins nixpkgs, again for project/home/nix.

Currently I’m using /etc/nixos/configuration.nix for anything that is needed to get a working system and a practical environment for root. I use home-manager for most other packages and configuration. Lastly I use direnv with shell.nix for project specific dependencies.

I still find the workflow a bit awkward, but regardless I’m using vim or vscode to edit these files and then rebuild the environment. For project files it rebuilds the environment automatically by direnv which is pretty cool.

2 Likes

If you are an Emacs userperhaps you’ll like to put config in org-mode and sudo tangle to the right place so with a simple backup of your home/your datas you can also replicate the system that enable you to use those datas

Or let Nix do it™ :wink:

1 Like

A nice simple solution that would cover this use-case would just be to have an /etc/nixos/pkgs.json that was imported into configuration.nix. Then it would be pretty straightforward to write a tool that could add/remove JSON entries in that file. Would be a nice start, and an improvement over nix-env, IMO.

Could even have per-user files that were included in the user configuration.

2 Likes

There are certain uses for nix-env -i. For example, I use it on my NixOps-managed machines because running non-installed programs with nix-shell quickly becomes annoying, and rebuilding the entire NixOps network just to have something like telnet or iftop available for quick inspection is overkill.

2 Likes

I’d say that rebuilding the networking feeling like overkill is a deficiency of NixOps rather than a good reason for nix-env.

The main use I see for nix-env is systems that serve two (or more) people who each want to manage their installed software in isolation from one another (But, those people could do it declaratively with home-manager). Since I don’t have a system like that that I manage, I also try to avoid using nix-env and channels too.

Thanks for the tip!

2 Likes

The pkgs.json in addition to nix install seemed quite viable, so I made a proof-of-concept this evening: Pocnix: a proof-of-concept Nix CLI

1 Like

It needs to be pkg.pname instead of pkg.name. At least, on nixos-19.09.
Following the issue Wrong documentation for non-free packages · Issue #67830 · NixOS/nixpkgs · GitHub.

1 Like

Hah.

  1. The right solution appears to be checking for both pname and name as showed here.
  2. While parsing pkg.pname works, it is redundant.

    Notice that you shouldn’t have to apply builtins.parseDrvName to pkg.pname , as the latter already is the package name without the version suffix.

Example:

nixpkgs.config.allowUnfreePredicate =
  (pkg: builtins.elem (pkg.pname or (builtins.parseDrvName pkg.name).name)
    [ "unrar" ]);
1 Like