Nix shell to apptainer
How to create an apptainer image from a nix shell
Preface
Previously I have written about setting up nix to run on the University of Iowa’s compute cluster. At the time I noted some issues with this approach. These made the approach unusable long term and I needed another solution. The new solution I ended up adopting was building apptainer1 images from nix-shell definitions.
The Method
This is carried out in two steps. First we use
dockerTools.buildNixShellImage
to construct a docker image then
convert this to an apptainer image.
The following example is from my own projects. I use npins and standalone
shell.nix
files. The same idea works
with a flake, you just have to juggle the stuff around a bit. Here we create a
new file container.nix
:
{
system ? builtins.currentSystem,
pins ? import ./npins,
pkgs ? import pins.nixpkgs { inherit system; },
}:
pkgs.dockerTools.buildNixShellImage {
tag = "latest";
drv = import ./shell.nix { };
compressor = "none";
}
We then build the container with nix-build container.nix
. Our docker image now
lives in the nix store somewhere with the link result
pointing to it. We can
now convert this to apptainer:
apptainer \
pull \
container.sif \
docker-archive://$(readlink result)
This approach does not spark joy, but it works and that’s what I needed right now.
Why didn’t you just —
I tried other stuff, it didn’t work.
Use nixpkgs singularity-tools?
They are currently scuffed. Not a great sign that there is an issue titled Beat singularity-tools up to shape
Build the apptainer image in nix?
apptainer
really wants to talk to the internet, nothing I tried stopped it.
As this is not kosher in the nix sandbox we build out of the sanbox. I’m not
really sure why it feels the need to talk to the internet but oh well. I started
exploring siftool as a potential way to convert without apptainer but turned
back lest I get stuck in the rabbit hole.
-
Also known as singularity containers↩︎