Sending entire flakes with nix flake archive command
Nix offers a powerful and flexible tool for package management, including the ability to efficiently copy closures
between different machines.
A closure in Nix is essentially a container that includes everything needed to build or run a package. There are two types of closures: build closures
,
which contain all the dependencies necessary to compile the package, including compilers and shell utilities, and runtime closures
, which cover
everything required to run the package’s programs, such as configuration files and dynamically linked libraries.
Unlike file transfer tools like rsync
or scp
, which operate on files and directories in a procedural manner, Nix manages complete closures declaratively.
You simply specify ‘what’ you want to copy, and Nix takes care of the ‘how’, ensuring that all necessary dependencies are also copied, eliminating the
need to manually manage dependency trees, a process prone to errors.
For example, to copy the famous hello
application to another machine with Nix installed and run it there, you would write:
$ nix copy --to ssh-ng://my-machine .#hello
This command will automatically send all the dependencies necessary to run hello
on the specified machine with the --to
argument, using the ssh protocol
(although as a prerequisite the destination machine must have nix
installed).
But how can we transfer an entire flake
?
“Flakes” are a feature of nix
that allows you to define a set of packages and configurations in a reproducible and consistent manner
(here’s a guide on Nix flakes if you need more information).
To transfer a complete environment defined by a flake
, you can use the command nix flake archive
:
$ nix flake archive --to ssh-ng://my-machine
And this way you would have the entire flake
on my-machine
! Nice!
If we think carefully, we can take advantage of the previous command to just create a poor’s man version of
colmena-rs or deploy-rs to update your systems with nix
.
We can do it as it follows:
$ nix flake archive --to ssh-ng//my-machine --json | jq -r '.path' | wl-copy
The above command copies the path of the flake
on the destination machine to the clipboard (in my case I am using wayland
so I use wl-copy
to copy the path of the flake to the clipboard). To apply the flake
configuration to the destination machine, you can execute:
$ ssh my-machine 'nixos-rebuild --flake /nix/store/path-to-flake#$(hostname) test'
Replace /nix/store/path-to-flake
with the path obtained from the clipboard. This command rebuilds the NixOS configuration on my-machine
based
on the specified flake
.
nix flake archive
is a pretty neat command that deserves to be more documented!
See you in my next article 👋🏻!