Skip to content
Snippets Groups Projects
Select Git revision
  • a2e487c8024e3140e2a446e0a9c75c948f5bfb0a
  • main default protected
  • transmission
  • sonarr
  • private-notes
  • ftpd
  • traccar
  • backup-docs
  • grist-native-package
  • new-runners
  • container-test
11 results

installation.md

Blame
  • Nicolas Lenz's avatar
    a2e487c8
    History
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.

    Installation

    These are instruction on how to install this configuration on a (new) machine.

    Note: command lines starting with # should be run as the root user.

    Prepare Device Config

    You'll need a device config that sets up the device-specific configuration.

    • create a file for your device config in devices/HOSTNAME.nix

    • start off with an existing device config and customize the imported modules, the network config and so on

    • detect your hardware config with nixos-generate-config on the corresponding device, you can find it on a NixOS install disk or in the nixos-install-tools package if you have a running Nix installation

      # nixos-generate-config --show-hardware-config

    • incorporate the relevant options into the device config

      That'll mostly be the kernel modules, stuff like microcode things and the file systems if you want to keep some of them. My configs don't use the suggested network config and some other stuff from there though, so leave that out.

      Note: you probably won't actually need some of the modules detected for boot.initrd.availableKernelModules, the detection script just puts modules for all connected hardware there, whether you need them to boot or not. You can experiment with which modules you actually need after the installation is done if you want to. If you can't boot anymore, you can always just boot an older configuration!

    • TODO: machine-id

    • add entries in flake/configurations.nix and flake/colmena.nix for your device with the correct system set (the correct system is in the detected hardware config under nixpkgs.hostPlatform)

    Partitioning

    GPT partition labels (not the same thing as filesystem labels!) are used to refer to partitions, so the config doesn't need to be adjusted to new partition UUIDs on a reinstall.

    This of course means that the partition labels have to be set as the configs expect.

    • create a GPT partition table on your target device

    • create 1 GiB partition at beginning of device, with partition label "boot" ("partition name" in GParted)

    • format boot as FAT (mkfs.vfat), flag it as esp

    • create partition filling the rest of the device, with partition label "main"

    • create a LUKS container on /dev/disk/by-partlabel/main:

      # cryptsetup luksFormat /dev/disk/by-partlabel/main

    • open the created LUKS container:

      # cryptsetup open /dev/disk/by-partlabel/main main

    • format /dev/mapper/main as btrfs:

      # mkfs.btrfs /dev/mapper/main

    Mounting & Subvolumes

    btrfs subvolumes are used to organize persistent data.

    • mount /dev/disk/by-partlabel/boot at /mnt/boot

      # mkdir -p /mnt/boot
      # mount /dev/disk/by-partlabel/boot /mnt/boot
    • mount /dev/mapper/main at /mnt/mnt/main:

      # mkdir -p /mnt/mnt/main
      # mount /dev/mapper/main /mnt/mnt/main

      Note: This mounts the root subvolume of main. This won't actually be used for data, but we need to be able to access it, e.g. to create subvolumes. It will also be accessible at that mountpoint in the installed system (without the first /mnt prefix of course, so at /mnt/main).

    • create btrfs subvolumes on main: /nix, /persist, /persist/.snapshots (for snapper snapshots) and /swap:

      # btrfs subvolume create /mnt/mnt/main/nix
      # btrfs subvolume create /mnt/mnt/main/persist
      # btrfs subvolume create /mnt/mnt/main/persist/.snapshots
      # btrfs subvolume create /mnt/mnt/main/swap
    • create btrfs swapfile in /mnt/mnt/main/swap/swapfile:

      # btrfs filesystem mkswapfile /mnt/mnt/main/swap/swapfile -s $SIZE

      $SIZE could be something like 32G.

    • mount the subvolumes with the right options at /mnt/nix:

      # mkdir /mnt/nix /mnt/persist /mnt/swap
      # mount -o "subvol=/nix" -o "compress=zstd" -o "noatime" \
        /dev/mapper/main /mnt/nix
      # mount -o "subvol=/persist" -o "compress=zstd" \
        /dev/mapper/main /mnt/persist
      # mount -o "subvol=/swap" -o "noatime" \
        /dev/mapper/main /mnt/swap

    Create home dir in /persist

    For devices with home dir persistence, we'll need to create that manually. That's because it's managed by impermanence in home-manager, which doesn't have the permissions to create a directory in the root-owned persist dir.

    • # mkdir -p /mnt/persist/home/eisfunke
    • # chown 1000:100 /mnt/persist/home/eisfunke
    • # chmod 700 /mnt/persist/home/eisfunke

    TODO: shouldn't be necessary anymore (I don't use the impermanence home-manager module anymore)

    Create Host Keys

    Regardless of whether the machine will be running an sshd SSH server, you'll need to generate an SSH host key. This is needed for decrypting secrets via agenix.

    If the device uses remote unlocking of an encrypted root partition you'll also need another, different, SSH key for use inside the initrd during boot for entering the key remotely.

    # mkdir -p /mnt/persist/etc/ssh
    # ssh-keygen -t ed25519 -N "" -f /mnt/persist/etc/ssh/ssh_host_ed25519_key -C "host_yourhostname_2000-00-00"
    # ssh-keygen -t ed25519 -N "" -f /mnt/persist/etc/ssh/ssh_boot_ed25519_key -C "boot_yourhostname_2000-00-00"

    -t for ssh-keygen sets the key type, we use ed25519. -N sets the passphrase, we don't want one, -f sets the output file and -C sets the key comment, which is appended to the public key file.

    Add the public key from /persist/etc/ssh/ssh_host_ed25519_key.pub to res/ssh-public-keys.nix and in secrets/secrets.nix. Then run agenix -r in the secrets folder to reencrypt all secrets with the new keys so the new machine will be able to decrypt them. Commit and push the changes.

    TODO: create user keys

    Install NixOS

    With the device config prepared and everything partitioned, mounted and keyed, you're ready to actually install NixOS from this flake. Note that the flake must be given as Git repo because the config uses things like the current flake revision, which isn't available for e.g. a tarball.

    TODO: this requires git to be installed, is it? TODO: maybe use nixos-rebuild instead, remotely?

    # nixos-install --no-root-password --root /mnt \
      --flake git+https://git.eisfunke.com/config/nixos.git#$HOSTNAME

    If git.eisfunke.com is not available, say because I'm trying to reinstall the server it's running on, the mirror repository at https://gitlab.fachschaften.org/nicolas.lenz/nixos.git can be used.

    In case you need to reset the cached repo, delete Nix's Git cache:

    # rm -r ~root/.cache/nix/gitv3

    Post Installation Setup

    Sadly, not all setup and logins can be automated using the config. Some steps have to be done manually after a fresh install.

    • If the installation includes calendar / contact sync, you have to run vdirsyncer discover manually once (and after every change to the accounts config or after adding a new collection). See calcard.nix.

    • If the installation includes a graphical desktop, you have to setup a default keyring without (e.g. named "Default keyring") any password using Seahorse (called "Passwords and Keys" in the launcher).

      On first automatic login, you might be prompted to create a keyring automatically. Just leave the password empty then.

      On a non-automatic login, a keyring with your login password will be created automatically without prompt. In that case you'll have to change the password to no password using Seahorse.

      No password is required in order for the keyring to be automatically unlocked even with automatic login. Otherwise you'll be prompted to unlock it manually every time. See also /nixos/desktop.nix.

    • If the installation includes Nextcloud, you have to setup the Nextcloud sync client using the GUI application.