NixOS

Change to Root user

sudo su

Keyboard Layout

loadkeys de_CH-latin1

Check UEFI mode

If the following command works, the system is booted in EFI.

ls /sys/firmware/efi/efivars

Verify internet connection

ping wiki.exu.li

Creating partitions

cfdisk

Use EFI System for EFI partition
Use Linux filesystem for other partitions

(LUKS) Create encrypted partition

Note: Do not put your /efi or /boot partition on an encrypted partition!

Create encrypted Partition
cryptsetup luksFormat /dev/(partition)

To view if this worked correctly
cryptsetup luksDump /dev/(partition)

Open the partition
Give it a fitting name
cryptsetup open /dev/(partition) (name)

Check if this worked with ls /dev/mapper/
The name should show up there

Format partitions

For EFI or BOOT partition Fat 32:
mkfs.fat -F32 /dev/(partition)

All other partitions btrfs:
mkfs.btrfs /dev/(partition)

Mounting partitions

Generally partitions have to be mounted where you will later use them in your system.
BTRFS with its subvolumes is a special case

Root: /mnt
EFI: /mnt/boot
Home: /mnt/home
etc...

Boot partition

mkdir /mnt/boot
mount /dev/(partition) /mnt/boot

[BTRFS] Btrfs preparation of subvolumes and mounting

Mount root partition

mount /dev/(partition) /mnt
btrfs subvolume create /mnt/root
btrfs subvolume create /mnt/home
btrfs subvolume create /mnt/nix
btrfs subvolume create /mnt/swap
umount /mnt
mount -o compress=zstd,subvol=root /dev/(partition) /mnt
mkdir /mnt/{boot,home,nix,swap}
mount -o compress=zstd,subvol=home /dev/(partition) /mnt/home
mount -o compress=zstd,noatime,subvol=nix /dev/(partition) /mnt/nix
mount -o noatime,subvol=swap /dev/(partition) /mnt/swap

Don't forget mounting other partitions!!

Swap

Swapfile

[BTRFS] Swapfile on btrfs

truncate -s 0 /mnt/swap/swapfile
chattr +C /mnt/swap/swapfile
btrfs property set /mnt/swap/swapfile compression none
fallocate -l (size)M /mnt/swap/swapfile

Initialising swapfile

chmod 600 /mnt/swap/swapfile
mkswap /mnt/swap/swapfile
swapon /mnt/swap/swapfile

Generate initial config

nixos-generate-config --root /mnt

Modify config file

{ config, pkgs, ... }:

let
  user = "exu";
  hostname = "nixos";
in
{

  # systemd-boot configuration limit
  boot.loader.systemd-boot.configurationLimit = 5;

  # Define hostname
  networking.hostName = "${hostname}";

  # time zone
  time.timeZone = "Europe/Zurich";

  # default locale
  i18n.defaultLocale = "de_CH.UTF-8";

  # TTY keymap
  console = {
    keyMap = "de_CH-latin1";
  };

  # Enable X11
  services.xserver = {
    enable = true;
    #displayManager.defaultSession = "none+hyprland";
    displayManager.lightdm = {
      enable = true;
      greeters.gtk.enable = true;
    };
    windowManager.openbox = {
      enable = true;
    };
  };

  # TODO figure out how to get this working in the ISO
  # Hyprland
  #programs.hyprland = {
  #  enable = true;
  #};

  # X11 keymap
  services.xserver.layout = "ch";

  # CUPS
  services.printing.enable = true;

  # Pipewire
  security.rtkit.enable = true;
  services.pipewire = {
    enable = true;
    alsa.enable = true;
    alsa.support32Bit = true;
    pulse.enable = true;
    # If you want to use JACK applications, uncomment this
    #jack.enable = true;
  };

  # Enable touchpad support
  services.xserver.libinput.enable = true;

  # Enable fish shell for nix
  programs.fish.enable = true;

  # Create user with initial password
  users.users.${user} = {
    isNormalUser = true;
    extraGroups = [ "wheel" "video" "audio" "networkmanager" "lp" "scanner" ];
    initialPassword = "pass";
    shell = pkgs.fish;
  };

  # System installed packages
  environment.systemPackages = with pkgs; [
    vim
    wget
  ];

  # Allow unfree packages
  nixpkgs.config.allowUnfree = true;

  # Enable SSH server
  services.openssh.enable = true;

[BTRFS] Mount options

Mount options are not automatically detected and have to be readded manually to their respective filesystems. As the hardware-config file is automatically generated, we have to add the relevant options in our main config file.

  # BTRFS options
  fileSystems = {
    "/".options = [ "compress=zstd" ];
    "/home".options = [ "compress=zstd" ];
    "/nix".options = [ "compress=zstd" "noatime" ];
    "/swap".options = [ "noatime" ];
  };

NixOS Wiki BTRFS

Swapfile configuration

The swapfile is not automatically detected either and has to be specified in the configuration file.

swapDevices = [ { device = "/swap/swapfile"; } ];

Modify hardware config file

networking.useDHCP = lib.mkDefault false;
networking.interfaces.(interface).useDHCP = lib.mkDefault true;

Installation

NOTE: Hyprland is not yet in any stable release of NixOS and needs to be specified later maybe?

nixos-install

You will be prompted to set a password for the root user.

Upgrade to unstable

From the installed system, run the following commands to change to the unstable channel.
Note that using sudo is required to change the system channel.

sudo nix-channel --add https://nixos.org/channels/nixos-unstable nixos

And rebuild the system
Before rebuilding it is possible to reenable the previously commented config for Hyprland

  # Hyprland
  programs.hyprland = {
    enable = true;
  };

Rebuild with upgrading packages

sudo nixos-rebuild switch --upgrade

Rebuild without upgrading packages

sudo nixos-rebuild switch

Usefull commands

Install single package as user

nix-env -iA nixos.(package)

Uninstall single user package

nix-env -e (package)

Rebuild and upgrade nix config

nixos-rebuild switch --upgrade

Collect and delete old packages

nix-collect-garbage --delete-old
nix-collect-garbage
nix-collect-garbage -d

List generations

nix-env --list-generations

Delete generations

nix-env --delete-generations (gen1) (gen2) # generation gen1 and gen2
nix-env --delete-generations 7d # older than 7 days

"Fixing?" errors about derivations

While trying to rebuild NixOS in a test VM I made, I ran across the following errors:

unpacking channels...
this derivation will be built:
  /nix/store/xzmcf9zqnk3jlkdk7z80y9f1xwjlh89k-nixos-rebuild.drv
error: getting status of '/nix/store/a9ndjg0b1ivi0av9m93vfkrndp7fqbw1-strip.sh': No such file or directory
building Nix...
error: opening file '/nix/store/6igxs6xrl07pfh7l2lcls4z43b61xpn3-patchelf-0.15.0.drv': No such file or directory

Nix seemed to still point to some older paths for some reason.
After some scouring the web, I finally found a post that helped me.

File in nix store empty, unable to be repaired

From this post I got the following command

nix-store --verify --check-contents --repair

Running the command only once did not resolve all errors, so I just ran it multiple times until it didn't output any errors anymore.

Automatisms

Automatic upgrades

  # Enable automatic package upgrades
  system.autoUpgrade = {
    enable = true;
    channel = "https://nixos.org/channels/nixos-unstable";
  };

Automatic garbage collection

  # Enable automatic garbage collection
  nix = {
    settings.auto-optimise-store = true;
    gc = {
      automatic = true;
      dates = "weekly";
      options = "--delete-older-than 7d";
    };
  };

Home-Manager

Add the Home-Manager channel to NixOS

sudo nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
sudo nix-channel --update

Add <home-manager/nixos> in the imports list of configuration.nix

  imports =
    [
      ./hardware-configuration.nix
      <home-manager/nixos>
    ];

  home-manager.users.${user} = { pkgs, ... }: {
    home.stateVersion = "22.11" # same as the system.stateVersion
    home.packages = [
      pkgs.firefox
    ];
  };