WillW
WillW

Reputation: 891

How do I apply a nix-shell config in a docker image?

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.

Upvotes: 10

Views: 3386

Answers (2)

WillW
WillW

Reputation: 891

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.

Upvotes: 2

Robert Hensing
Robert Hensing

Reputation: 7369

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.

Upvotes: 7

Related Questions