Skip to content

Commit

Permalink
give a thorough review and edit the post
Browse files Browse the repository at this point in the history
  • Loading branch information
srid committed Feb 19, 2024
1 parent 8e94f8d commit 5e01ba9
Showing 1 changed file with 122 additions and 78 deletions.
200 changes: 122 additions & 78 deletions en/nixos-install-disko.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ order: 2

# Install NixOS and partition the disk with `disko`

This tutorial adds another layer of reproducibility to [[nixos-install-flake|our first NixOS installation tutorial]] by defining the disk partitioning scheme in [[nixos|NixOS]] configuration itself, using the declarative disk partitioning tool [disko](https://github.com/nix-community/disko).
In this tutorial, we will walk you through the process of installing [[nixos|NixOS]]. Unlike [[nixos-install-flake|the first installation tutorial]], we will use the command line to install NixOS manually, except for using [disko] to specify disk partitions declaratively in [[nix|Nix]] itself.


[disko]: https://github.com/nix-community/disko

{#prepare}
## Prepare to install NixOS
Expand All @@ -14,9 +17,9 @@ This tutorial adds another layer of reproducibility to [[nixos-install-flake|our
> This tutorial doesn't use a [[nixos-install-flake|graphical installer]]. Instead, it uses the minimal ISO image. This is primarily because we don't want the installer to partion the disk for us. We will use [disko](https://github.com/nix-community/disko) to do that.
- Download the latest NixOS ISO from [here](https://nixos.org/download#download-nixos). Choose the "Minimal ISO image" for your architecture.
- Create a bootable USB flash drive ([instructions here](https://nixos.org/manual/nixos/stable/index.html#sec-booting-from-usb)) and boot the computer from it.
- Create a bootable USB flash drive ([instructions here](https://nixos.org/manual/nixos/stable/index.html#sec-booting-from-usb))

NixOS will boot into the USB in CLI mode.
Boot your computer from this USB flash drive, and expect to be greeted with a command line interface (CLI):

:::{.center}
![[nixos-installer-cli.jpeg]]
Expand All @@ -25,14 +28,14 @@ NixOS will boot into the USB in CLI mode.
{#partition}
## Partition the disk

The [disko quickstart guide](https://github.com/nix-community/disko/blob/master/docs/quickstart.md) does an excellent job of explaining it. We will follow the same steps and include screenshots wherever necessary. Additionally, in the last step we will use flakes to manage the configuration.
Before installing NixOS, let's define our partition layout in Nix. We will follow [the official disko documentation](https://github.com/nix-community/disko/blob/master/docs/quickstart.md) and include screenshots wherever necessary. Finally, we will use flakes to manage the configuration.

{#disk-config}
### Choosing the disk configuration

Disko provides a few examples to choose [from](https://github.com/nix-community/disko/tree/master/example). We will use the [hybrid](https://github.com/nix-community/disko/blob/master/example/hybrid.nix) example as it will work for both BIOS and UEFI systems.
Instead of creating our partition layout from scratch, we can choose one of the examples Disko itself provides (see [here](https://github.com/nix-community/disko/tree/master/example)). We will use the [hybrid](https://github.com/nix-community/disko/blob/master/example/hybrid.nix) example as it will work for both BIOS and UEFI systems.

Copy the disk configuration on to the USB flash drive.
Retrieve the disk configuration to a temporary location, calling it `disko-config.nix`:

```bash
curl https://raw.githubusercontent.com/nix-community/disko/master/example/hybrid.nix -o /tmp/disko-config.nix
Expand All @@ -41,7 +44,7 @@ curl https://raw.githubusercontent.com/nix-community/disko/master/example/hybrid
{#disk-config-edit}
### Modify the disk configuration

We need to find the device name of the disk we want to install [[nixos]] on. We can use `lsblk` to find it.
The downloaded expression uses a hardcoded disk device. So, we need to find the device name of the disk we want to install [[nixos]] on. We can use `lsblk` to find it.


:::{.center}
Expand All @@ -56,96 +59,132 @@ In this case, the device name is `vda`. The device file is located at `/dev/vda`

### Run the partitioning script

>[!note]
> The disk will be partitioned and mounted at `/mnt`.
The disko flake provides an app that will take our partitioning scheme defined in Nix above, partition the specified disk device and mount it at `/mnt`. This is what we need to happen prior to installing NixOS. Let's do that now:

```bash
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko -- --mode disko /tmp/disko-config.nix
sudo nix \
--experimental-features "nix-command flakes" \
run github:nix-community/disko -- \
--mode disko /tmp/disko-config.nix
```

Once the command completes, you should see the disk partitioned and mounted at `/mnt`:

:::{.center}
![[nixos-disko-post-partition.jpeg]]
:::

{#configuration}
## Generate initial NixOS configuration

With the disk partitioned, we are ready to follow the usual NixOS installation process. The first step is to generate the initial NixOS configuration under `/mnt`.

```bash
sudo nixos-generate-config --no-filesystems --root /mnt
```

The [fileSystems](https://search.nixos.org/options?channel=23.11&show=fileSystems&from=0&size=50&sort=relevance&type=packages&query=fileSystems) configuration will be added by `disko`'s [nixosModule](https://nixos.wiki/wiki/NixOS_modules) hence we use `--no-filesystems` to avoid generating it. `--root` is to specify the mountpoint to generate `configuration.nix` and `hardware-configuration.nix` in. Here, it will be `/mnt/etc/nixos`.
> [!tip] Why `--no-filesystems` and `--root`?
> - The [fileSystems](https://search.nixos.org/options?channel=23.11&show=fileSystems&from=0&size=50&sort=relevance&type=packages&query=fileSystems) configuration will automatically be added by `disko`'s [nixosModule](https://nixos.wiki/wiki/NixOS_modules) (see below). Therefore, we use `--no-filesystems` to avoid generating it here.
> - `--root` is to specify the mountpoint to generate `configuration.nix` and `hardware-configuration.nix` in. Here, our configuration will be generated in `/mnt/etc/nixos`.
{#flakeify}
## Flakeify the configuration

![[configuration-as-flake]]

{#add-disko}
## Add the `disko` nixosModule

Add the `disko` flake input:
Before we can utilize the `disko` nixosModule, we need to convert our configuration to a flake. This is a simple process of adding a `flake.nix` file in `/mnt/etc/nixos`:

```nix
# In `flake.nix`
```bash
# /mnt/etc/nixos/flake.nix
{
inputs = {
disko.url = "github:nix-community/disko";
disko.inputs.nixpkgs.follows = "nixpkgs";
# NOTE: Replace "nixos-23.11" with that which is in system.stateVersion of
# configuration.nix. You can also use latter versions if you wish to
# upgrade.
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
};
}
```
>[!info]
> `disko.inputs.nixpkgs.follows = "nixpkgs";` is to ensure that `disko` uses the same version of `nixpkgs` as specified in the current flake. This avoids having two different sources of `nixpkgs` and saves space.
Add the `disko` nixosModule:

```nix
{
# In `outputs` of `flake.nix`
nixosConfigurations.nixos = {
# ...
modules = [
./configuration.nix
inputs.disko.nixosModules.disko
];
outputs = inputs@{ self, nixpkgs, ... }: {
# NOTE: 'nixos' is the default hostname set by the installer
nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
# NOTE: Change this to aarch64-linux if you are on ARM
system = "x86_64-linux";
modules = [ ./configuration.nix ];
};
};
}
```
:::{.center}
![[nixos-flake-with-disko.jpeg]]
:::

Move the `disko-config.nix` to the flake directory:

```bash
mv /tmp/disko-config.nix /mnt/etc/nixos
```

Add the disk configuration and use GRUB:
> [!note] Make sure to change a couple of things in the above snippet:
> - Replace `nixos-23.11` with the version from [`system.stateVersion`](https://nixos.wiki/wiki/FAQ/When_do_I_update_stateVersion) in your `/etc/nixos/configuration.nix`. If you wish to upgrade right away, you can also use latter versions, or use `nixos-unstable` for the bleeding edge.
> - `x86_64-linux` should be `aarch64-linux` if you are on ARM
```nix
{
# In `configuration.nix`
imports = [
./hardware-configuration.nix
./disko-config.nix
];
#boot.loader.systemd-boot.enable = true;
#boot.loader.efi.canTouchEfiVariables = true;
boot.loader.grub.enable = true;
boot.loader.grub.efiSupport = true;
boot.loader.grub.efiInstallAsRemovable = true;
}
```
:::{.center}
![[nixos-configuration-nix-with-disko-config.jpeg]]
:::
For details, see [[configuration-as-flake]].

>[!info]
> The boot loader configuration above is compatible with both BIOS and UEFI systems. Additionally, BIOS also requires [boot.loader.grub.device](https://search.nixos.org/options?channel=23.11&show=boot.loader.grub.device&from=0&size=50&sort=relevance&type=packages&query=boot.loader.grub.device) to be set which is done by `disko`'s `nixosModule`.
{#add-disko}
## Add the `disko` nixosModule

Use [[repl]] to check that our configuration is correct, in particular the `fileSystems` set by `disko`:
Our NixOS configuration still does not know anything about filesystems. Let's teach it just that by using the previously downloaded disko example. We do this by adding the `disko` flake input, importing its NixOS module before importing our `/tmp/disko-config.nix`.

1. Add the `disko` flake input in `/mnt/etc/nixos/flake.nix`:

```nix
# In `/mnt/etc/nixos/flake.nix`
{
inputs = {
disko.url = "github:nix-community/disko";
disko.inputs.nixpkgs.follows = "nixpkgs";
};
}
```
>[!info] Why the "follows"?
> `disko.inputs.nixpkgs.follows = "nixpkgs";` is to ensure that `disko` uses the same version of `nixpkgs` as specified in the current flake. This avoids having two different sources of `nixpkgs` and saves space.
1. Add the `disko` nixosModule:
```nix
{
# In `outputs` of `/mnt/etc/nixos/flake.nix`
nixosConfigurations.nixos = {
# ...
modules = [
./configuration.nix
inputs.disko.nixosModules.disko
];
};
}
```
:::{.center}
![[nixos-flake-with-disko.jpeg]]
:::
1. Move the `disko-config.nix` to the flake directory:
```bash
mv /tmp/disko-config.nix /mnt/etc/nixos
```
1. Add the disk configuration and use GRUB:
```nix
{
# In `/mnt/etc/nixos/configuration.nix`
imports = [
./hardware-configuration.nix
./disko-config.nix
];
#boot.loader.systemd-boot.enable = true;
#boot.loader.efi.canTouchEfiVariables = true;
boot.loader.grub.enable = true;
boot.loader.grub.efiSupport = true;
boot.loader.grub.efiInstallAsRemovable = true;
}
```
:::{.center}
![[nixos-configuration-nix-with-disko-config.jpeg]]
:::
>[!info]
> The boot loader configuration above is compatible with both BIOS and UEFI systems. Additionally, BIOS also requires [boot.loader.grub.device](https://search.nixos.org/options?channel=23.11&show=boot.loader.grub.device&from=0&size=50&sort=relevance&type=packages&query=boot.loader.grub.device) to be set which is done by `disko`'s `nixosModule`.
Let's check that our final configuration is correct by using [[repl]]. In particular, we test the `fileSystems` set by `disko`:
```sh
# First, create a flake.lock
Expand All @@ -159,33 +198,38 @@ nix --experimental-features "nix-command flakes" repl
![[nixos-disko-filesystems.jpeg]]
:::

If you see something similar to the above, everything's good and ready to perform the actual installation.

{#install}
## Install NixOS

With our NixOS configuration in place, we will use the `nixos-install` program to install NixOS:

```bash
sudo nixos-install --root /mnt --flake '/mnt/etc/nixos#nixos'
# NOTE: You will be prompted to set the root password at this point.
sudo reboot
```

{#extras}
## Extra configuration (Good to have)
Once rebooted, you should be greeted with the NixOS login screen, allowing you to login to the machine using the root password you had set.

- [Move configuration to home dir](https://nixos.asia/en/tutorial/nixos-install#homedir)
- [Store the configuration on Git](https://nixos.asia/en/tutorial/nixos-install#git)
- [Enable flakes](https://nixos.asia/en/tutorial/nixos-install#enable-flakes)
{#bonus}
## Bonus steps

This tutorial focused mostly on [disko], but left some of the things covered in [[nixos-install-flake|the previous tutorial]] which you might want to consider:

- [Move configuration to home dir](configuration-as-flake.md#homedir)
- [Store the configuration on Git](nixos-install-flake.md#git)
- [Enable flakes](nixos-install-flake.md#enable-flakes)

{#video}
## Video walkthrough

:::{class="flex items-center justify-center mb-8"}
<iframe width="878" height="494" src="https://www.youtube.com/embed/H3NPVazMXOE" title="nixos install with disko" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
:::

## Recap

You now have a reproducible disk partitioning scheme. This does come with a cost of few extra manual steps but you can automate them with a script. Which is what we will do in the next tutorial.

## Up next
{#end}
## Recap & next steps

We will use [nixos-anywhere](https://github.com/nix-community/nixos-anywhere) to automate the steps above and eliminate the need for a USB flash drive (assuming you have a working Linux system or are booted into a rescue image).
You now have a reproducible disk partitioning scheme. This does come with a cost of few extra manual steps but you can automate them with a script. Which is what we will do in the next tutorial. We will use [nixos-anywhere](https://github.com/nix-community/nixos-anywhere) to automate the steps above and eliminate the need for a USB flash drive (assuming you have a working Linux system or are booted into a rescue image).

0 comments on commit 5e01ba9

Please sign in to comment.