Difference between installing via nix-env and configuration.nix?

I’m new to Nix and NixOS and have been installing new packages by adding them to environment.systemPackages in /etc/nixos/configuration.nix then rebuilding, which I thought was the same as using the package manager. Today I used nix-env -i hello and realized that it doesn’t put that package in the configuration.nix file.

What’s the difference between those installation methods? Is it like installing to /Applications vs ~/Applications on macOS?

3 Likes

packages listed in configuration.nix get added to a system profile. This also gives you the generations

no, nix-env is meant to give you a similar experience to other package managers, however, i manages it’s own gcroots (what derivations can be cleaned up), and even generations. Generally you should avoid using nix-env for package installation as it doesn’t leverage the power of nix.

Somewhat. In terms of user vs system installation, yes. However, nixos is different from normal FHS operating systems in that there’s a layer of indirection when you install something, so your PATH and other environment variables just reference the current “profile” or generation

$ echo $PATH
/run/wrappers/bin:/home/jon//.nix-profile/bin:/etc/profiles/per-user/jon/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:/home/jon//.cargo/bin:/home/jon//.config/nixpkgs/bin

/home/jon//.cargo/bin:/home/jon//.config was added by me.

2 Likes

This is marked as solution but tbh it makes me more confused. :smiley:

So nix-env is supposed to behave like a traditional package manager but then somehow throws out some of Nix’s advantages with the bath water?

I’m not sure what the gcroots and generations are. Could somebody explain, please?

1 Like

Unfortunately, nix covers a lot of surface area. So I apologize if I didn’t clarify much :frowning:

You can take a look at Nix Pills | Nix & NixOS which goes from a fundamentals perspective and works its way up the nix stack.

EDIT: I also have some videos which cover different topics in nix https://www.youtube.com/channel/UC-cY3DcYladGdFQWIKL90SQ , unfortunately I haven’t made one on specifically nix-env yet

1 Like

Ok, so…then what should we use? The site you linked to literally says to use nix-env -i to install packages [1].

I’m just getting started with NixOS, too, and it’s unfortunately full of bad omens so far.

[1] Nix Pills | Nix & NixOS

The preferred way is to use declarative ways of installing packages. The most common ways to do so is the system configuration (/etc/nixos/configuration.nix) or home-manager.

Also, I’d warn about reading the pills as a beginner. It explains installing quite nice, but then does a deep dive into the inner workings of nix. Though nixpkgs provides a lot of nice abstractions, such that direct usage and understanding of builtins.derivation is rarely necessary. Reading the pills becomes necessary once you either want to understand how mkDerivation works or you want to implement your own version of it from scratch.

3 Likes

Thanks. I like the idea of installing everything via /etc/nixos/configuration.nix. I would like to have a 100% reproducible setup.

You brought up home manager. How can I install this via /etc/nixos/configuration.nix.? The official instructions seem to go off the rails and have us run imperative commands: nix-channel, nix-shell, etc. Do I have to remember to run these commands again after I rebuild?

1 Like

The README only covers standalone installation.

On top of that the manual covers installing standalone, nixos module and Darwin module.

All require to imperatively set up channels at least.

This is due to the fact that there is currently no declarative channel management.

1 Like

Seems a little ironic how many NixOS-centric tutorials and READMEs are pushing non-NixOS-philosophy instructions. As a NixOS beginner it’s felt as though I’m constantly jumping through hoops just to find out how to do things “the right way”.

Anyway, thanks!

4 Likes

What exactly do you mean?

Most instructions and blog posts I’m aware of, do as little imperative things as possible and then use declarative tooling.

Sadly there are still things you can’t do declaratively without jumping through even more hoops.

Without flakes it’s not trivial to manage/pin your channels. Without flakes, it’s actually not common that people even use one of the various pinning techniques, though if they do, they usually know how to translate the imperative commands into their specific declarative way.

1 Like

What exactly do you mean?

I mean the little NixOS documentation that does exist [1][2][3] doesn’t explain NixOS package management to beginners clearly enough, and most Google search results for the subject are misleading.

For example the official NixOS manual [3], when it first introduces nixos-rebuild switch, introduces it quite robotically in a way that only someone already versed with NixOS could understand—it took me a full day to understand how to install packages. Googling “NixOS how to install packages” was a frustrating experience, and the few Reddit/Stackoverflow/blog results will trick a newbie into using nix-env -i [4][5][6] and concluding that’s how you do it in NixOS, because it reminds them of other package managers and so fits their old mental model.

Without flakes it’s not trivial to manage/pin your channels.

Next, then, I’ll need to learn what channels flakes are. :slight_smile:

[1] Learn Nix | Nix & NixOS
[2] Nix Pills | Nix & NixOS
[3] NixOS 23.11 manual | Nix & NixOS
[4] nixos - How can I install some nix packages? - Stack Overflow
[5] https://www.reddit.com/r/NixOS/comments/67njbp/how_do_you_install_packages_from_nixpkgs/
[6] How to use NixOS Package Manager?

3 Likes

I’ll just add that I’m having similar confusing experiences trying to use nix “the right way” as well. Just trying to figure out how to install docker was a day-long experience, and I ended up using nix-env -i because that’s the only example I could find. Everything nix-related seems to focus on the BUILDING rather than the USING of software. So for someone coming fresh to nix, it’s frustration after frustration just trying to USE the system as it’s supposed to be used (as in, I want my machine to be deterministic, so I can just save the config files, destroy the system, rebuild, and be back where I started).

This gets even more frustrating because every blog post, manual, and example is couched in terms of “You could do it this way or that way or this other esoteric way or …”

As a beginner, I don’t have the mental model to process the millions of ways to do the same thing and by-the-way-there-are-these-other-wonderful-shiny-features-over-here. I’m left screaming in frustration “Won’t someone PLEASE just post an opinionated, best-practice-for-nixos way of using my system in the day-to-day???” It starts to feel like CMake documentation after awhile. OK, rant off.

5 Likes

I think this thread is a great chance for us to reflect on some of the failures of our documentation, esp. when it comes to onboarding new users. Although the nix ecosystem has a lot to offer, it is quickly moving and a lot of different documentation suggests many different approaches to solving the same problem. Nix also has a plethora of different concepts: derivations, the language itself, channels, nix-env, nix-shell, flakes, nix-foo commands vs nix foo commands, generations, GC, and so on. It’s kind of a nightmare.

I remember going through the rough patches in the beginning as well, and I still don’t understand everything that nix has to offer. IMHO we ought to rethink what kind of “first impression” experience we want newcomers to have.

For a start I’d like to propose that we

  • Deprecate nix-env -i installation with a warning message. Replace it with nix-shell on https://search.nixos.org/ and all of the documentation.
  • Make it dead-simple to install home-manager straight from nixpkgs, no channels funny business. Pointing users towards home-manager straight away will help to alleviate many of the “how do I do X in nix?” issues.

It would also be great to have some kind of semi-official tutorial/video/documentation that walks newcomers through the basic steps of installing and setting up nix, opinionated towards the tools/patterns of the future and avoiding all of the cruft from the past (cough nix-env cough).

3 Likes

One big impediment to newcomers is the lack of support/documentation for running in a VM. After finally getting it to work in libvirt, I wrote up instructions here: Test-driving a NixOS VM using libvirt - 🪄 Technical Sourcery

Unfortunately, I’m still stuck at this point because I’m not sure how to:

  • Install software without it being local to my home dir, and thus destroyed when I rebuild the machine
  • Run containers (there seem to be three ways to do this and no blessed way?)
  • Set up samba file sharing
  • Make sure certain directories get created
  • Mount certain disks at boot
  • Run periodic tasks
  • Set up a bridge
  • Build configurations that will be compatible with what other people are doing, so that I can incorporate others innovations

The information for all of this is technically out there, but it feels a lot like plotting a road trip from Berlin to Capetown using only a world map.

1 Like

I’m not 100% sure I understand what you mean, but packages installed via home-manager or via configuration.nix will be preserved across rebuilds!

What I mean is: I want to take what I have on machine A and save it so that I can destroy machine A and rebuild it from scratch in a deterministic way, or I can take machine A and replicate it to machine B without copying gigabytes of OS data (just my configuration, then rebuild the exact same env on the new machine). That’s really what I’m hoping for in nixos. Something like terraform or ansible on steroids, where everything I want to run is just a nixos-install on a blank machine away.

Ideally, my /etc/nixos dir would be a git repo, so whenever I change something, I can commit and push those changes. Then rebuilding/replicating the machine is a git clone + nixos-install away.

You’ve described the way to do it, make a git repository from your /etc/nixos and clone it next time you want to install it on a new machine; The one thing that’s less easy to do declaratively is managing /etc/nixos/hardware-configuration.nix, since it will be different for every machine. I recommend just running the configuration generation script once before cloning on a new machine, and adding a file for that specific machine, import-ing it based on hostname.

If you’re looking for how to install packages, modify this setting in /etc/nixos/configuration.nix: environment.systemPackages.

If you used the installation instructions, you should already have some basic configuration doing exactly that while explaining it too :slight_smile:

There is a documentation problem, at least for the official docs. I think I learned by scouring other people’s repositories on github - it would be great to have a basic tutorial for “basic declarative install from git” in the manual.

Deprecating nix-env -i seems important too, it’s nothing but a footgun that confuses new users, I have never used it.

1 Like

Use environment.systemPackages in configuration.nix.

Why there should be just one blessed way when there are multiple technologies to do that? That said, the simplest way is to use containers.<name> entry in configuation.nix.

See for an example my home server configuration.

You can use the activation scripts or systemd.tmpfiles.rules.

Just use normal fstab or systemd’s mount configs, see for an example one of my machines configuration.

Use systemd.timers entry.

Use networking.bridges.

You have to be more specific, but generally looking into man configuration.nix is a great starting point :wink:

2 Likes