Deploy a NixOS Host

  • Use this when building, deploying, or rolling back a NixOS host from this repo. Host inventory lives in Fleet; architecture background lives in Architecture/NixOS.

  • Quick checks

    • Confirm the host exists in the flake:

    • nix eval --json .#nixosConfigurations --apply builtins.attrNames
    • Build the system closure without deploying:

    • nix build .#nixosConfigurations.<hostname>.config.system.build.toplevel --no-link
    • Operator-run ARM host builds always use Fleet/forge; use the exact pre-PR build command in Runbooks/Validate Infra Changes.

    • Run a harmless remote command through the host app:

    • nix run .#<hostname> -- date
  • Deploy safely

    • Prefer boot for remote or headless hosts. It builds and installs the new generation, but activation waits until the next reboot:

    • nixos-rebuild boot --sudo --target-host <hostname> --flake .#<hostname>
    • Use switch when immediate activation is intended:

    • nixos-rebuild switch --flake .#<hostname> --target-host <hostname> --sudo
    • For offsite or Tailscale-only paths, use the reachable target host name:

    • nixos-rebuild boot --sudo --target-host <hostname>.<tailnet-name> --flake .#<hostname>
  • After deploying

    • Verify the host answers:

    • nix run .#<hostname> -- hostname
      nix run .#<hostname> -- systemctl --failed --no-pager
    • If the change touched a service, check that unit explicitly:

    • nix run .#<hostname> -- systemctl --no-pager --full status <unit>.service
      nix run .#<hostname> -- journalctl -u <unit>.service -n 80 --no-pager
  • Roll back

    • If the host is reachable and the current generation is bad:

    • nix run .#<hostname> -- sudo nixos-rebuild switch --rollback
    • If remote access is risky, use the bootloader console or local access and select the previous generation.

  • Adding a host

    • Kubernetes nodes are declared inline in nixosConfigurations in flake.nix via mkHost; the hostname is the attr name and cluster membership comes from tags = [ &quot;folly&quot; ] or [ &quot;offsite&quot; ].

    • Standalone hosts with unique config get a file under nix/hosts/&lt;hostname&gt;.nix and a flake.nix host entry pointing at it.

    • Validate after adding a host:

    • nix flake check
      nix build .#nixosConfigurations.<hostname>.config.system.build.toplevel --no-link
  • Dotfiles

    • Dotfiles are mise-managed from the in-repo dotfiles/ tree. nix/system/mise-dotfiles.nix carries that subtree into the system closure and runs mise run bootstrap during activation.

    • Shell tooling (eza, fzf, neovim, bat, ripgrep, fd, delta, jq, gh, btop, sd, 1password-cli) and zsh plugins (pure, fzf-tab, autosuggestions, syntax-highlighting, kube-ps1) come from home-manager for the jawn user via nix/system/home-manager.nix and nix/home/jawn.nix. Activation sets HM_ACTIVATED=1 so dotfiles/scripts/deploy-dotfiles.sh skips deploying ~/.config/zsh on those hosts.

    • The bootstrap task routes by OS; there is no dotfiles-only bootstrap flag.

  • Auto-upgrade caveat

    • Hosts auto-rebuild from GitHub main. A config deployed from a branch can be reverted by the next auto-upgrade unless the branch merges promptly. Treat a branch deploy as a test unless it has merged.

Linked references 5

Architecture/GitOps

Step-by-step: Runbooks/Deploy a NixOS Host. Host inventory: Fleet. Layer background: Architecture/NixOS.

Architecture/NixOS

Layer 1: bare metal. Every host in the fleet is declared as NixOS in one flake at the repo root (flake.nix), configured under nix/. A few hosts run something else and are being brought across — Fleet lists the machine inventory and the known divergence. Runbooks/Deploy a NixOS Host has the build/deploy/rollback commands; this page is architecture only.

Architecture/NixOS

Actual nixos-rebuild/nix build invocations, adding a new host, rollback, and the auto-upgrade branch-revert caveat in command form: Runbooks/Deploy a NixOS Host.

Runbooks

Runbooks/Deploy a NixOS Host — build, deploy, verify, and roll back NixOS hosts