Hi. Recently I have been looking into solutions for installing third party packages on Steam Deck’s SteamOS. I have gone through a few options and now I am looking into Nix. I have been able to install Nix, get it functioning and installed some packages as well. But I have some questions. These stem from (my observation) that Nix moves very fast and there are sometimes multiple ways to do one thing. So I was hoping to toss some questions over to you folks to help a newbie out.
To install Nix (the non-determinate variant), I used nix-installer. I saw that it has a specific plan for Steam Deck so it seemed like a good choice. Here are the questions that I have. They are a bit vague because I don’t know enough to ask the right questions but any input is appreciated.
When I used NixOS, the process for installing packages was something like editing a configuration file then running nixos-rebuild switch. With only Nix, from my reading the way to install something would be nix-env -iA nixpkgs.firefox. Is this correct? During the internet searches I came across this page which suggests that nix-env is a “legacy command” so that seeded some doubt in my mind even though nix-env has served me well so far.
Is there a way I can use a declarative configuration to define which packages I want installed? This is not something I am ultra keen on but it would be nice to know. I found two repos for this: Keenan/home-manager-deck and Stream5710/deck-flake. So it seems like if I want a declarative configuration I will have to use home-manager.
Question 3 is a bit longer. I am trying to get tailscale running on the deck it is installed through nix-env right now. I need help unraveling the linking. The service file is installed at .nix-profile/lib/systemd/system/tailscaled.service. I symlink this to the relevant directory to make a system service out of it:
I have to systemctil edit tailscaled.service to define the environment variables the service expects. Then I enable the service with systemctl enable tailscaled.service. But the success message says this:
My concern here is that this symlink will probably be invalidated once tailscale is updated. Is my concern valid? If yes, what would be a better approach here? I think I could just copy /home/deck/.nix-profile/lib/systemd/system/tailscaled.service instead of symlinking to /etc/systemd/system/
Going declarative will absolutely give you a less awful experience than nix-env, though.
That said, nix is not a good package manager. I consider it primarily a decent build tool whose outputs have useful bonus properties, that has an excellent ecosystem around it which provides some of the best declarative system configuration tooling (home-manager and NixOS) out there - possibly the only usable tooling that can be used on bare metal, in fact.
Nix’ package management features primarily exist as tools to make writing the latter easier (though if you really know what you’re doing you can use them directly for some neat tricks).
As for the rest of your question… Just use home-manager. It provides declarative package management, so that bypasses the issues with nix’ built-in package management features, and it sorts out questions like “how do I manage systemd unit symlinks” for you through an activation script.
Ironically, nix moves pretty slowly. If you use just nix itself there is generally only one way to do things that was designed in the mid-2000s, and an eternally-experimental preview of how things may be done a bit better that is also flawed and hasn’t gone anywhere in 5 years.
The ecosystem around it morphs quite a bit, but this is just because there is a very active community - and because nix is a build tool, which means that there are a lot of different things you can do with it.
When you use the nix ecosystem to deploy software, however, there is mainly just NixOS and home-manager.
You’ll also see a lot of vaporware, frameworks that are really just leaky abstractions, scripts and other things which are hardly necessary. People write these because NixOS/home-manager requires a fair bit of technical understanding, and software folks have long been in the business of layering technically involved abstractions on top of each other in an effort to “simplify” things.
IMO newcomers will be much better off just sticking to learning how to use NixOS, or home-manager if they are using another distro, though, and just asking around here if they run into issues. These projects are by no means perfect, to be clear, but I don’t think the various frameworks really help fix the underlying problems.
Jovian - and other things which provide pre-made configs for specific hardware, e.g. nixos-hardware and nix-darwin - are a bit of an exception, since they are more targeted and can provide things NixOS cannot.
I didn’t want to cover that in detail, but sadly nix profile, especially when coupled with those buildEnv-based hacks, also has its own issues.
Primarily, nix profile install on a buildEnv package will install multiple copies of the env into the profile, and is pretty easy to fall for (as several people in that gist appear to). You need to deliberately nix profile upgrade instead.
Ironically, nix-env has fewer issues here, but I don’t think recommending nix-env in any capacity is responsible.
Nix certainly can be used like this if you’re careful and knowledgeable, but I don’t recommend using nix for package management directly to newcomers. Each built-in tool available has footguns and confusing semantics that really need to be managed by something more user-friendly.
I said or not and
Anyway, nix outside of NixOS generally sucks, I wouldn’t recommend it at all to newcomers. But if I have to meet them where they’re at, nix-env -iA nixpkgs.foobar is the worst introduction to nix with all the performance issues (it can take minutes to upgrade one package), syntax inconsistency, and broken upgrade behavior.
At the very least, nix profile can’t be worse in the way you describe, as it errors on conflicting files.