Skip to content

Latest commit

 

History

History
838 lines (752 loc) · 21.5 KB

nixos.org

File metadata and controls

838 lines (752 loc) · 21.5 KB

NixOS Fresh Install Guide

rsc/NixOS.svg

Table of Content

NixOS

Introduction

  1. Linux distribution based on Nix package manager
  2. Supports declarative reproducible system configurations
  3. “Unbreakable”
    • Boot to specific configuration generations. (as mentioned above - reproducible)
  4. nix-store: no /lib & /usr/lib. almost non-existant /bin & /usr/bin. -> /nix/store
  5. nix-env: install packages at user level without having to change system state

Getting Started

NixOS Website

  • NixOS
  • Manual: Downloads -> NixOS -> More -> Manual
  • Unstable: Downloads -> NixOS -> More -> also available

Burning ISO

  • balenaEtcher

Booting into ISO

Via USB

  • On boot: Esc / Del / F1-12

Virt-Manager

  • Download GUI ISO
  • Optional minimal ISO
  • No password needed
  • Root
    • Terminal (Konsole)
    • $ sudo su
  • Layout:
    • minimal iso: # loadkeys ...
    • graphical iso: # setxkbmap ...

Partitioning

GUI: Gparted

  • Device -> Create partition table -> msdos (legacy boot) -> gpt (uefi boot)
  • Add new partition -> fileSystem: ext4/linux-swap
  • Manage flags -> boot for ext4 (possible not necessary)
  • Label partitions (useful later)

Terminal: Parted

These step are for a fresh installation. Not dual boot

# parted /dev/sda -- mklabel msdos (gpt for uefi)
# parted /dev/sda -- mkpart primary 1MiB -8GiB (512MiB -8GiB for uefi)
# parted /dev/sda -- mkpart primary linux-swap -8GiB 100%

/* extra for UEFI */
# parted /dev/sda -- mkpart ESP fat32 1Mib 512MiB
# parted /dev/sda -- set 3 esp on

# mkfs.ext4 -L nixos /dev/sda1
# mkswap -L swap /dev/sda2

/* extra for UEFI */
# mkfs.fat -F 32 -n boot /dev/sda3

Mounting

# mount /dev/disk/by-label/nixos /mnt

/* extra for UEFI */
# mkdir -p /mnt/boot
# mount /dev/disk/by-label/boot /mnt/boot

# swapon /dev/sda2

Initial Configuration

Generate

  • Generate default configuration:
    • # nixos-generate-config --root /mnt
  • Location:
    • # cd /mnt/etc/nixos

Configuration.nix

General

  • Argument on how to evaluate config:
    • {config, pkgs, ...}:
  • Pull in other files used within the config:
    • import = [./hardware-configuration.nix];

Boot

Legacy

Only viable if dualbooting linux distributions

# Default Grub setup
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
boot.loader.grub.device = "/dev/vda";
# Dual booting made easy (Optional)
boot.loader.grub.useOSProber = true;
# Dual booting made a bit harder (Extra Optional)
boot.loader.grub.extraEntries = ''
  menuentry "Windows 10" {
    chainloader (hd0,1)+1
  }
'';
UEFI

Used for larger boot drives and dual booting with Windows

# Default UEFI setup
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# Dual Booting using grub
boot.loader = {
  efi = {
    canTouchEfiVariables = true;
    efiSysMountPoint = "/boot/efi"; # /boot will probably work too
  };
  grub = {                          # Using grub means first 2 lines can be removed
    enable = true;
    #device = ["nodev"];            # Generate boot menu but not actually installed
    devices = ["nodev"];            # Install grub
    efiSupport = true;
    useOSProber = true;             # Or use extraEntries like seen with Legacy
  };                                # OSProber will probably not find windows partition on first install. Just do a rebuild than.
};
Extras
{ pkgs, ... }:

{
  boot ={
    kernelPackages = pkgs.linuxPackages_latest;       # Get latest kernel
    initrd.kernelModules = ["amdgpu"];                # More on this later on (setting it for xserver)
    loader = {
      #efi = {
        #canTouchEfiVariables = true;
        #efiSysMountPoint = "/boot/efi";
      #};
      grub = {
        #enable = true;
        #devices = ["nodev"];
        #efiSupport = true;
        #useOSProber = true;
        configurationLimit = 5;                       # Limit stored system configurations.
      };                                              # Also exists for systemd-boot
      timeout = 5;                                    # Work for grub and efi boot, time before auto-boot
    };
  };
}

Networking

  • Uncomment: networking.hostName="nixos";
  • Network card details. Note: some of these options might have moved to hardware-configuration.nix
    • Deprecated but keep: networking.useDHCP = false;
    • Just internet via ethernet: networking.interfaces.<networkcard-id>.useDHCP = true;
Extras
networking = {
  #hostName = "nixos";
  #networkmanager.enable = true;
  interfaces ={
    enp0s3 = {
      #useDHCP = true;
      ipv4.addresses = [ {                  # Of course not compatible with networkmanager
        address = "192.168.0.50";
        prefixLength = 24;
      } ];
    };
  };
  defaultGateway = "192.168.0.1";
  nameservers = [ "1.1.1.1" ];
};

Internationalisation

Locales, Layouts and Options

# Clock
time.timeZone = "Belgium/Brussels";
# Locale
i18n.defaultLocale = "en_US.UTF-8";
i18n.extraLocaleSettings = {
  LC_TIME = "nl_BE.UTF-8";
  LC_MONETARY = "nl_BE.UTF-8";
};
# TTY layout
console = {
  font = "...";
  keyMap = "...";                           # us / fr / azerty / etc...
};
# XServer layout (possibly also sets console now)
services.xserver.xkb.layout = "..."             # us / fr / be / etc..
# Extra keyboard settings:
services.xserver.xkb.options = "eurosign:e"; # For example adds €

Display Managers/Desktop Environments/Window Managers

Default

services.xserver.enable = true;
services.xserver.displayManager.sddm.enable = true;
services.xserver.desktopManager.plasma5.enable = true;

Customized

services = {
  xserver = {
    enable = true;
    displayManager = {
      lightdm.enable = true;
      defaultSession =none+bspwm;
    };
    desktopManager.xfce.enable = true;
    windowManager.bspwm.enable = true;
  };
};

Hardware

Audio & Bluetooth
PulseAudio Example
{ pkgs, ... }:

{
  sound = {
    enable = true;
    mediaKeys.enable = true;
  };
  hardware = {
    pulseaudio = {
      enable = true;
      package = pkgs.pulseaudioFull;
      extraConfig = ''
        load-module module-switch-on-connect
      '';
    };
    bluetooth = {
      enable = true;
      hsphfpd.enable = true;         # HSP & HFP daemon
      settings = {
        General = {
          Enable = "Source,Sink,Media,Socket";
        };
      };
    };
  };
}
Pipewire Example
services = {
  pipewire = {
    enable = true;
    alsa = {
      enable = true;
      support32Bit = true;
    };
    pulse.enable = true;
    jack.enable = true;
  };
};
hardware = {
  bluetooth = {
    enable = true;
    settings = {
      General = {
        Enable = "Source,Sink,Media,Socket";
      };
    };
  };
};
Touchpad
services.xserver.libinput = {
  enable = true;
  #tapping = true;
  #naturalScrolling = true;
  #...
};

Users

users.users.<name> = {
  isNormalUser = true;
  extraGroups = [ "wheel" "video" "audio" "networkmanager" "lp" "scanner"]
  #initialPassword = "password";
  #shell = pkgs.zsh;
};

Packages

environment.systemPackages = with pkgs; [
  vim
  wget
  git
  #pkgs.firefox
  firefox
];

StateVersion

  • No need to touch this.
  • Nothing to do with the version of the system.
  • Just tells the version of state/config
  • Can be updated to a stable version if you are really sure.
    • Do consult the release notes first.

Hardware-configuration.nix

Generate

  • Also get automatically generated with:
    • # nixos-generate-config --root /mnt
  • Should detect mounted drives, device parts, kernelModules, etc.. that are needed
  • Can be deleted and regenerated with:
    • # nixos-generate-config

File System

  • $ sudo blkid
  • or just look in gparted
fileSystems."/" =
  { device = "/dev/disk/by-uuid/e97ad9a8-d84f-4710-b8c9-cfa7707510ca";
    fsType = "ext4";
  };

#fileSystem."/" =
#  { device = "/dev/disk/by-label/nixos";
#    fsType = "ext4";
#  };

Installation

System

  • For initial installation:
    • # nixos-install
  • After applying changes to the config:
    • # nixos-rebuild switch
  • Lastly: Set a root password

Login

initialPassword

  • Log in with given password at users.users.<user>.initialPassword

via TTY

  • Ctrl + Alt + F1 -> Log in via root
  • # passwd <user>
  • Ctrl + Alt + F7 -> Log in via user

Installing and Declaring Packages

Options

  • Individually via Nix Package Manager
    • Install: $ nix-env -iA nixos.firefox
    • List: $ nix-env -q
    • Uninstall: $ nix-env --uninstall firefox
  • Alternatively you can also use $ nix-shell -p <package name>
  • Configuration file: see below

Links

Declaring Packages

Installed system-wide with configuration.nix

environment = {
  systemPackages = with pkgs; [
    plex
    superTux
  ];
};

nixpkgs.config.allowUnfree = true;

Declaring Option

Some packages will also have options to configure it further

services = {
  plex = {
    enable = true;
    openFirewall = true;
  };
};

Variables

Values that can change often or you want to use multiple times

let
  rofi-theme = {
    "*" = {
      bg = "#FFFFFF";
    };
  };
in
{
  programs.rofi = {
    enable = true;
    theme = rofi-theme;
  };
}

Overlays

Change packages or add new packages to existing in nix

nixpkgs.overlays = [
  (self: super: {
    sl = super.sl.overrideAttrs (old: {
      src = super.fetchFromGitHub {
        owner = "mtoyoda";
        repo = "sl";
        rev = "923e7d7ebc5c1f009755bdeb789ac25658ccce03";
        sha256 = "0000000000000000000000000000000000000000000000000000";
      };
    });
  })

  (self: super: {
    discord = super.discord.overrideAttrs (
      _: { src = builtins.fetchTarball {
        url = "https://discord.com/api/download?platform=linux&format=tar.gz";
        sha256 = "0000000000000000000000000000000000000000000000000000"; #52 0's
      }; }
    );
  })
];
#Should be the same for home-manager

Applying

  • $ sudo nixos-rebuild switch

Extras

Updating & Upgrading

Nix-channel

A. $ nix-channel --add https://nixos.org/channels/nixos-21.11 OR B. $ nix-channel --update

  1. Next rebuild,use the –upgrade flag:
    • $ sudo nixos-rebuild --upgrade

D. Installed through nix-env:

  • $ nix-env -u '*'

Configuration.nix

system.autoUpgrade = {
  enable = true;
  channel = "https://nixos.org/channels/nixos-unstable";
};

Garbage Collection

Command-line

  • Remove undeclared packages, dependencies and symlinks:
    • $ nix-collect-garbage
  • Remove older generations:
    • $ nix-collect-garbage --delete-old
    • List generations:
      • $ nix-env --list-generations
  • Remove specific generations or older than … days:
    • $ nix-env --delete-generations 14d
    • $ nix-env --delete-generations 10 11
    • Optimize store:
      • $ nix-store --gc
  • All in one:
    • # nix-collect-garbage -d

Configuration.nix

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

Troubleshooting nix store

  • First make sure it’s not something wrong in your configuration.
  • If it’s clearly not something like a syntax it might be a corrupted store or cache where it fails to extract something.
  • This can be often be fixed running the commands below:
$ rm -r /tmp/* $HOME/.cache/nix
$ sudo nix-collect-garbage && nix-collect-garbage && sudo nix-store --verify --check-contents --repair && sudo nix-store --optimise

Home-Manager

Introduction

  • It’s like configuration.nix, but for the user environment.
  • Plenty more options to declare packages
  • Also a better way to manage dotfiles

Getting Started

Home-Manager Website

Setup

Initial

As a user

  • Add the channel: needs to be run with root privileges if you want to us the NixOS Module
    • $ nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
    • $ nix-channel --add https://github.com/nix-community/home-manager/archive/release-21.11.tar.gz home-manager
  • $ nix-channel --update
  • Just to be sure, relog.

NixOS Module

Add to configuration.nix

let
in
{
  imports = [ <home-manager/nixos> ];

  users.users.<name> = {
    isNormalUser = true;
  }

  home-manager.users.<name> = { pkgs,}: {
    # declared packages. for example:
    home.packages = [ pkgs.atool pkgs.httpie ];
  };
}

Standalone

Installation:

  • $ nix-shell '<home-manager>' -A install

Configuration file:

  • $ cd ~/.config/nixpkgs/home.nix

Configuration

Links

Declare user packages

home.packages = with pkgs; [
  firefox
];

services.dunst = {
  enable = true;
};

Applying

  • $ home-manager switch

Dotfiles

Copy/Symlink

Existing config files

For example, randomly nicked files used by other (who don’t use NixOS)

home.file = {
  ".config/alacritty/alacritty.yml".text = ''
    {"font":{"bold":{"style":"Bold"}}}
  '';
};

Stored files

Which also don’t have any links with NixOS

home.file.".doom.d" = {
  source = ./doom.d;
  recursive = true;
  onChange = builtins.readFile ./doom.sh;
};
home.file.".config/polybar/script/mic.sh"={
  source = ./mic.sh;
  executable = true;
};

Declared

Example will generate a file .config/bspwm/bspwmrc

{
  xsession = {
    windowManager = {
      bspwm = {
        enable = true;
        rules = {
          "Emacs" = {
            desktop = "3";
            follow = true;
            state = "tiled";
          };
          ".blueman-manager-wrapped" ={
            state = "floating";
            sticky = true;
          };
        };
      };
    };
  };
}

Flakes

Introduction

  • Flakes are an “upcoming feature” of the Nix package manager.
  • Specify code dependencies declaratively (will be stored in flake.lock)
    • For example: home-manager
  • Rebuilding and updating whole system made easy
  • Very useful tool to build your own config
    • Multiple configs in one
    • People with github dotfiles will feel right at home

Getting Started

Flakes Wiki

Setup

Configuration.nix

nix = {
  package = pkgs.nixFlakes;
  extraOptions = "experimental-features = nix-command flakes";
};

Generate

This command will generate a flake.nix and flake.lock file

  • cd into a location to store in your system
  • $ nix flake init

Inputs and Outputs

Inputs

attribute set of all the dependencies used in the flake

inputs = {
  nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
};
Outputs

function of an argument that uses the inputs for reference

  • Configure what you imported
  • Can be pretty much anything: Packages / configurations / modules / etc…

Configuration

NixOS

Flake.nix

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    #nixpkgs-unstable.url = "github:nixos/nixpkgs/nixpkgs-unstable";
  };
  outputs = { nixpkgs, home-manager, ... }:
    let
      system = "x86_64-linux";
      pkgs = import nixpkgs {
        inherit system;
        config.allowUnfree = true;
      };

      lib = nixpkgs.lib;
    in {
      nixosConfigurations = {
         <user> = lib.nixosSystem {
          inherit system pkgs;
          modules = [ ./configuration.nix ];
        };
        #<second user> = lib.nixosSystem {
        #inherit system;
        #modules = [ ./configuration.nix ];
        #};
      };
    };
}

Build

a “.(#)” will just build host found in location specify host with “<config path>#<host>” appended

  • optional $ cp /etc/nixos/* <flake location>
  • $ nixos-rebuild build --flake .#

or build and automatically switch

  • $ sudo nixos-rebuild switch --flake .#

Home-Manager

Flake.nix

Seperate
{
  inputs = {
    #other inputs
    home-manager = {
      url = github:nix-community/home-manager;
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };
  outputs = { self, nixpkgs, home-manager, ... }:
    let
      #variables
      system = "x86_64-linux";
      pkgs = nixpkgs.legacyPackages.system.${system};
    in {
      #other outputs
      homeManagerConfigurations = {
        <user> = home-manager.lib.homeManagerConfiguration {
          inherit pkgs;
          extraSpecialArgs = { inherit <variables>; };
          modules = [
            </relative/path/to/home.nix>
            {
              home = {
                username =<user>;
                homeDirectory = “/home/<user>;
                packages = [ pkgs.home-manager ];
                stateVersion = "22.05";
              };
            }
          ];
        };
      };
    };
}
Inside nixosConfigurations
{
  inputs = {
    #other inputs
    home-manager = {
      url = github:nix-community/home-manager;
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };
  outputs = { self, nixpkgs, home-manager, ... }:
    let
      #variables
    in {
      nixosConfigurations = {
        <user> = lib.nixosSystem {
          inherit system;
          modules = [
            ./configuration.nix
            home-manager.nixosModules.home-manager {
              home-manager.useGlobalPkgs = true;
              home-manager.useUserPackages = true;
              home-manager.users.<user> = {
                imports = [ ./home.nix ];
              };
            }
          ];
        };
      };
    };
}

Build

Seperate

This will build a directory with everything home-manager needs. An activation script is also located inside this dir

  • $ nix build .#homeManagerConfigurations.<user>.activationPackage
  • $ ./result/activate

Afterwards you will be able to build home-manager from the flake using

  • $ home-manager switch --flake .#<host>
Inside nixosConfiguraitons

Can be build with default rebuild command

  • $ sudo nixos-rebuild switch --flake .#<host>

Updating

This will update the flake.lock file

  • $ nix flake update
  • Now rebuild and switch

Flake on fresh install

  • Boot into ISO
$ sudo su
# nix-env -iA nixos.git
# git clone <repo url> /mnt/<path>
# nixos-install --flake .#<host>
# reboot
/* login */
$ sudo rm -r /etc/nixos/configuration.nix
/* move config to desired location */

Resources

  1. NixOS Website
  2. NixOS Learn
  3. NixOS Manual
  4. NixOS Wiki
  5. Nix Pills
  6. Home-Manager Github
  7. Home-Manager Manual
  8. Home-Manager Appendix_A
  9. Home-Manager Appendix B
  10. List of reference configurations