Is this a sensible way to setup nix-shell for development and CI?


#1

I’m taking my first major steps with nix and I’m wondering how people are setting up their nix-shell development environments.

Is this a sensible way to be doing things?

{
  stable ? import (builtins.fetchTarball {
             url = "https://github.com/NixOS/nixpkgs/archive/18.09.tar.gz";
             # Hash obtained using `nix-prefetch-url --unpack <url>`
             sha256 = "1ib96has10v5nr6bzf7v8kw7yzww8zanxgw2qi1ll1sbv6kj6zpd";
           }) {},
  unstable ? import (builtins.fetchTarball {
               url = https://github.com/nixos/nixpkgs-channels/archive/44b02b52ea6a49674f124f50009299f192ed78bb.tar.gz;
               # Hash obtained using `nix-prefetch-url --unpack <url>`
               sha256 = "0gmk6w1lnp6kjf26ak8jzj0h2qrnk7bin54gq68w1ky2pdijnc44";
             }) {}
}:
with stable;
stdenv.mkDerivation {
  name = "env";
  buildInputs = [
    awscli
    unstable.bazel
    git
    kubectl
    python37
    ...
  ];
}

What I’m looking for here is creating a reproducible environment in a declarative way, with dependencies, but also a way to pull in certain packages from unstable. It appears to work, but I’m not sure if it’s a terrible idea.

The next step on top of that, would be adding custom derivations for things that are not yet in nix. Or I guess I can just create a repo for custom derivations and then have (stable, unstable, custom).

Thoughts?


#2

This will work but you now need to track multiple nixpkgs. Also, you’ll likely run into problems mixing python dependencies from stable and unstable. I like to use overlays for this and separate out the package definition. I typically have a

  • package.nix containing {stdenv, awscli, git, python, ...}: stdenv.mkDerivation...
  • release.nix which imports the appropriate nixpkgs, applies overlays if any, then callPackages the package.nix

Does this fit your use case
https://nixos.org/nixpkgs/manual/#chap-overlays ?

Edit: fix link, typo


#3

If you don’t care for using Nix for the actual build but only want to get a shell with dependencies, there’s also mkShell: https://nixos.org/nixpkgs/manual/#sec-pkgs-mkShell


#4

Thanks. I’ll check it out.

My actual use-case is to use Bazel to build components inside a monorepo, but I’d like to use Nix for managing the handful of external toolchains that Bazel doesn’t easily provide.

i.e. I’d like to pin Python and other utility binaries that we use for our local developement, CI test and build.

So, essentially, I imagine that developers and CI could enter the nix-shell with --pure and should be able to execute tests and build artifacts.


#5

Yes, sounds sensible to me, including an expression like the one above.