There seems to be a dozen different ways to install packages on NixOS, so googling for help keeps giving me results for things like flakes, “nix profile”, and “nix env”, which I’m not familiar with.
I’ve install all my packages using what seemed to be the standard config file:
/etc/nixos/configuration.nix
environment.systemPackages = with pkgs; [
android-tools
chromium
cryptsetup
...
When installing something, I add it to that list and run sudo nixos-rebuild switch or if I want to install something temporarily, I just run nix-shell -P pkg.
I now need to update signal-desktop to the latest version, but I don’t want to update any other installed packages. How can I do that?
The way I understand it is that this is not really intended because that would just increase the amount of dependencies that you need. So there is no way to keep the old ones and just declare that new one but there is a way to declare that you want to keep the older versions of the other programs you use. This is done through overrides. In that case you need to specify how that package is supposed to be build.
I thought one of the main benefits of NixOS was that packages were installed with all of their dependencies independent from other packages. Shouldn’t that make upgrading a single package easy? What do you recommend I do?
Going through all the dozens of packages I’ve installed and pinning them with explicit versions seems like a lot of work. Eventually I’m going to want to upgrade them, but not every time I want to bump a single package version.
Assuming the version of signal-desktop you want has already been packaged, you can “pin” the package, following the instructions from the NixOS Wiki on Pinning Nixpkgs. Specifically, you can do something like this:
environment.systemPackages = with pkgs;
let myPkgs = import (builtins.fetchTarball {
url = "https://github.com/NixOS/nixpkgs/archive/9957cd48326fe8dbd52fdc50dd2502307f188b0d.tar.gz"; #Change this URL accordingly
}) {}; in [
android-tools
chromium
cryptsetup
myPkgs.signal-desktop
...
];
Solutions have been mentioned, but I’ll try to add some clarification:
NixOS is based on the nixpkgs repo. Whenever you build a system generation, this is connected to a certain commit in this repo, which means you will get the program versions (e.g. for Signal Desktop) as defined by this commit.
When you update, either via nix-channel --update or via nix flake update, you look up the nixpkgs repo and move your inputs for the next rebuild to the latest commit in a certain branch of Nixpkgs.
To mix program versions of different age, you can have multiple named pointers to different commits in nixpkgs (and other repos). The you can select the desired package via the named pointer. By default you get pkgs and the with pkgs;" tells nix to look up e.g. chromium by name and if not found to continue searching in the pkgs namespace.
When you follow the posted solutions, you will mainly find people using the current release of NixOS and mixing in the unstable branch, but you can also import the release-14.04 as oldandtrusty and then use oldandtrusty.firefox in your configuration.
If you need a special version of a program you need find a matching commit in the nixpkgs history where this exact version was defined/packaged.
That said, if the build recipe for the desired package hasn’t changed, it is often desirable to simply override the version and source hash to benefit from sharing dependencies with your base set of packages.