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:
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
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
But how can we transfer an entire
“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
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
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
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'
/nix/store/path-to-flake with the path obtained from the clipboard. This command rebuilds the NixOS configuration on
on the specified
nix flake archive is a pretty neat command that deserves to be more documented!
See you in my next article 👋🏻!