Nix's inherent design is well-suited for remote deployment, and the Nix community offers several tools tailored for this purpose, such as [NixOps](https://github.com/NixOS/nixops) and [colmena](https://github.com/zhaofengli/colmena). Additionally, the official tool we've used extensively, `nixos-rebuild`, possesses some remote deployment capabilities too.
Before embarking on remote deployment, a few preparatory steps are necessary:
1. To prevent sudo password verification failures, either deploy as the `root` user or grant the user sudo permission without password verification.
2. Configure SSH public key authentication for the remote hosts.
It's advisable to use the `root` user for deployment as it's more convenient and avoids the complexities of sudo permissions.
Assuming we intend to deploy remotely using the root user, the initial step involves configuring SSH public key authentication for the root user on the remote host.
To accomplish this, simply add the following content to any NixOS Module in the remote host's Nix configuration (e.g., `configuration.nix`), then rebuild the system:
```nix
# configuration.nix
{
# ...
users.users.root.openssh.authorizedKeys.keys = [
# TODO Replace with your own SSH public key.
"ssh-ed25519 AAAAC3Nxxxxx ryan@xxx"
];
# ...
}
```
Furthermore, you'll need to add the SSH private key to the SSH agent on your local machine for authentication during remote deployment:
```bash
ssh-add ~/.ssh/your-private-key
```
## Deploy through `colmena`
`colmena` doesn't directly use the familiar `nixosConfigurations.xxx` for remote deployment. Instead, it customizes a flake outputs named `colmena`. Although its structure is similar to `nixosConfigurations.xxx`, it's not identical.
In your system's `flake.nix`, add a new outputs named `colmena`. A simple example is shown below:
```nix
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05";
# ...
};
outputs = { self, nixpkgs }: {
# ...
# Add this output, colmena will read its contents for remote deployment
colmena = {
meta = {
nixpkgs = import nixpkgs { system = "x86_64-linux"; };
# This parameter functions similarly to `sepcialArgs` in `nixosConfigurations.xxx`,
# used for passing custom arguments to all submodules.
specialArgs = {
inherit nixpkgs;
};
};
# Host name = "nixos-test"
"nixos-test" = { name, nodes, ... }: {
# Parameters related to remote deployment
deployment.targetHost = "192.168.5.42"; # Remote host's IP address
Using `nixos-rebuild` for remote deployment has the advantage of being similar to deploying to a local host. It only requires a few additional parameters to specify the remote host's IP address, username, and other details.
For instance, to deploy the configuration defined in the `nixosConfigurations.nixos-test` of your flake to a remote host, use the following command:
The above command will build and deploy the configuration of `nixos-test` to a server with IP `192.168.4.1`. The system build process will occur locally.