The Hive
A Hive is the configuration that describes your fleet. It is a Nix attribute set
where most attributes are nodes, and a few reserved attributes configure Navi
itself. Navi presupposes flakes, so the Hive lives under the navi output of a
flake.
Create a flake.nix:
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
outputs = { nixpkgs, ... }: {
navi = {
meta.nixpkgs = import nixpkgs { system = "x86_64-linux"; };
defaults = { pkgs, ... }: {
environment.systemPackages = [ pkgs.vim pkgs.curl ];
};
web-01 = { name, nodes, pkgs, ... }: {
deployment.targetHost = "web-01.example.com";
services.nginx.enable = true;
system.stateVersion = "24.11";
};
};
};
}
Navi searches upward from the working directory for a flake.nix unless you
pass --config. Because nixpkgs comes from a flake input rather than the
channel, evaluation stays pure.
Reserved attributes
Two attribute names are reserved and are not treated as nodes.
meta configures the Hive as a whole. The most important field is nixpkgs,
which selects the package set every node is built against. Under flakes it must
be set from an input.
defaults is a NixOS module merged into every node. Put configuration that all
machines share here, such as common packages, users, or SSH settings.
Nodes
Every other attribute in the navi output is a node, and its value is a NixOS
module. The node name is the attribute name. Inside a node, the deployment
options control how Navi connects and applies the configuration. The rest is
ordinary NixOS.
The most common deployment option is deployment.targetHost, which sets the
address Navi connects to. If you omit it, Navi uses the node name as the host.
Sharing modules
Because the Hive is a flake output, it composes with the rest of your Nix
configuration. Pin nixpkgs through the input, import shared modules into
defaults or individual nodes, and reuse the same flake to expose packages or
NixOS configurations elsewhere.
The next chapter deploys this Hive.