Nix Shell Container#
We focus here on the shells produced by the mkShell
function.
The shell environments produced are not isolated from the environment of your machine.
Consider the following flake.nix
:
{
inputs.nixpkgs.url = "github:nixos/nixpkgs/23.05";
outputs = { self, nixpkgs }:
let
system = "x86_64-linux";
pkgs = import nixpkgs { inherit system; };
in {
devShells.${system}.default = pkgs.mkShell {
packages = [ pkgs.gcc ];
};
};
}
When entering the shell (nix develop
), the environment will contain the disired gcc
on top of your current environment.
One way to isolate the shell would be to create a Docker container, build it, load it, and run it.
But this is cumbersome.
A better way would be to isolate the shell without any extra dependency.
The Nix4Science flake provides a way to do so by using the Linux user namespace feature.
First, let’s import the flake as n4s
.
This flake provides a replacement for the mkShell
fonction: n4s.lib.${system}.mkShell
.
By default it behaves like mkShell
, but we can activate the containerization of the shell by setting the containerize
parameter:
{
inputs.nixpkgs.url = "github:nixos/nixpkgs/23.05";
inputs.n4s.url = "github:nix4science/n4s";
outputs = { self, nixpkgs, n4s }:
let
system = "x86_64-linux";
pkgs = import nixpkgs { inherit system; };
in {
devShells.${system}.default = n4s.lib.${system}.mkShell {
containerize = true;
packages = [ pkgs.gcc ];
};
};
}
Now, calling nix develop
will start the shell in a containerized environment!
However, this method cannot accept to run command inside the container like nix develop --command gcc --version
.
This is because of the way Nix manages the --command
flag.
Our workaround is the following:
{
inputs.nixpkgs.url = "github:nixos/nixpkgs/23.05";
inputs.n4s.url = "github:nix4science/n4s";
outputs = { self, nixpkgs, n4s }:
let
system = "x86_64-linux";
pkgs = import nixpkgs { inherit system; };
in {
packages.${system}.default = n4s.lib.${system}.mkShellContainer {
packages = [ pkgs.gcc ];
};
};
}
Now, instead of running nix develop
you have to run nix run
.
To pass a command, simply append the command after --
:
nix run . -- gcc --version