Deploying to remote machines
Once a config lives in a flake, you do not have to sit at the target machine to
apply it. nixos-rebuild can build a configuration and activate it on a remote
host over SSH, and a few higher level tools add safety and scale on top of that.
The built-in way with nixos-rebuild
nixos-rebuild understands two location flags. --target-host is the machine
where the configuration is activated, and --build-host is the machine that
compiles it. Point both at the server to build and switch entirely on the remote.
nixos-rebuild switch \
--flake .#server \
--target-host root@server.example.com \
--build-host root@server.example.comOmit --build-host to build on your laptop and copy the finished closure to the
server, which is handy when the server is small and your laptop is fast.
nixos-rebuild switch --flake .#server --target-host root@server.example.comIf you connect as a normal user rather than root, add --use-remote-sudo so the
activation step runs with sudo on the far side.
nixos-rebuild switch --flake .#server \
--target-host you@server.example.com --use-remote-sudoPrerequisites
Three things need to be true before any of this works. You need SSH access to the
host, the host already needs to be running NixOS, and the flake needs to expose
the host as nixosConfigurations.<host>. The first deploy onto a machine that is
not yet running NixOS is a different job, covered by nixos-anywhere below.
Copying closures directly
Sometimes you just want to move a built result to another machine without
activating anything. nix copy sends a store path over SSH.
# build locally, then copy the result to the server's store
nix build .#nixosConfigurations.server.config.system.build.toplevel
nix copy --to ssh://root@server.example.com ./resultHigher level tools
The built-in flags are enough for one host. For more than that, reach for a tool built around deployments.
- deploy-rs builds each node, copies the closure, and activates with an automatic rollback if the new system fails to come back online. It is a good fit when you cannot afford to lose access to a remote machine.
- colmena describes a fleet of hosts in one file and deploys them in parallel, which suits a set of servers you manage together.
- nixos-anywhere installs NixOS onto a machine that is not running it yet, including partitioning, over SSH. Use it for first-time provisioning.
A minimal deploy-rs node looks like this in the flake.
{
deploy.nodes.server = {
hostname = "server.example.com";
profiles.system = {
user = "root";
path = deploy-rs.lib.x86_64-linux.activate.nixos
self.nixosConfigurations.server;
};
};
}nix run github:serokell/deploy-rs -- .#serverA multi-host flake recap
One flake can hold many hosts that share a common module. Deploy whichever one
you mean by naming it after the #.
outputs = { self, nixpkgs, ... }: {
nixosConfigurations = {
laptop = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./common.nix ./laptop.nix ];
};
server = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./common.nix ./server.nix ];
};
};
};# deploy only the server, from your laptop
nixos-rebuild switch --flake .#server \
--target-host root@server.example.comAdvanced
For repeated remote builds, register build machines so heavy compiles run on a
beefier host with nix.buildMachines. Pairing that with a shared
binary cache means most paths are downloaded rather than built,
which makes remote deploys fast even over a slow link.
{
nix.buildMachines = [{
hostName = "builder.example.com";
systems = [ "x86_64-linux" ];
maxJobs = 8;
sshUser = "nix";
}];
nix.distributedBuilds = true;
}Next
For the flake outputs you deploy see Flakes, for full host configs see Examples, for keeping credentials off the wire see Secrets management, and for the commands behind these workflows see Commands and scripts.