JustToThePoint English Website Version
JustToThePoint en español
Colaborate with us

NixOS

When you have eliminated the impossible, whatever remains, however improbable, must be the truth, Sherlock Holmes.

Introduction to NixOS

NixOS is a unique and powerful Linux distribution that leverages the Nix package manager. It is renowned for its immutable design and atomic update model, which means that the system's state is defined by a configuration file and system updates are applied atomically, reducing the risk of system breakage and making NixOS very stable and reliable.

NixOS is a Linux distribution that uses the Nix package manager to handle both packages and system configuration in a purely functional manner. This approach ensures that builds are reproducible and that the system state can be reliably replicated or rolled back.

Key Features:

  1. Immutable Design: System configurations are declaratively specified, leading to consistent and reproducible environments.
  2. Atomic Updates: System updates are applied atomically, meaning you can roll back to previous configurations if something goes wrong.
  3. Isolation: Packages are stored in isolation from each other, meaning each package is placed in its own directory within the Nix store. This isolation reduces conflicts and improves stability, as packages do not overwrite or interfere with each other’s files.

In this guide, we’ll walk through the installation of NixOS and delve into the configuration file, explaining each component to help you understand how to tailor NixOS to your particular needs.

Nix OS

Installation

  1. Visit the NixOS official website and navigate to the Download section. Under NixOS: the Linux distribution section, you’ll find ISO images for different desktop environments, such as GNOME and KDE. Choose the ISO that bests suits your preference.

    sudo dd if=Downloads/nixos-gnome-24.05.6668.e8c38b73aeb2-x86_64-linux.iso of=/dev/sdb status=progress && sync
    

    This is a common way to write an ISO image of a Linux distribution to a USB pendrive. dd is a low-level utility for converting and copying files. It can be used to create exact copies of data, making it very suitable for writing ISO images.

    if stands for “input file”. It specifies the path to the downloaded ISO you want to write to the USB drive. of stands for “output file.” It specifies the target device where the ISO will be written. Make sure to replace /dev/sdb with the correct device identifier for your USB drive (lsblk or fdisk -l). “status=progress” provides ongoing feedback about the progress of the operation. “sync” is used to flush the file system buffers, ensuring that all data is written to the USB drive before you remove it and avoiding data corruption.

  2. Booting into the Installer. Create a bootable USB drive using tools like dd, Etcher, Rufus or Ventoy. Reboot your computer and select the USB drive as the boot drive. You will be greeted with the NixOS boot menu. Choose the default option to start the installer.

  3. Installer Settings The graphical installer will guide you through basic settings:
    Language Selection: Choose your preferred languages.
    Region and Timezone: Set your geographical region and timezone to ensure accurate system time.
    Keyboard Layout: Select the keyboard layout that matches your hardware.
    User Creation: Create a user account with a username and password. If you forget it, then you can reset it from the Pendrive without reinstalling it.
    Desktop Environment: Choose a desktop environment to install, e.g., GNOME, KDE, or none for a headless setup.

  4. Disk Partitioning. ⚠ This step will erase all data on the selected disk.⚠ When prompted, I strongly recommend to enable non-free packages (if you need proprietary drivers or software anyway). Choose “Erase disk” for simplicity. The installer will automatically handle partitioning, formatting, and filesystem setup.

  5. Review and Install. The installer will show a summary of your selections. Review these settings carefully to ensure they are correct. If everything looks good, click the “Install” button to begin the installation process.

  6. First Boot. After installation is complete, reboot your system. Remove the USB drive and reboot your machine. You should be able to boot into your new NixOS installation.

Understanding the Configuration File

One of NixOS’s most distinguishing features is the ability to declaratively configure the entire system through a single configuration file, located at /etc/nixos/configuration.nix.This file specifies the system state, including installed packages, system services, user accounts, and system options.

Changing a single line in this file and running sudo nixos-rebuild switch will typically alter your system configuration declaratively.

Accessing the Configuration File

Open a terminal and edit the configuration file located at /etc/nixos/configuration.nix:

	sudo [nano | vim] /etc/nixos/configuration.nix

At the bottom of Nano’s window, you can find some shortcuts to use with the Nano editor. The “^” (caret) means that you must press CTRL (Windows) or control (macOS) to use the chosen command:

  sudo gnome-text-editor /etc/nixos/configuration.nix # You may encounter an error like: "Authorization required, but no authorization protocol specified."
  sudo -E gnome-text-editor /etc/nixos/configuration.nix

Use sudo -E to use your existing environment variables to allow the graphical editor to connect to the display..

Configuration Structure

The configuration file is written in the Nix Expression Language, which is a simple, functional language used to describe system configuration declaratively.

At the top of the file, you typically will see:

{ config, pkgs, ... }:
{
	# Configuration options go here
}

Line 1: Defines a a function that takes at least two arguments config and pkgs (packages). Line 3: The function returns a set of option definitions enclosed in curly brackets { … }. These definitions have the form optionName = optionValue.

Importing Modules

imports =
  [
    ./hardware-configuration.nix
    < home-manager/nixos > # Without spaces
    /home/nmaximo7/dotfiles/home-manager.nix # Import our Home Manager's configuration
  ];

Boot Loader Settings

When configuring a Linux system, one of the initial steps is setting up the boot loader. This is a piece of software that runs right after your machine’s firmware (BIOS or UEFI) and before your operating system kernel. It basically determines which operating system to boot and in what mode.

UEFI (Unified Extensible Firmware Interface) is the modern replacement for the older BIOS (Basic Input/Output System). UEFI supports more features, such as larger boot partitions, faster boot times, and a more flexible pre-operating system environment. BIOS is the traditional firmware interface, older and often more limited. It provides basic functionality and is less flexible, but still widely used.

To check whether your system is running in UEFI mode or BIOS mode, you can use the following command:

[ -d /sys/firmware/efi ] && echo "UEFI mode" || echo "BIOS mode"

This is important because the type of boot mode determine the configuration, tools, and set up of your operating system. For instance, systemd-boot (a free and open-source UEFI boot manager) works only under UEFI, whereas GRUB (a widely used and versatile boot loader) can be used with both BIOS and UEFI.

A boot manager is a software utility that manages the boot process of your computer, allowing you to select which operating system or kernel to boot into.

GRUB Configuration

Below is an example snippet showing how to enable GRUB in a NixOS configuration file.

  boot = {
  	loader = {
	    grub = {
	    	enable = true; # This tells NixOS to use GRUB as the boot loader.
	    	device = "/dev/nvme0n1"; # It indicates that GRUB should be installed on the entire disk rather than a single partition (like /dev/nvme0n1p1).
	    };
	    timeout = 1; # Sets the number of seconds before GRUB automatically boots the default entry.
      # A short timeout is handy and productive if you rarely need to select between different kernels.

  	  # If you previously had system-boot enable, you must disable it here to prevent conflicts between GRUB and systemd-boot
  	  systemd-boot.enable = false;
  	 };
    # The following kernel parameters disable the open-source Nouveau driver (for NVIDIA GPUs)
    # and enable NVIDIA's proprietary modesetting. This can improve stability with Wayland compositors like Hyprland
  	kernelParams = [ "nvidia-drm.modeset=1" "nouveau.modeset=0" ];
  };

Adding parameters at boot time can help configure drivers and can help control hardware detection, debugging settings, power management, and other system functionalities.

systemd-boot Configuration

systemd-boot is a simpler, lightweight boot loader that integrates closely with systemd. Be aware, it requires UEFI.

systemd is responsible for booting the system, initializing hardware, and starting services and daemons.

boot.loader = {
  # Enable systemd-boot (systemd-boot is a UEFI boot manager that is part of the systemd project) as the bootloader
  systemd-boot.enable = true;

  # On UEFI systems, the boot loader needs to modify EFI variables.
  # Set this to true if you are on UEFI; it grants permission to make changes (write)
  # to the EFI variables stored in NVRAM. NVRAM is a type of memory that retains its data even when the power is turned off, e.g.,
  # it stores settings and configurations for the BIOS or UEFI firmware, including boot order, hardware configuration, and system preferences).
  efi.canTouchEfiVariables = true;

  # The boot menu will show for 1 second before automatically starting the default entry (OS)
  timeout = 1;
};

Networking Configuration

Networking configuration (hostnames, DHCP or static IP addresses, DNS servers, etc.) defines how your system connects to other machines, the Internet, and internal networks.

When running a virtual machine inside VirtualBox, you can choose different networking modes. The “Bridged Adapter” mode connects the VM directly to the host’s physical network. This allows the VM to get an IP address on the same local network as the host, making the VM appear as a separate, meaning completely independent physical machine on that network.

To set up a bridged network in VirtualBox (static IP):

  1. Open VirtualBox, select your VM and go to Settings, Network.
  2. Choose “Bridged Adapter” from the dropdown menu for Adapter 1.
  3. Select your host machine’s physical network interface that you want to bridge to (enp0s3) in the “Name” field.
  4. Optionally, in the Advanced section, generate a new MAC address for the VM.
  5. Start your VM and configure a static IP address within the guest OS as follows:
  networking = {
    hostName = "nixos"; # Set your system's hostname
    useDHCP = false; # Turn off DHCP to assign a static IP, meaning that you'll manually want to configure the IP
    interfaces.enp0s3 = {  #  This is where you define your static IP.
    # Replace 'enp0s3' with your actual interface name (ip link)
      ipv4.addresses = [
        {

          address = "192.168.1.14";  # Choose an IP available on your LAN
          prefixLength = 24; # Equivalent to a typical home subnet 255.255.255.0
        }
      ];
    };
    defaultGateway = "192.168.1.1";  # The IP address of the router or gateway of your network.
    nameservers = [ "10.0.2.3" "8.8.8.8" ];  # DNS servers
    # DNS servers translate domain names to IP addresses.
  };

If you’re configuring networking on a desktop system, you might do something similar:

networking = {
  # Set the hostname for the system
  hostName = "nixos";

  # Disable DHCP; set to true if you want to use DHCP instead
  useDHCP = false;

  # Configure the network interface.
  # Replace 'enp5s0' with your actual interface name (ip link)
  interfaces.enp5s0 = {
    ipv4.addresses = [
      {
        # Static IP address configuration
        address = "192.168.1.36";  # Set your desired static IP address
        prefixLength = 24; # Subnet mask
      }
    ];
  };

  # Set the default router or gateway for the network
  defaultGateway = "192.168.1.1";

  # Configure DNS servers for name resolution
  nameservers = [
    "80.58.61.254"  # First DNS server
    "80.58.61.250"  # Second DNS server
  ];  # Add any additional DNS servers as needed
};

# NetworkManager is a program for configuring network devices on Linux.
networking.networkmanager.enable = true;

In order to allow access to the NetworkManager daemon and be able to configure and add new networks, the user must be added to the networkmanager group: users.users.YOUR-USERNAME.extraGroups = [ “networkmanager” ];

By default, NetworkManager comes with nmcli, nmtui, nm-applet, and nm-connection-editor. nm-applet and nm-connection-editor are graphical tools for configuring and managing networks.

Localization Settings

It involves configuring things like the time zone, language, numeric formats, and input methods so that they match your preferences or region, making sure that everything is tailored to your preferences.

time.timeZone = "Europe/Madrid"; # Sets the system's time zone to Europe/Madrid.
# It determines the local time displayed by your computer.

# Internationalization.
i18n.defaultLocale = "en_GB.UTF-8"; # It sets the default system locale (language) to English.
# The en_GB.UTF-8 locale corresponds to British English using UTF-8 encoding, so the system use British English for messages, menus, and other system interface elements by default.

# Overrides specific locale categories, setting them to Spanish
# They include formats for addresses, units of measurements, numbers, time, date, etc.
i18n.extraLocaleSettings = {
    LC_ADDRESS = "es_ES.UTF-8";
    LC_IDENTIFICATION = "es_ES.UTF-8";
    LC_MEASUREMENT = "es_ES.UTF-8";
    LC_MONETARY = "es_ES.UTF-8";
    LC_NAME = "es_ES.UTF-8";
    LC_NUMERIC = "es_ES.UTF-8";
    LC_PAPER = "es_ES.UTF-8";
    LC_TELEPHONE = "es_ES.UTF-8";
    LC_TIME = "es_ES.UTF-8";
};

# Configures the console (outside the graphical environment) font and keymap.
console = {
  font = "Lat2-Terminus16"; # It sets the font used in the virtual console (Ctrl + Alt + F1/F2...)
  keyMap = "es"; # It sets the console keyboard layout to Spanish.
};

# X11 Keyboard Layout
services.xserver.xkb = {
  layout = "es"; # Sets the keyboard layout for the X11 System (graphical environment) to Spanish.
  variant = ""; # We are not choosing a specific variant of the Spanish layout.
};

Font Configuration

By carefully selecting and installing the right fonts, you can significantly enhance your computing experience and make your work more efficient and visually pleasing.

fonts.packages installs a variety of fonts to the system, including programming fonts like Fira Code and Iosevka, as well as emoji and CJK fonts (Chinese, Japanese, and Korean languages).

fonts.packages = with pkgs; [
	bqn386
	dina-font
	fira-code
	fira-code-symbols
	font-awesome # Provides a vast library of icons and symbols. It is necessary for waybar.
	iosevka
	liberation_ttf
	noto-fonts # The Noto family by Google aims to cover all languages to prevent the dreaded "tofu" (missing character boxes)
	noto-fonts-cjk-sans
	noto-fonts-emoji # noto-fonts-emoji ensures emojis display correctly
	proggyfonts
	source-code-pro
	uiua386
	(nerdfonts.override { fonts = [ "FiraCode" "SourceCodePro" ]; })
];

nerdfonts are patched fonts that include a large number of icons and glyphs. Overriding this with fonts = [ “FiraCode” “SourceCodePro” ]; tells NixOS to build a Nerd Font variant of your preferred typefaces (the overall design of the characters, e.g., Helvetica, Times New Roman, Arial.), such as FiraCode and SourceCodePro, giving you the original fonts plus additional icons which can be incredibly useful for various applications like coding, terminal, code editors, and more.

Resources

Bitcoin donation

JustToThePoint Copyright © 2011 - 2025 Anawim. ALL RIGHTS RESERVED. Bilingual e-books, articles, and videos to help your child and your entire family succeed, develop a healthy lifestyle, and have a lot of fun. Social Issues, Join us.

This website uses cookies to improve your navigation experience.
By continuing, you are consenting to our use of cookies, in accordance with our Cookies Policy and Website Terms and Conditions of use.