diff --git a/README.md b/README.md
index c13f9d0..6c74bb3 100644
--- a/README.md
+++ b/README.md
@@ -1,126 +1,191 @@
-# nixos-anywhere - install nixos everywhere via ssh
+# nixos-anywhere
-
+***Install NixOS everywhere via ssh***
-nixos-anywhere (formally known as nixos-remote) makes it possible to install
-nixos from Linux machines reachable via ssh. Under the hood uses a
-[kexec image](https://github.com/nix-community/nixos-images#kexec-tarballs) to
-boot into a NixOS installer from a running Linux system. It then uses
-[disko](https://github.com/nix-community/disko) to partition and format the
-disks on the target system before it installs the user provided nixos
-configuration.
+![](https://raw.githubusercontent.com/numtide/nixos-anywhere/main/docs/logo.png)
-## Requirements
+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:
-`nixos-anywhere` can detect nixos installer if those contain the identifier
-`VARIANT=installer` in their `/etc/os-release` file. This is the case for the
-nixos-unstable installer and will be also part of nixos 23.05. If installer is
-detected `nixos-anywhere` will not try to kexec into its own image.
+- Disk partitioning and formatting
+- Configuring and installing either NixOS or SrvOS
+- Installing additional files and software
-If your system is not booted into a nixos installer than the following
-requirements apply for kexec to succeed:
+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.
-- `x86_64` Linux system with kexec support (most `x86_64` machine do have kexec
- support) or you have to provide your own
- [image](https://github.com/numtide/nixos-anywhere#using-your-own-kexec-image)
-- At least 1.5GB RAM (swap does not count). If you do not have enough RAM you
- will see failures unpacking the initrd), this is because kexec needs to load
- the whole nixos into memory.
+Once you have initiated the command, there is no need to 'babysit' the installation. It all happens automatically.
-## Usage
+You can use the stored configuration to repeat the same installation if you need to.
-Needs a repo with your configurations with flakes. For a minimal example
-checkout https://github.com/numtide/nixos-anywhere-examples.
+## Overview
-Your NixOS configuration will also need a
-[disko](https://github.com/nix-community/disko) configuration as we can see in
-our
-[example](https://github.com/numtide/nixos-anywhere-examples/blob/9768e438b1467ec55d42e096860e7199bd1ef43d/flake.nix#L15-L19)
+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.
-Afterwards you can just run:
+**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.
+
+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.
+
+Once the configuration has been created, a single command will:
+
+- Connect to the remote server via SSH
+- Detect whether a NixOS installer is present; if not, it will use the Linux ```kexec``` tool to boot into a Nixos installer.
+- Use the [disko](https://github.com/nix-community/disko) tool to partition and format the hard drive
+- Install NixOS
+- Optionally install any Nix packages and other software required.
+- Optionally copy additional files to the new machine
+
+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.
+
+**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.
+
+## Prerequisites
+
+- Source Machine:
+
+- - Can be any Linux machine with Nix installed, or a NixOS machine.
+- Target Machine:
+
+ - 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
+
+ - Must have at least 1.5 GB of RAM, excluding swap.
+
+
+## How to use nixos-anywhere
+
+Here’s a quick summary of how to use **nixos-anywhere**. You can find more information in the [product documentation](./docs).
+
+The tool doesn't need to be installed, since it can be run directly from this repository.
+
+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.
+
+Here’s an example of a simple disk configuration:
```
-nix run github:numtide/nixos-anywhere -- root@yourip --flake github:your-user/your-repo#your-system
+{ disks ? [ "/dev/vda" ], ... }:
+{
+ disk = {
+ main = {
+ type = "disk";
+ device = builtins.elemAt disks 0;
+ content = {
+ type = "table";
+ format = "gpt";
+ partitions = [
+ {
+ name = "boot";
+ type = "partition";
+ start = "0";
+ end = "1M";
+ flags = [ "bios_grub" ];
+ }
+ {
+ type = "partition";
+ name = "ESP";
+ start = "1M";
+ end = "512M";
+ bootable = true;
+ content = {
+ type = "filesystem";
+ format = "vfat";
+ mountpoint = "/boot";
+ };
+ }
+ {
+ type = "partition";
+ name = "root";
+ start = "512M";
+ end = "100%";
+ content = {
+ type = "filesystem";
+ format = "ext4";
+ mountpoint = "/";
+ };
+ }
+ ];
+ };
+ };
+ };
+}
```
-The parameter passed to `--flake` should point to your nixos configuration
-exposed in your flake (`nixosConfigurations.your-system` in the example above).
+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.
+
+A simple flake may look like this:
-
```
-Usage: nixos-anywhere [options] ssh-host
-
-Options:
-
-* -f, --flake flake
- set the flake to install the system from
-* -L, --print-build-logs
- print full build logs
-* -s, --store-paths
- set the store paths to the disko-script and nixos-system directly
- if this is give, flake is not needed
-* --no-reboot
- do not reboot after installation, allowing further customization of the target installation.
-* --kexec url
- use another kexec tarball to bootstrap NixOS
-* --stop-after-disko
- exit after disko formating, you can then proceed to install manually or some other way
-* --extra-files files
- files to copy into the new nixos installation
-* --disk-encryption-keys remote_path local_path
- copy the contents of the file or pipe in local_path to remote_path in the installer environment,
- after kexec but before installation. Can be repeated.
-* --no-substitute-on-destination
- disable passing --substitute-on-destination to nix-copy
-* --debug
- enable debug output
-* --option KEY VALUE
- nix option to pass to every nix related command
-* --from store-uri
- URL of the source Nix store to copy the nixos and disko closure from
-* --build-on-remote
- build the closure on the remote machine instead of locally and copy-closuring it
+{
+ inputs.nixpkgs.url = github:NixOS/nixpkgs;
+ inputs.disko.url = github:nix-community/disko;
+ inputs.disko.inputs.nixpkgs.follows = "nixpkgs";
+ outputs = { self, nixpkgs, disko, ... }@attrs: {
+ #-----------------------------------------------------------
+ #The following line names the configuration as hetzner-cloud
+ #This name will be referenced when nixos-remote is run
+ #-----------------------------------------------------------
+ nixosConfigurations.hetzner-cloud = nixpkgs.lib.nixosSystem {
+ system = "x86_64-linux";
+ specialArgs = attrs;
+ modules = [
+ ({modulesPath, ... }: {
+ imports = [
+ (modulesPath + "/installer/scan/not-detected.nix")
+ (modulesPath + "/profiles/qemu-guest.nix")
+ disko.nixosModules.disko
+ ];
+ disko.devices = import ./disk-config.nix {
+ lib = nixpkgs.lib;
+ };
+ boot.loader.grub = {
+ devices = [ "/dev/sda" ];
+ efiSupport = true;
+ efiInstallAsRemovable = true;
+ };
+ services.openssh.enable = true;
+#-------------------------------------------------------
+# Change the line below replacing
+# with your own ssh public key
+#-------------------------------------------------------
+ users.users.root.openssh.authorizedKeys.keys = [ "" ];
+ })
+ ];
+ };
+ };
+}
```
-## Using your own kexec image
+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:
-By default `nixos-anywhere` will download the kexec image from
-[here](https://github.com/nix-community/nixos-images#kexec-tarballs). It is also
-possible to provide your own by providing a file to `--kexec`. The image will
-than uploaded prior to executing.
-
-```shell
-nixos-anywhere \
- --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" \
- --flake 'github:your-user/your-repo#your-system' \
- root@yourip
+```
+nix run github:numtide/nixos-anywhere -- --flake github:JillThornhill/flakes-example#hetzner-cloud root@135.181.254.201
```
-`--kexec` can be useful for example for aarch64-linux, where there is no
-pre-build image. The following example assumes that your local machine can build
-for aarch64-linux either natively or through a remote builder
+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.
-```shell
-nixos-anywhere \
- --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" \
- --flake 'your-flake#your-system' \
- root@yourip
-```
+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).
-## Developer guide
+# Further Reading
-To run `nixos-anywhere` from the repo:
+@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/):
-```console
-nix run . -- --help
-```
+## Related Tools
-To format the code
+**nixos-anywhere** makes use of the [disko](https://github.com/nix-community/disko) tool to handle the partitioning and formatting of the disks.
-```console
-nix fmt
-```
+## Licensing and Contribution details
-# Further Reading
+This software is provided free under the [MIT Licence](https://opensource.org/licenses/MIT).
-@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/
+If you would like to become a contributor, please see our [contribution guidelines.](https://github.com/numtide/docs/contribution-guidelines.md)
+
+---
+
+This project is supported by [Numtide](https://numtide.com/). ![Untitledpng](https://codahosted.io/docs/6FCIMTRM0p/blobs/bl-sgSunaXYWX/077f3f9d7d76d6a228a937afa0658292584dedb5b852a8ca370b6c61dabb7872b7f617e603f1793928dc5410c74b3e77af21a89e435fa71a681a868d21fd1f599dd10a647dd855e14043979f1df7956f67c3260c0442e24b34662307204b83ea34de929d)
+
+We are a team of independent freelancers that love open source. We help our customers make their project lifecycles more efficient by:
+
+- Providing and supporting useful tools such as this one
+- Building and deploying infrastructure, and offering dedicated DevOps support
+- Building their in-house Nix skills, and integrating Nix with their workflows
+- Developing additional features and tools
+- Carrying out custom research and development.
+
+[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
diff --git a/docs/Quickstart.md b/docs/Quickstart.md
new file mode 100644
index 0000000..0c16531
--- /dev/null
+++ b/docs/Quickstart.md
@@ -0,0 +1,5 @@
+# Quickstart Guide: nixos-anywhere
+
+This document describes how to use **nixos-anywhere** in its simplest case: installing NixOS on an existing Linux distribution via SSH.
+
+TODO: Populate this guide
diff --git a/docs/Reference.md b/docs/Reference.md
new file mode 100644
index 0000000..ba0a10f
--- /dev/null
+++ b/docs/Reference.md
@@ -0,0 +1,68 @@
+# Reference Manual: nixos-anywhere
+
+TODO: Populate this guide properly
+
+## Contents
+
+[Command Line Usage](#command-line-usage)
+
+[Developer guide](#developer-guide)
+
+[Explanation of known error messages](#explanation-of-known-error-messages)
+
+## Command Line Usage
+
+```
+Usage: nixos-anywhere [options] ssh-host
+
+Options:
+
+* -f, --flake flake
+ set the flake to install the system from
+* -L, --print-build-logs
+ print full build logs
+* -s, --store-paths
+ set the store paths to the disko-script and nixos-system directly
+ if this is give, flake is not needed
+* --no-reboot
+ do not reboot after installation, allowing further customization of the target installation.
+* --kexec url
+ use another kexec tarball to bootstrap NixOS
+* --stop-after-disko
+ exit after disko formating, you can then proceed to install manually or some other way
+* --extra-files files
+ files to copy into the new nixos installation
+* --disk-encryption-keys remote_path local_path
+ copy the contents of the file or pipe in local_path to remote_path in the installer environment,
+ after kexec but before installation. Can be repeated.
+* --no-substitute-on-destination
+ disable passing --substitute-on-destination to nix-copy
+* --debug
+ enable debug output
+* --option KEY VALUE
+ nix option to pass to every nix related command
+* --from store-uri
+ URL of the source Nix store to copy the nixos and disko closure from
+* --build-on-remote
+ build the closure on the remote machine instead of locally and copy-closuring it
+```
+
+## Developer guide
+
+To run `nixos-anywhere` from the repo:
+
+```shell
+nix run . -- --help
+```
+
+To format the code
+
+```shell
+nix fmt
+```
+
+## Explanation of known error messages
+
+TODO: List actual error messages and meanings. Include:
+
+If you do not have enough RAM you will see failures unpacking the initrd), this is because kexec needs to load the whole nixos into memory.
diff --git a/docs/how_to.md b/docs/how_to.md
new file mode 100644
index 0000000..a8cfdd3
--- /dev/null
+++ b/docs/how_to.md
@@ -0,0 +1,42 @@
+# How To Guide: nixos-anywhere
+
+## Contents
+
+[Installing on a machine with no operating system](#installing-on-a-machine-with-no-operating-system)
+
+[Using your own kexec image](#using-your-own-kexec-image)
+
+[Using nixos-anywhere without flakes](#using-nixos-anywhere-without-flakes)
+
+TODO: Add more topics
+
+## Installing on a machine with no operating system
+
+TODO: Still to be documented
+
+Include:
+
+`nixos-anywhere` can detect a nixos installer if it contains the identifier `VARIANT=installer` in its `/etc/os-release` file. This is the case for the nixos-unstable installer and will be also part of nixos 23.05. If an installer is detected `nixos-anywhere` will not try to kexec into its own image.
+
+## Using your own kexec image
+
+By default `nixos-anywhere` will download the kexec image from [here](https://github.com/nix-community/nixos-images#kexec-tarballs). It is also possible to provide your own by using the command line switch `--kexec` to specify the image file. The image will then be uploaded prior to executing.
+
+```
+nixos-anywhere \
+ --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" \
+ --flake 'github:your-user/your-repo#your-system' \
+ root@yourip
+```
+
+This is particularly useful for distributions like aarch64-linux, where there is no pre-build image. The following example assumes that your local machine can build for aarch64-linux either natively or through a remote builder
+
+## Using nixos-anywhere without flakes
+
+TODO: Add content
+
+```
+
+```
+
+