|
1 |
| -# nixos-anywhere - install nixos everywhere via ssh |
| 1 | +# nixos-anywhere |
2 | 2 |
|
3 |
| -<img src="https://raw.githubusercontent.com/numtide/nixos-anywhere/main/docs/logo.png" width="256" height="256"> |
| 3 | +***Install NixOS everywhere via ssh*** |
4 | 4 |
|
5 |
| -nixos-anywhere (formally known as nixos-remote) makes it possible to install |
6 |
| -nixos from Linux machines reachable via ssh. Under the hood uses a |
7 |
| -[kexec image](https://github.com/nix-community/nixos-images#kexec-tarballs) to |
8 |
| -boot into a NixOS installer from a running Linux system. It then uses |
9 |
| -[disko](https://github.com/nix-community/disko) to partition and format the |
10 |
| -disks on the target system before it installs the user provided nixos |
11 |
| -configuration. |
| 5 | + |
12 | 6 |
|
13 |
| -## Requirements |
| 7 | +Setting up a new machine is time-consuming, and becomes complicated when it needs to be done remotely. If you're installing NixOS, the **nixos-anywhere** (formerly known as **nixos-remote**) tool allows you to pre-configure the whole process including: |
14 | 8 |
|
15 |
| -`nixos-anywhere` can detect nixos installer if those contain the identifier |
16 |
| -`VARIANT=installer` in their `/etc/os-release` file. This is the case for the |
17 |
| -nixos-unstable installer and will be also part of nixos 23.05. If installer is |
18 |
| -detected `nixos-anywhere` will not try to kexec into its own image. |
| 9 | +- Disk partitioning and formatting |
| 10 | +- Configuring and installing either NixOS or SrvOS |
| 11 | +- Installing additional files and software |
19 | 12 |
|
20 |
| -If your system is not booted into a nixos installer than the following |
21 |
| -requirements apply for kexec to succeed: |
| 13 | +You can then initiate an unattended installation with a single CLI command. Since **nixos-anywhere** can access the new machine using SSH, it's ideal for remote installations. |
22 | 14 |
|
23 |
| -- `x86_64` Linux system with kexec support (most `x86_64` machine do have kexec |
24 |
| - support) or you have to provide your own |
25 |
| - [image](https://github.com/numtide/nixos-anywhere#using-your-own-kexec-image) |
26 |
| -- At least 1.5GB RAM (swap does not count). If you do not have enough RAM you |
27 |
| - will see failures unpacking the initrd), this is because kexec needs to load |
28 |
| - the whole nixos into memory. |
| 15 | +Once you have initiated the command, there is no need to 'babysit' the installation. It all happens automatically. |
29 | 16 |
|
30 |
| -## Usage |
| 17 | +You can use the stored configuration to repeat the same installation if you need to. |
31 | 18 |
|
32 |
| -Needs a repo with your configurations with flakes. For a minimal example |
33 |
| -checkout https://github.com/numtide/nixos-anywhere-examples. |
| 19 | +## Overview |
34 | 20 |
|
35 |
| -Your NixOS configuration will also need a |
36 |
| -[disko](https://github.com/nix-community/disko) configuration as we can see in |
37 |
| -our |
38 |
| -[example](https://github.com/numtide/nixos-anywhere-examples/blob/9768e438b1467ec55d42e096860e7199bd1ef43d/flake.nix#L15-L19) |
| 21 | +If you have machines on a mix of platforms, you'll need a common installation solution that works anywhere. **nixos-anywhere** is ideal in this situation. |
39 | 22 |
|
40 |
| -Afterwards you can just run: |
| 23 | +**nixos-anywhere** can be used equally well for cloud servers, bare metal servers such as Hetzner, and local servers accessible via a LAN. You can create standard configurations, and use the same configuration to create identical servers anywhere. |
41 | 24 |
|
42 |
| -``` |
43 |
| -nix run github:numtide/nixos-anywhere -- root@yourip --flake github:your-user/your-repo#your-system |
44 |
| -``` |
| 25 | +You first create Nix configurations to specify partitioning, formatting and NixOS configurations. Further options can be controlled by a flake and by run-time switches. |
| 26 | + |
| 27 | +Once the configuration has been created, a single command will: |
| 28 | + |
| 29 | +- Connect to the remote server via SSH |
| 30 | +- Detect whether a NixOS installer is present; if not, it will use the Linux ```kexec``` tool to boot into a Nixos installer. |
| 31 | +- Use the [disko](https://github.com/nix-community/disko) tool to partition and format the hard drive |
| 32 | +- Install NixOS |
| 33 | +- Optionally install any Nix packages and other software required. |
| 34 | +- Optionally copy additional files to the new machine |
| 35 | + |
| 36 | +It's also possible to use **nixos-anywhere** to simplify the installation on a machine that has no current operating system, first booting from a NixOS installer image. This feature is described in the [how-to guide](./docs/how_to.md#installing-on-a-machine-with-no-operating-system). It's useful because you can pre-configure your required software and preferences, and build the new machine with a single command. |
| 37 | + |
| 38 | +**Important Note:** Never use a production server as the target. It will be completely overwritten and all data lost. This tool should only be used for commissioning a new computer or repurposing an old machine once all important data has been migrated. |
| 39 | + |
| 40 | +## Prerequisites |
| 41 | + |
| 42 | +- Source Machine: |
| 43 | + |
| 44 | +- - Can be any Linux machine with Nix installed, or a NixOS machine. |
| 45 | +- Target Machine: |
| 46 | + |
| 47 | + - Unless you're using the option to boot from a NixOS installer image, or providing your own ```kexec``` image, it must be running x86-64 Linux with kexec support. Most x86_64 Linux systems do have kexec support. By providing your own [image](./docs/how_to.md#using-your-own-kexec-image) you can also perform kexec for other architectures eg aarch64 |
| 48 | + |
| 49 | + - Must have at least 1.5 GB of RAM, excluding swap. |
| 50 | + |
| 51 | + |
| 52 | +## How to use nixos-anywhere |
| 53 | + |
| 54 | +Here’s a quick summary of how to use **nixos-anywhere**. You can find more information in the [product documentation](./docs). |
| 55 | + |
| 56 | +The tool doesn't need to be installed, since it can be run directly from this repository. |
| 57 | + |
| 58 | +First create a repo that includes the disk configuration and a [flake](https://nixos.wiki/wiki/Flakes) to configure your options. This example assumes that flakes have been enabled on your source machine. |
45 | 59 |
|
46 |
| -The parameter passed to `--flake` should point to your nixos configuration |
47 |
| -exposed in your flake (`nixosConfigurations.your-system` in the example above). |
| 60 | +Here’s an example of a simple disk configuration: |
48 | 61 |
|
49 |
| -<!-- `$ bash ./src/nixos-anywhere.sh --help` --> |
50 | 62 | ```
|
51 |
| -Usage: nixos-anywhere [options] ssh-host |
52 |
| -
|
53 |
| -Options: |
54 |
| -
|
55 |
| -* -f, --flake flake |
56 |
| - set the flake to install the system from |
57 |
| -* -L, --print-build-logs |
58 |
| - print full build logs |
59 |
| -* -s, --store-paths |
60 |
| - set the store paths to the disko-script and nixos-system directly |
61 |
| - if this is give, flake is not needed |
62 |
| -* --no-reboot |
63 |
| - do not reboot after installation, allowing further customization of the target installation. |
64 |
| -* --kexec url |
65 |
| - use another kexec tarball to bootstrap NixOS |
66 |
| -* --stop-after-disko |
67 |
| - exit after disko formating, you can then proceed to install manually or some other way |
68 |
| -* --extra-files files |
69 |
| - files to copy into the new nixos installation |
70 |
| -* --disk-encryption-keys remote_path local_path |
71 |
| - copy the contents of the file or pipe in local_path to remote_path in the installer environment, |
72 |
| - after kexec but before installation. Can be repeated. |
73 |
| -* --no-substitute-on-destination |
74 |
| - disable passing --substitute-on-destination to nix-copy |
75 |
| -* --debug |
76 |
| - enable debug output |
77 |
| -* --option KEY VALUE |
78 |
| - nix option to pass to every nix related command |
79 |
| -* --from store-uri |
80 |
| - URL of the source Nix store to copy the nixos and disko closure from |
81 |
| -* --build-on-remote |
82 |
| - build the closure on the remote machine instead of locally and copy-closuring it |
| 63 | +{ disks ? [ "/dev/vda" ], ... }: |
| 64 | +{ |
| 65 | + disk = { |
| 66 | + main = { |
| 67 | + type = "disk"; |
| 68 | + device = builtins.elemAt disks 0; |
| 69 | + content = { |
| 70 | + type = "table"; |
| 71 | + format = "gpt"; |
| 72 | + partitions = [ |
| 73 | + { |
| 74 | + name = "boot"; |
| 75 | + type = "partition"; |
| 76 | + start = "0"; |
| 77 | + end = "1M"; |
| 78 | + flags = [ "bios_grub" ]; |
| 79 | + } |
| 80 | + { |
| 81 | + type = "partition"; |
| 82 | + name = "ESP"; |
| 83 | + start = "1M"; |
| 84 | + end = "512M"; |
| 85 | + bootable = true; |
| 86 | + content = { |
| 87 | + type = "filesystem"; |
| 88 | + format = "vfat"; |
| 89 | + mountpoint = "/boot"; |
| 90 | + }; |
| 91 | + } |
| 92 | + { |
| 93 | + type = "partition"; |
| 94 | + name = "root"; |
| 95 | + start = "512M"; |
| 96 | + end = "100%"; |
| 97 | + content = { |
| 98 | + type = "filesystem"; |
| 99 | + format = "ext4"; |
| 100 | + mountpoint = "/"; |
| 101 | + }; |
| 102 | + } |
| 103 | + ]; |
| 104 | + }; |
| 105 | + }; |
| 106 | + }; |
| 107 | +} |
83 | 108 | ```
|
84 | 109 |
|
85 |
| -## Using your own kexec image |
| 110 | +The [disko repository](https://github.com/nix-community/disko/tree/master/example) has several examples of disk configurations. You can adapt them to our own needs. |
86 | 111 |
|
87 |
| -By default `nixos-anywhere` will download the kexec image from |
88 |
| -[here](https://github.com/nix-community/nixos-images#kexec-tarballs). It is also |
89 |
| -possible to provide your own by providing a file to `--kexec`. The image will |
90 |
| -than uploaded prior to executing. |
| 112 | +A simple flake may look like this: |
91 | 113 |
|
92 |
| -```shell |
93 |
| -nixos-anywhere \ |
94 |
| - --kexec "$(nix build --print-out-paths github:nix-community/nixos-images#packages.x86_64-linux.kexec-installer-noninteractive-nixos-unstable)/nixos-kexec-installer-noninteractive-x86_64-linux.tar.gz" \ |
95 |
| - --flake 'github:your-user/your-repo#your-system' \ |
96 |
| - root@yourip |
| 114 | +``` |
| 115 | +{ |
| 116 | + inputs.nixpkgs.url = github:NixOS/nixpkgs; |
| 117 | + inputs.disko.url = github:nix-community/disko; |
| 118 | + inputs.disko.inputs.nixpkgs.follows = "nixpkgs"; |
| 119 | + outputs = { self, nixpkgs, disko, ... }@attrs: { |
| 120 | + #----------------------------------------------------------- |
| 121 | + #The following line names the configuration as hetzner-cloud |
| 122 | + #This name will be referenced when nixos-remote is run |
| 123 | + #----------------------------------------------------------- |
| 124 | + nixosConfigurations.hetzner-cloud = nixpkgs.lib.nixosSystem { |
| 125 | + system = "x86_64-linux"; |
| 126 | + specialArgs = attrs; |
| 127 | + modules = [ |
| 128 | + ({modulesPath, ... }: { |
| 129 | + imports = [ |
| 130 | + (modulesPath + "/installer/scan/not-detected.nix") |
| 131 | + (modulesPath + "/profiles/qemu-guest.nix") |
| 132 | + disko.nixosModules.disko |
| 133 | + ]; |
| 134 | + disko.devices = import ./disk-config.nix { |
| 135 | + lib = nixpkgs.lib; |
| 136 | + }; |
| 137 | + boot.loader.grub = { |
| 138 | + devices = [ "/dev/sda" ]; |
| 139 | + efiSupport = true; |
| 140 | + efiInstallAsRemovable = true; |
| 141 | + }; |
| 142 | + services.openssh.enable = true; |
| 143 | +#------------------------------------------------------- |
| 144 | +# Change the line below replacing <insert your key here> |
| 145 | +# with your own ssh public key |
| 146 | +#------------------------------------------------------- |
| 147 | + users.users.root.openssh.authorizedKeys.keys = [ "<insert your key here>" ]; |
| 148 | + }) |
| 149 | + ]; |
| 150 | + }; |
| 151 | + }; |
| 152 | +} |
97 | 153 | ```
|
98 | 154 |
|
99 |
| -`--kexec` can be useful for example for aarch64-linux, where there is no |
100 |
| -pre-build image. The following example assumes that your local machine can build |
101 |
| -for aarch64-linux either natively or through a remote builder |
| 155 | +Once you’ve created the disk configuration and the flake, you can run the tool with a single nix command, which may look like this: |
102 | 156 |
|
103 |
| -```shell |
104 |
| -nixos-anywhere \ |
105 |
| - --kexec "$(nix build --print-out-paths github:nix-community/nixos-images#packages.aarch64-linux.kexec-installer-noninteractive-nixos-unstable)/nixos-kexec-installer-noninteractive-aarch64-linux.tar.gz" \ |
106 |
| - --flake 'your-flake#your-system' \ |
107 |
| - root@yourip |
| 157 | +``` |
| 158 | +nix run github:numtide/nixos-anywhere -- --flake github:JillThornhill/flakes-example#hetzner-cloud root@135.181.254.201 |
108 | 159 | ```
|
109 | 160 |
|
110 |
| -## Developer guide |
| 161 | +Note that this command references the URL of your flake, in this case github:JillThornhill/flakes-example, together with the name of the system #hetzner-cloud, as highlighted by the comment in the sample flake. |
111 | 162 |
|
112 |
| -To run `nixos-anywhere` from the repo: |
| 163 | +The [Quickstart Guide](./docs/Quickstart.md) gives more information on how to run **nixos-anywhere** in its simplest form. For more specific instructions to suit individual requirements, see the [How To Guide](./docs/how_to.md). |
113 | 164 |
|
114 |
| -```console |
115 |
| -nix run . -- --help |
116 |
| -``` |
| 165 | +# Further Reading |
117 | 166 |
|
118 |
| -To format the code |
| 167 | +@tfc has written a walkthrough on how use **nixos-anywhere** to bootstrap hetzner cloud servers as well as dedicated machines on his [blog](https://galowicz.de/2023/04/05/single-command-server-bootstrap/): |
119 | 168 |
|
120 |
| -```console |
121 |
| -nix fmt |
122 |
| -``` |
| 169 | +## Related Tools |
| 170 | + |
| 171 | +**nixos-anywhere** makes use of the [disko](https://github.com/nix-community/disko) tool to handle the partitioning and formatting of the disks. |
| 172 | + |
| 173 | +## Licensing and Contribution details |
| 174 | + |
| 175 | +This software is provided free under the [MIT Licence](https://opensource.org/licenses/MIT). |
| 176 | + |
| 177 | +If you would like to become a contributor, please see our [contribution guidelines.](https://github.com/numtide/docs/contribution-guidelines.md) |
| 178 | + |
| 179 | +--- |
| 180 | + |
| 181 | +This project is supported by [Numtide](https://numtide.com/).  |
| 182 | + |
| 183 | +We are a team of independent freelancers that love open source. We help our customers make their project lifecycles more efficient by: |
123 | 184 |
|
124 |
| -# Further Reading |
| 185 | +- Providing and supporting useful tools such as this one |
| 186 | +- Building and deploying infrastructure, and offering dedicated DevOps support |
| 187 | +- Building their in-house Nix skills, and integrating Nix with their workflows |
| 188 | +- Developing additional features and tools |
| 189 | +- Carrying out custom research and development. |
125 | 190 |
|
126 |
| -@tfc has written a walkthrough on how use nixos-anywhere to bootstrap hetzner cloud servers as well as dedicated ones on his blog: https://galowicz.de/2023/04/05/single-command-server-bootstrap/ |
| 191 | +[Contact us](https://numtide.com/contact) if you have a project in mind, or if you need help with any of our supported tools, including this one. We'd love to |
0 commit comments