Use packages from nixos-unstable in configuration.nix without nix-channel

2018-02-18

I recently installed NixOS on one of my laptops. One of the packages I wanted to install, k2pdfopt, was not available in the nixos-stable1 channel. I needed to install it from nixos-unstable.

When looking up how to install packages from nixos-unstable in /etc/nixos/configuration.nix, most instructions recommend adding the nixos-unstable channel with the nix-channel command. However, there is another way to that does not require using nix-channel. I present both ways below.

Using nix-channel

First, you need to use nix-channel to add the nixos-unstable channel2:

$ sudo nix-channel --add https://nixos.org/channels/nixos-unstable unstable
$ sudo nix-channel --update unstable

You can confirm that the channel has been added with the nix-channel --list command:

$ sudo nix-channel --list
nixos https://nixos.org/channels/nixos-17.09
unstable https://nixos.org/channels/nixos-unstable

This will download the nixos-unstable repository and put it in /nix/var/nix/profiles/per-user/root/channels/. This path can be found in your NIX_PATH environment variable.

With a directory called unstable/ existing in a directory in NIX_PATH, you will now be able to reference it in configuration.nix as <unstable>. This is used below to add the k2pdfopt packages from nixos-unstable to environment.systemPackages:

{ config, pkgs, ... }:

let
  unstable = import <unstable> {};
in {
  ...
  environment.systemPackages = [
    unstable.k2pdfopt
  ];
}

Without using nix-channel

The problem with using nix-channel is that you will no longer be able to run nixos-rebuild switch to setup NixOS on a new system. Instead, you will have to run nix-channel --add and nix-channel --update before running nixos-rebuild switch. For a distribution like NixOS that aims to be pure and immutable, this reliance on external state is tragic.

However, there is a way around this. It is possible to download and reference nixos-unstable directly in your /etc/nixos/configuration.nix file. It looks like this:

{ config, pkgs, ... }:

let
  unstableTarball =
    fetchTarball
      https://github.com/NixOS/nixpkgs-channels/archive/nixos-unstable.tar.gz;
in
{
  ...

  nixpkgs.config = {
    packageOverrides = pkgs: {
      unstable = import unstableTarball {
        config = config.nixpkgs.config;
      };
    };
  };

  environment.systemPackages = with pkgs; [
    ...
    unstable.k2pdfopt
  ];
}

This uses the fetchTarball function to download the nixos-unstable repository. It then uses packageOverrides to add a derivation called unstable to pkgs. This unstable derivation can be referenced as pkgs.unstable. It can be used within environment.systemPackages to install packages from nixos-unstable.

Conclusion

Installing packages directly from nixos-unstable in configuration.nix without depending on nix-channel makes it slightly easier when installing your configuration.nix on a new system.

Footnotes


  1. There actually is no nixos-stable channel. Instead, I am actually using the nixos-17.09 channel.

  2. Note that there are some non-obvious restrictions on what you can name the channel.

tags: nixos