Sure, you can do it easily, with multiple methods. Since nix considers channels and programs as just variables, you can do many different things. If you really want to, you can clone the whole nixpkgs and just point your channel to this clone, e.g. via:
nix-channel --add https://your/nixpkgs/clone nixos
but maintaining a clone of nixpkgs might be a bit tedious. You can also create a channel (a channel is nothing more that a set of programs) containing only the programs you wish to install this way, read below for more details. Another, more recommended option, is to use overlays:
{ config, pkgs, lib, ... }:
{
# [...]
nixpkgs.overlays = [ (final: prev: { yourPackage = pkgs.stdenv.mkDerivation {…}; } ];
}
This also allows you to change only the version of a package based on a package already existing in nixpkgs, for instance using overrideAttrs
, you can read more here Overlays - NixOS Wiki or in the manual. Overlays have the advantage that if you modify an existing package, it will also use that version in NixOs modules (e.g. the gitea module), which might not be the case by default with other methods.
Since programs are just variables, you can also just install a program like:
{config, ...}:
{
environment.systemPackages = [
# create a new package from scratch
(pkgs.stdenv.mkDerivation {…})
# Install a package from nixpkgs
emacs
# Create a new package from an old one coming from nixpkgs
(vim.overrideAttrs {…})
];
}
If your derivation is getting long/complex, you can also put in a different file myProgram.nix
:
{stdenv, any, other, dependency, like, gtk3}:
stdenv.mkDerivation {
…
}
and in your configuration just add:
environment.systemPackages = [
(pkgs.callPackage ./myProgram.nix {})
];
(this is the method I choose most of the time as it is simple to maintain, and packages are directly included in the git repository of my configuration)
Finally, you can also create a channel containing only the programs you like (so no need to take the whole nixpkgs), and do something like:
nix-channel --add https://your/channel yourchannel
where the channel contains a default.nix
file containing:
{ pkgs ? import <nixpkgs> {} }:
{
yourFirstPackage = pkgs.stdenv.mkDerivation {};
}
and change your configuration using something like:
{config, pkgs, ...}:
let yourChannel = import <yourchannel> { inherit pkgs; }; in
{
environment.systemPackages = [
yourChannel.yourFirstPackage
];
}
You can also “pin” yourChannel
to a precise url like:
let yourChannel = import (builtins.fetchGit {
# Descriptive name to make the store path easier to identify
name = "nixos-unstable-2018-09-12";
url = "https://github.com/nixos/nixpkgs/";
# Commit hash for nixos-unstable as of 2018-09-12
# `git ls-remote https://github.com/nixos/nixpkgs nixos-unstable`
ref = "refs/heads/nixos-unstable";
rev = "ca2ba44cab47767c8127d1c8633e2b581644eb8f";
}) {}
Many options!