Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Quickstart

The minimum path from a fresh repo to a single managed host. For multi-host fleets, see RFC-0001 (fleet.nix) and the operator cookbook. For the unattended signed-rollout machinery, see architecture and RFC-0002 (reconciler).

A minimal host

mkFleet is the typical path even for a single host: declare the host, channel, and rollout policy; the framework wires the per-host nixosSystem for you. Direct nixfleet.lib.mkHost is also supported for one-off setups (the rest of this section uses mkFleet; see lib/mk-host.nix for the direct primitive).

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    nixfleet.url = "github:arcanesys/nixfleet";
  };

  outputs = { nixpkgs, nixfleet, ... }: let
    fleet = nixfleet.lib.mkFleet {
      hosts.my-server = {
        system = "x86_64-linux";
        channel = "stable";
        tags = [];
        nixosArgs = {
          hostSpec.userName = "deploy";
          modules = [
            nixfleet.scopes.persistence.impermanence
            nixfleet.scopes.secrets

            ./hardware-configuration.nix
            ({ ... }: {
              users.users.deploy = {
                isNormalUser = true;
                extraGroups = [ "wheel" ];
                openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAA..." ];
              };
              services.nixfleet-agent = {
                enable = true;
                controlPlane.url = "https://cp.example.com:8080";
              };
            })
          ];
        };
      };
      channels.stable = {
        rolloutPolicy = "all-at-once";
        signingIntervalMinutes = 60;
        freshnessWindow = 1440;
      };
      rolloutPolicies.all-at-once = {
        strategy = "all-at-once";
        waves = [{ selector.all = true; soakMinutes = 0; }];
      };
    };
  in {
    nixosConfigurations = fleet.nixosConfigurations;
  };
}

fleet.nixosConfigurations.<host> is a standard nixosSystem (or darwinSystem for Darwin platforms). Nothing in the result is NixFleet-specific — if you remove the agent module, the host is a vanilla NixOS configuration deployable with stock tooling.

Deploy

Standard NixOS / Darwin tooling, no NixFleet-specific glue:

nixos-anywhere --flake .#my-server root@192.168.1.50  # fresh install
sudo nixos-rebuild switch --flake .#my-server          # local rebuild
darwin-rebuild switch --flake .#my-mac                 # macOS

Fleet rollouts are git-driven from this point: commit -> CI signs -> CP polls fleet.resolved.json -> agents pull their per-host target on next checkin. There is no operator CLI verb between commit and host activation. See operator cookbook -> Deploy a fleet change.

Build and install the operator CLI

cargo build --release -p nixfleet-cli
install -m 0755 target/release/nixfleet ~/.local/bin/

Alternatively, run without installing: nix run github:arcanesys/nixfleet#nixfleet-cli -- <subcommand>.

Initialise operator config

nixfleet config init \
  --cp-url https://cp.example.com:8080 \
  --ca-cert /etc/nixfleet/ca.pem \
  --client-cert ~/.config/nixfleet/operator.pem \
  --client-key  ~/.config/nixfleet/operator.key

Writes ~/.config/nixfleet/config.toml (mode 0600). Override values per-invocation via flags or NIXFLEET_* environment variables. The flag > env > file precedence is locked in tests.

Verify

nixfleet status                  # rendered fleet table
nixfleet status --json           # raw HostsResponse for piping
nixfleet rollout hosts <id>      # per-host summary for a rollout
nixfleet rollout events <id>     # chronological event-log stream

For the full CLI surface (subcommands, flags, status-label precedence, pin markers), see reference/crates/nixfleet-cli.

Next steps