Deploying and Binary Cache

The way Nix is designed enables to explicitly describe a package. More specifically, one side effect of creating a derivation is that the inputs of a package are stated and that the package build process is expressed. These properties provide a way to share and distribute code packages that can be built in the same way in another machine with a Nix installation.

Yet, building a package can be relatively long, for instance compiling SimGrid can take several minutes. In addition, some experiments can be designed to be executed into a set of machines, and thus one may need to deploy a specific software environment into several machines. Nix offers the possibility to export packages from one Nix store to another Nix store.

Store import & export

Every package is located into the Nix store and is identified by a cryptographic hash of its inputs. For instance the chord package defined in section Experiment Packaging: Don’t Repeat Yourself should exactly have the following path (on a x86_64-linux system).

$ nix-build https://gitlab.inria.fr/nix-tutorial/packages-repository/-/archive/master/packages-repository-8e43243635cd8f28c7213205b08c12f2ca2ac74d.tar.gz -A chord
>> /nix/store/km39s468afmv1rmykkbk8gipgdfhi6ph-chord-0.1.0

You might have noticed that this command does not compile the simulator at each call. This is because nix-build looks into the store whether the package can be found. This is made possible thanks to the hashing of the package inputs (and thanks to the package name).

Packages in the store have may have references to other packages. For example, the references of the chord package can be listed with the following command (assuming that you have run the previous command, that generated a link from ./result to /nix/store/km39s468afmv1rmykkbk8gipgdfhi6ph-chord-0.1.0).

$ nix-store --query --references ./result
>> /nix/store/d2bpliayddadf6lx6l1i04w265gqw8n6-glibc-2.34-210
>> /nix/store/q9gfnkp0zaafccpgj4mqngmp9f9y93xh-gcc-11.3.0-lib
>> /nix/store/7n338lngr6m7n8903d34wrb21ppda6in-simgrid-3.31

Nix enables to recursively list the references of a package, which is called a closure in Nix terminology. The closure of the chord package can be displayed with the following command.

$ nix-store --query --requisites ./result
>> ...

Nix closures can easily be exported out of a store into a Nix ARchive (NAR) thanks to nix-store’s --export option. The following command creates a chord.nar from the chord package closure.

nix-store --export $(nix-store --query --requisites ./result) > chord.nar

The resulting NAR file can be imported into a Nix store, on the same machine or another one.

nix-store --import < chord.nar

Note

If the machines have a different architecture, importing the closure might not help the second machine, as the packages would not be available in the architecture it desires. In this case, the second machine would fetch the required packages from a binary cache if possible, or rebuild them otherwise.

Nix Copy Closure

Exporting and importing closures can be useful, it can be used to share ready-to-use applications. Its usage can be compared to the sharing of docker images that bundle a given application.

However, in some cases it is not required to export the whole closure as some dependencies can already be present on the target machine.

In that case, one should consider using the nix-copy-closure command. This command copies a closure from one store to another, but it only transfers the dependencies that are missing on the target host.