nixos-anywhere

repository·main·Indexed 25 days ago

https://github.com/nix-community/nixos-anywhere

A tool for installing NixOS on remote machines via SSH. It automates disk partitioning and formatting using disko, handles software installation, and supports unattended provisioning for cloud servers, bare metal, and local LAN servers. Features include kexec booting for installers, Terraform modules for deployment management, and the ability to copy extra files to the target host.

Tokens
13.5K
Snippets
32
Records
58
Agent score
86%

What's inside nixos-anywhere

  1. Overview of nixos-anywhere

    main

    nixos-anywhere is a tool used to install NixOS on remote machines via SSH. It automates the entire provisioning process, including disk partitioning, formatting, NixOS installation, and the installation of additional software or files. It is designed for unattended installations, meaning once the command is initiated, the process runs automatically without manual intervention.

    Key capabilities:

    • Connect to remote servers via SSH.
    • Use kexec to boot into a NixOS installer if one is not present.
    • Use disko for disk partitioning and formatting.
    • Install Nix packages and additional files.
    • Support for cloud servers, bare metal (e.g., Hetzner), and local LAN servers.
  2. Overview of NixOS-Anywhere Terraform Modules

    main

    The nixos-anywhere Terraform modules enable the use of Terraform to install and update NixOS. There are four primary modules available depending on your deployment needs:

    • All-in-One: A consolidated module that performs an initial installation using nixos-anywhere and subsequently manages updates using nixos-rebuild. This is a complete replacement for other deployment tools like Colmena.
    • Install: A specialized module dedicated exclusively to the initial installation of NixOS via nixos-anywhere.
    • NixOS-Rebuild: A module designed for remote updates of existing NixOS machines using nixos-rebuild.
    • Nix-Build: A helper module used to build a Nix flake attribute or an attribute from a Nix file.
  3. Generate hardware-configuration.nix on target machine

    main

    To obtain the necessary hardware configuration for a target machine, you must run the configuration generator on that machine.

    Options for accessing the target:

    1. Boot into a NixOS installer without completing the installation.
    2. Use the kexec tarball method.

    Command: Run the following on the target machine to generate the files in /tmp/config/. You must then copy /tmp/config/nixos/hardware-configuration.nix to your local machine's configuration directory.

    nixos-generate-config --no-filesystems --dir /tmp/config
  4. Set NIX_PATH via NixOS configuration (Recommended)

    main

    To avoid errors when using tools like nix-shell or nix-env (e.g., error: file 'nixpkgs' was not found in the Nix search path), you can populate the NIX_PATH directly within your NixOS flake configuration. This is the recommended approach because it is stateless and automatically stays in sync with your flake updates.

    Add a module to your nixosConfigurations that sets nix.nixPath using your flake inputs.

    {
      inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
      # ... other inputs
    
      outputs = inputs@{ nixpkgs, ... }: 
        {
          nixosConfigurations.yoursystem = nixpkgs.lib.nixosSystem {
            system = "x86_64-linux"; # adapt to your actual system
            modules = [
              # This line will populate NIX_PATH
              { nix.nixPath = [ "nixpkgs=${inputs.nixpkgs}" ]; }
              # ... other modules and your configuration.nix
            ];
          };
        };
    }
  5. Repair NixOS installations using --disko-mode mount

    main

    To recover from a misconfigured NixOS installation without wiping existing data, use the --disko-mode mount flag. This mode avoids reformatting disks and instead mounts the existing filesystems of the target machine to run nixos-install based on your provided flake.

    Workflow:

    1. Boots into a nixos-installer.
    2. Mounts existing disks using disko.
    3. Runs nixos-install using the specified flake configuration.
    4. Reboots the machine.
    nix run github:nix-community/nixos-anywhere -- --disko-mode mount --flake <path to configuration>#<configuration name> --target-host root@<ip address>
  6. Install NixOS using Terraform modules

    main

    You can automate NixOS installation using nixos-anywhere Terraform modules. This involves building the NixOS system and partitioner (e.g., using Disko) as separate modules, then passing their outputs to the install module.

    Using Flakes

    When using Flakes, specify the attribute pointing to the NixOS configuration path (e.g., .#nixosConfigurations.NAME.config.system.build.toplevel).

    Without Flakes

    When not using Flakes, specify the file path to your NixOS configuration and the attribute path (e.g., config.system.build.toplevel). The file can use the (pkgs.nixos []) function from nixpkgs.

    locals {
      ipv4 = "192.0.2.1"
    }
    
    module "system-build" {
      source            = "github.com/nix-community/nixos-anywhere//terraform/nix-build"
      # with flakes
      attribute         = ".#nixosConfigurations.mymachine.config.system.build.toplevel"
      # without flakes
      # file can use (pkgs.nixos []) function from nixpkgs
      #file              = "${path.module}/../.."
      #attribute         = "config.system.build.toplevel"
    }
    
    module "disko" {
      source         = "github.com/nix-community/nixos-anywhere//terraform/nix-build"
      # with flakes
      attribute      = ".#nixosConfigurations.mymachine.config.system.build.diskoScript"
      # without flakes
      # file can use (pkgs.nixos []) function from nixpkgs
      #file           = "${path.module}/../.."
      #attribute      = "config.system.build.diskoScript"
    }
    
    module "install" {
      source            = "github.com/nix-community/nixos-anywhere//terraform/install"
      nixos_system      = module.system-build.result.out
      nixos_partitioner = module.disko.result.out
      target_host       = local.ipv4
    }
  7. Update NixOS configuration remotely

    main

    To apply configuration changes to a remote machine, ensure you have an SSH server enabled on the target and your SSH key is added to the root user's openssh.authorizedKeys.keys. Use the --target-host flag with nixos-rebuild to specify the remote connection.

    nixos-rebuild switch --flake <URL to your flake> --target-host "root@<ip address>"
  8. Install Terraform with required providers for nixos-anywhere

    main

    The nixos-anywhere Terraform modules require the null and external providers. You can obtain a Terraform installation with these plugins pre-configured using nix-shell with the following expression:

    nix-shell -p '(pkgs.terraform.withPlugins (p: [ p.null p.external ]))'

    Alternatively, you can add this expression to the packages list in your devShell within a flake.nix or shell.nix file to ensure the providers are available in your development environment.

  9. Destination machine requirements for nixos-anywhere

    main

    The destination machine must be reachable over the public internet or a local network. Note: nixos-anywhere does not support wifi networks.

    Boot Options

    • Direct Boot: The machine must already be running a NixOS installer.
    • Alternative Boot (kexec): If not booting from a NixOS installer image, the machine must meet these requirements:
      • Architecture: Must be an x86-64 or aarch64 Linux system with kexec support. For other architectures, you may need to specify a custom kexec image manually.
      • Memory: At least 1.5 GB of RAM (excluding swap space).

    Network Connectivity

    If a VPN is required to reach the destination machine, you must define a custom installer using the --kexec flag to connect to your VPN.