Hi there. I manage some NixOS machines, which are pinned to a particular stable branch from 2019, and I’m fine with this.
However, the version of certbot that this branch offers is 0.31.0, while unstable has 1.0.0. I’d like to upgrade, and do so via the usual environment.systemPackages list. However, I don’t want to update the whole channel (thus bumping everything else on the system), just certbot.
@dalto Is there a way to add the unstable nix channel within one’s configuration.nix ?
@fosskers You had a perfectly valid question there, I see no reason to withdraw it. The answer can be found elsewhere, but it is good to have multiple references for visibility. Unfortunately the prominent NixOS Wiki search result does not even feature it. Really it is a combination of that and the example on pinning nixpkgs:
# configuration.nix
{ config, pkgs, ... }:
let
unstable = import
(builtins.fetchTarball https://github.com/nixos/nixpkgs/tarball/<branch or commit>)
# reuse the current configuration
{ config = config.nixpkgs.config; };
in
{
environment.systemPackages = with pkgs; [
nginx
unstable.certbot
];
}
You should of course specify a hash, and probably a derivation name, my example is simplified for readability. Check the Nix manual for builtin function specs.
To install packages declaratively as a regular user you can use home-manager. The respective code in home.nix would look exactly the same, except replace environment.systemPackages with home.packages.
Since nobody has mentioned it, for flake users this is substantially simpler since one can declare multiple versions of nixpkgs as an input. Then one can use an overlay to place the contents of a single package from nixos-unstable into the base system.
Also, @nixinator this isn’t possible by default, but one can easily pull a module from unstable nixpkgs manually, while adding the old version to disabledModules.
I have a (not so minimal) example available in my DevOS project.
To fully understand what’s going on you’ll want to look at the logic, and the place where overrides are declared.
The reason this isn’t minimal is because it tries to automatically disable a module that is pulled from the override nixpkgs input.
To do it manually in stable nix one would simply add the module name relative to the nixpkgs/nixos/modules directory to disabledModules, then import the alternative version from a reference to another nixpkgs:
# some NixOS module
let
someOtherNixpkgs = builtins.fetchurl # some nixpkgs url
;
in
{
# if your NIX_PATH contains another nixpkgs reference,
# you can use the <some_nixpkgs/nixos/modules/...> syntax instead
imports = [ "${someOtherNixpkgs}/nixos/modules/programs/steam.nix" ];
disabledModules = [ "programs/steam.nix" ];
}
The configuration settings come from modules, not packages. The NixOS module system is much more involved, but you can substitute out a module from an old nixpkgs with one from a new nixpkgs: NixOS 23.11 manual | Nix & NixOS
This is much less likely to work properly, after all any differences in underlying modules could break things quite a bit, but if it’s a completely new module and for something relatively simple as in your case it will usually be fine.