- Linux distribution based on Nix package manager
- Supports declarative reproducible system configurations
- “Unbreakable”
- Boot to specific configuration generations. (as mentioned above - reproducible)
- nix-store: no
/lib
&/usr/lib
. almost non-existant/bin
&/usr/bin
. ->/nix/store
- nix-env: install packages at user level without having to change system state
- NixOS
- Manual: Downloads -> NixOS -> More -> Manual
- Unstable: Downloads -> NixOS -> More -> also available
- balenaEtcher
- On boot: Esc / Del / F1-12
- Download GUI ISO
- Optional minimal ISO
- No password needed
- Root
- Terminal (Konsole)
$ sudo su
- Layout:
- minimal iso:
# loadkeys ...
- graphical iso:
# setxkbmap ...
- minimal iso:
- 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)
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
# 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
- Generate default configuration:
# nixos-generate-config --root /mnt
- Location:
# cd /mnt/etc/nixos
- Argument on how to evaluate config:
{config, pkgs, ...}:
- Pull in other files used within the config:
import = [./hardware-configuration.nix];
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
}
'';
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.
};
{ 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
};
};
}
- 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;
- Deprecated but keep:
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" ];
};
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 €
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;
};
};
{ 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";
};
};
};
};
}
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";
};
};
};
};
services.xserver.libinput = {
enable = true;
#tapping = true;
#naturalScrolling = true;
#...
};
users.users.<name> = {
isNormalUser = true;
extraGroups = [ "wheel" "video" "audio" "networkmanager" "lp" "scanner"]
#initialPassword = "password";
#shell = pkgs.zsh;
};
environment.systemPackages = with pkgs; [
vim
wget
git
#pkgs.firefox
firefox
];
- 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.
- 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
$ 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";
# };
- For initial installation:
# nixos-install
- After applying changes to the config:
# nixos-rebuild switch
- Lastly: Set a root password
- Log in with given password at
users.users.<user>.initialPassword
- Ctrl + Alt + F1 -> Log in via root
# passwd <user>
- Ctrl + Alt + F7 -> Log in via user
- Individually via Nix Package Manager
- Install:
$ nix-env -iA nixos.firefox
- List:
$ nix-env -q
- Uninstall:
$ nix-env --uninstall firefox
- Install:
- Alternatively you can also use
$ nix-shell -p <package name>
- Configuration file: see below
Installed system-wide with configuration.nix
environment = {
systemPackages = with pkgs; [
plex
superTux
];
};
nixpkgs.config.allowUnfree = true;
Some packages will also have options to configure it further
services = {
plex = {
enable = true;
openFirewall = true;
};
};
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;
};
}
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
$ sudo nixos-rebuild switch
A. $ nix-channel --add https://nixos.org/channels/nixos-21.11
OR
B. $ nix-channel --update
- Next rebuild,use the –upgrade flag:
$ sudo nixos-rebuild --upgrade
D. Installed through nix-env:
$ nix-env -u '*'
system.autoUpgrade = {
enable = true;
channel = "https://nixos.org/channels/nixos-unstable";
};
- 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
nix = {
settings.auto-optimise-store = true;
gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 7d"
};
};
- 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
- It’s like configuration.nix, but for the user environment.
- Plenty more options to declare packages
- Also a better way to manage dotfiles
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.
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 ];
};
}
Installation:
$ nix-shell '<home-manager>' -A install
Configuration file:
$ cd ~/.config/nixpkgs/home.nix
- Home-Manager Options
$ man home-configuration.nix
home.packages = with pkgs; [
firefox
];
services.dunst = {
enable = true;
};
$ home-manager switch
For example, randomly nicked files used by other (who don’t use NixOS)
home.file = {
".config/alacritty/alacritty.yml".text = ''
{"font":{"bold":{"style":"Bold"}}}
'';
};
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;
};
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 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
nix = {
package = pkgs.nixFlakes;
extraOptions = "experimental-features = nix-command flakes";
};
This command will generate a flake.nix and flake.lock file
cd
into a location to store in your system$ nix flake init
attribute set of all the dependencies used in the flake
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
};
function of an argument that uses the inputs for reference
- Configure what you imported
- Can be pretty much anything: Packages / configurations / modules / etc…
{
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 ];
#};
};
};
}
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 .#
{
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";
};
}
];
};
};
};
}
{
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 ];
};
}
];
};
};
};
}
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>
Can be build with default rebuild command
$ sudo nixos-rebuild switch --flake .#<host>
This will update the flake.lock file
$ nix flake update
- Now rebuild and switch
- 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 */