9

I’m trying to use Nix as a way of unifying my local development environment and the docker based Gitlab CI build that I’m using.

I have a simple shell.nix that works perfectly - I can run nix-shell locally and get everything I need.

If, in my CI config I then use nixos/nix:latest as my docker image, and surround every command with nix-shell --run "xxx" that all works. That nix-shell all over the place is tedious to maintain and hard to read what is actually going on. What I'd like to do is apply that configuration to the docker image somehow as the first command, so that the environment is available to all the subsequent build commands.

I think what I want is something like nix-env -f shell.nix -i but that fails with “This derivation is not meant to be built, aborting”.

Thanks in advance.

WillW
  • 871
  • 6
  • 18

2 Answers2

7

You can use buildEnv to combine your tools into a single derivation.

default.nix:

{ pkgs ? import <nixpkgs> {} }:

pkgs.buildEnv {
  name = "my-tools";
  paths = [
    pkgs.hello
    pkgs.figlet
  ];
}

Now you can install your tools in the docker image:

nix-env -i -f default.nix

And use it in your shell.nix:

{ pkgs ? import <nixpkgs> {} }:

pkgs.mkShell {
  name = "shell-dummy";
  buildInputs = [ (import ./default.nix { inherit pkgs; }) ];
}

See also the Declarative Package Management section in the Nixpkgs manual.

Robert Hensing
  • 6,708
  • 18
  • 23
  • Thank you for your answer, I hadn't quite understood what `buildEnv` was for so that is very helpful. – WillW Oct 18 '19 at 15:45
2

This is the magic command:

nix-env -f shell.nix -i -A buildInputs

This uses the buildInputs list in mkShell as a list of derivations to install into the environment. This is simpler, but represents a less clean separation of concerns than Robert's answer.

WillW
  • 871
  • 6
  • 18
  • 1
    This will install them as separate packages, whereas my solution installs a single "my-tools" package with everything in it. This matters for `nix-env -q`, `nix-env -e`. What's best depends on your use case. For a docker image it shouldn't matter. – Robert Hensing Oct 18 '19 at 17:18
  • Yes, I realised that and that's why yours is the accepted answer! – WillW Oct 19 '19 at 18:49