If you’re going through hell, keep on going, Winston Churchill
NixOS is a unique, innovative, and powerful Linux distribution that leverages the Nix package manager. Unlike traditional Linux distributions that update packages and system configurations in-place, NixOS uses a purely functional and declarative approach to define the system state, reducing the risk of system breakage.
NixOS is a Linux distribution that uses the Nix package manager to handle 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.
sudo nix-env ‐‐rollback is a command used to revert your system to the previous configuration. It’s a powerful tool for undoing unintended changes or recovering from failed package installations. Before rolling back, consider if there’s a more targeted solution, like uninstalling specific packages or reverting configuration files.
NixOS leverages a declarative approach to system configuration, making it incredibly flexible and powerful. By defining your desired system state in the configuration.nix file, you can easily manage desktop environments and services, install and manage packages, and configure system-wide settings like time zones, locales, and keyboard layouts.
Services and desktop environments are enabled and configured via the configuration.nix file. Instead of manually editing multiple system files, you declare your desired desktop environment (GNOME, KDE Plasma, XFCE, i3, etc.) and services, and then NixOS will ensure they are set up correctly after a rebuild.
A service is a computer program that runs in the background, performing specific tasks without direct user interaction. They are essential for the smooth functioning of the system and provide various functionalities, such as: network services (SSH, FTP, HTTP, etc.) for remote access and communication; time synchronization and system management (NTP, systemd-timesyncd); PipeWire and PulseAudio for audio and multimedia; synchronization and backup services (rsync, Nextcloud, etc.); inter-process communication (D-Bus); automated task scheduling (Cron).
services = {
xserver = {
# XServer Settings: Configures the display server and desktop environments.
enable = true; # Enables the X11 Window system
displayManager.gdm.enable = true; # Uses GDM as the graphical login manager (common in GNOME desktop environments).
# GDM provides the login screen and handles user sessions for the GNOME desktop environment.
desktopManager.gnome.enable = true; # Enables the GNOME desktop environment
# Enable the i3 window manager with gaps
windowManager.i3 = {
enable = true;
package = pkgs.i3-gaps;
};
# Keep your screen active
displayManager.sessionCommands = ''
# Disable DPMS (Display Power Management Signaling)
${pkgs.xorg.xset}/bin/xset -dpms
# Disable screen saver
${pkgs.xorg.xset}/bin/xset s off
'';
};
# A cleaner alternative (only i3) with sddm
xserver = {
enable = true; # Enables the X server, which is necessary for graphical environments.
windowManager.i3 = {
enable = true; # Enables the i3 window manager, a popular tiling window manager known for its stability and efficiency.
package = pkgs.i3-gaps; # Specifies the package to be used for i3, i3-gaps adds gaps between windows.
};
};
flatpak.enable = true; # Enables Flatpak, a system for building, distributing, and running sandboxed desktop applications.
displayManager.sddm.enable = true; # Enables the SDDM for managing user sessions and logins.
# It is a modern display manager aiming to be fast, simple, and beautiful.
displayManager.autoLogin = {
enable = true; # Enables automatic login for the specified user.
user = "YOUR-USERNAME"; # Specifies the username for automatic login.
};
Enabling both GNOME and i3 allows you to choose between a full desktop environment and a lightweight window manager.
Tiling window managers arrange windows in a way that maximizes screen real estate (windows are automatically arranged in a tiled pattern, covering the entire screen without overlapping) and minimizes the need for manual window resizing and positioning. This ensures efficient use of screen space and great productivity.
In case something goes seriously wrong with your graphical session, you can press Ctrl+Alt+F1 (or F2 through F6) to switch to a different virtual console. These consoles provide a text-based login shell, allowing you to troubleshoot the system and fix issues without relying on the graphical environment.
NixOS user management is also declarative. Instead of manually adding users (useradd) or editing /etc/passwd, you define user accounts in configuration.nix.
users.users.nmaximo7 = { # Defines a user account.
#Remember to set a password for the user using: sudo passwd nmaximo7
description = "nmaximo7"; # Description for the user
isNormalUser = true; # Indicates this is a regular (non-system) user
shell = "${pkgs.zsh}/bin/zsh"; # Sets Zsh as the default shell
openssh.authorizedKeys.keys = [
"< INSERT PUBLIC KEY >" # A public SSH key for passwordless login.
# Typically, you copy and paste the content: cat .ssh/id_ed25519.pub.
];
extraGroups = [ "networkmanager" "wheel" "docker" "audio" "input" ];
# Adds the user to several groups:
# "wheel" grants sudo access (allowing administrative tasks)
# "networkmanager" grants permissions to control network interfaces
# "docker" allows the user to run Docker containers without sudo
# "audio" and "input" are useful for granting permissions to audio devices
# and input devices, needed by certain programs and status bars (e.g., polybar).
packages = with pkgs; [
# You can list user-specific packages here
# which will be installed specifically for this use
];
};
i3 is a dynamic tiling window manager that arranges windows in a non-overlapping manner to maximize screen real estate. It is highly customizable and controlled primarily through keyboard shortcuts.
In NixOS, once you have enabled i3, you can place your i3 configuration files (like ~/.config/i3/config) in a consistent, well-known place, usually under your $HOME directory. Many people use a ~/dotfiles directory to keep their configuration files organized and under version control.
mkdir -p ~/dotfiles/i3 # Create the i3 configuration directory in your dotfiles folder and copy your existing i3 config, i3status.conf (for i3status bar), and picom.conf (for the Picom compositor).
Differences with traditional Arch’s i3 configuration:
set $mod Mod4
font pango:Hack 14
exec --no-startup-id dex --autostart --environment i3
exec --no-startup-id nm-applet # Network Management Applet
# start a terminal and pavucontrol
bindsym $mod+Return exec alacritty
bindsym $mod+b exec pavucontrol
# kill focused window
bindsym $mod+Shift+q kill
bindsym $mod+Shift+d exec rofi -show power-menu -modi power-menu:rofi-power-menu
# keybinding ($mod+Shift+d) runs rofi with a power-menu mode.
# Rofi is a powerful and flexible application launcher and menu system. The power menu mode (provided by rofi-power-menu) allows you to reboot, shutdown, suspend, or hibernate your system easily.
# Option 1
bindsym --release Shift+Print exec scrot -s ~/Dropbox/%b%d::%H%M%S.png
bindsym --release Print exec scrot -s ~/Dropbox/%b%d::%H%M%S.png
# Option 2
# An alternative is to use flameshot, a powerful yet simple to use screenshot software
bindsym --release Print exec flameshot full # Take a screenshot of a whole window. You can add -p pathToADirectory.
bindsym --release Shift+Print exec flameshot gui # Take a screenshot of a screen region.bindsym $mod+d exec --no-startup-id dmenu_run
# enter fullscreen mode for the focused container
bindsym $mod+f fullscreen toggle
# change container layout (stacked, tabbed, toggle split)
bindsym $mod+s layout stacking
bindsym $mod+w layout tabbed
bindsym $mod+e layout toggle split
exec_always nitrogen --set-zoom-fill --random ~/Pictures/wallpapers
# Nitrogen is a versatile and lightweight wallpaper manager for Linux.
# Here it is configured to select a random wallpaper from the ~/Pictures/wallpapers directory each time i3 starts.
# The --set-zoom-fill option sets the wallpaper to fill the screen.
exec --no-startup-id picom --config ~/.config/picom/picom.conf #
# picom is a lightweight and versatile compositor for X11.
# It provides various visual effects such as window transparency, fading, and shadows.
# Running it at startup is recommended.
# The --no-startup-id option prevents i3 from keeping track of picom as a "startup application,"
# allowing i3 to continue loading without waiting for picom to exit.
exec --no-startup-id systemctl --user start espanso
# espanso is a text expander application.
# Using systemctl --user start espanso starts it as a user service.
# This means it will run in the background, allowing you to type shortcuts that expand into longer strings.
exec --no-startup-id barrier
# exec: This command is used to execute a program.
# --no-startup-id: This option tells the window manager not to manage the application's startup status. In other words, it won't track the application for session management.
# barrier is a software that allows you to share a keyboard and mouse between multiple computers.
exec --no-startup-id dropbox start -i
# It starts the Dropbox client with the -i option in the background and show the icon in the system tray.
set $ws1 "1: Terminal"
set $ws3 "3: Knowledge"
# These lines define variables for workspace names, making the configuration more readable and meaningful.
# Instead of just calling it "Workspace 1," we call it "1: Terminal," "2: Browser", "3: Knowledge", or "4: Code",
# indicating its purpose or use
exec --no-startup-id i3-msg 'workspace $ws1; exec alacritty'
# It tells i3 that upon startup, it should switch to the $ws1 workspace and run alacritty (a GPU-accelerated terminal).
exec --no-startup-id i3-msg 'workspace $ws3; exec obsidian'
# It start Obsidian, a note-taking and knowledge management application, in the Knowledge workspace.
exec --no-startup-id i3-msg 'workspace $ws4; exec code ~/justtothepoint/'
exec --no-startup-id i3-msg 'workspace $ws4; exec distrobox-enter archlinux -- google-chrome-stable'
exec --no-startup-id setxkbmap es
exec --no-startup-id xrandr --output DVI-I-1 --mode 1920x1200 --rate 59.88
NixOS Home Manager is a separate NixOS tool that manages user-specific configuration independently of the system configuration. It follows the same declarative approach as NixOS, allowing you to manage dotfiles, user services, and user-specific packages in a structured and reproducible way.
home.file = {
".config/espanso/match/base.yml".source = "/home/${username}/dotfiles/Espanso/base.yml";
".config/i3/config".source = "/home/${username}/dotfiles/i3/config";
".config/i3status/i3status.conf".source = "/home/${username}/dotfiles/i3/i3status.conf";
".config/picom/picom.conf".source = "/home/${username}/dotfiles/i3/picom.conf";
# ... other home.file entries
};
The provided Home Manager directives, using the home.file syntax, are a concise and effective way to manage configuration files within your home directory.
Directive Structure: home.file."< target_path >".source = “< source_path >”;
It basically tells the system to create a file at ~/.config/i3/config (or i3status.conf, picom.conf) by linking (or copying) it from your dotfiles directory. This ensures your configurations are kept in version control (in dotfiles) and seamlessly integrated into your home directory after running home-manager switch or sudo nixos-rebuild switch.
NixOS leverages the declarative approach of Nix, a functional language, to manage system packages. Instead of installing packages imperatively (like sudo pacman -S package on Arch, apt install package on Ubuntu, dnf install package, etc.), you declare which packages you want in environment.systemPackages. After running sudo nixos-rebuild switch, NixOS ensures those packages are installed and available system-wide.
services.flatpak.enable = true;
# Enable Flatpak Support, a system for building, distributing, and running sandboxed desktop applications.
# After enabling Flatpak, add the Flathub repository (an app store)
# so we can install applications from Flathub
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
programs.firefox.enable = true; # Install or enable firefox.
programs.zsh.enable = true; # Set zsh as the default shell.
# environment.systemPackages: Lists packages to be installed system-wide.
environment.systemPackages = with pkgs; [
vim # A powerful, popular, and highly configurable text editor, widely used among developers.
pavucontrol # A user-friendly GUI interface for managing audio settings on PulseAudio.
google-chrome # Google Chrome, Google's browser.
# Non-free browser, therefore allowUnfree = true; is required.
espanso # A cross-platform text expander written in Rust, useful for inserting predefined text snippets.
rofi # A fast application launcher and window switcher, often used as an alternative to dmenu.
picom # A compositor for X11, providing effects like transparency and shadow support for windows.
vscode # Visual Studio Code, a popular code editor with a rich ecosystem of extensions.
nitrogen # A wallpaper manager.
xss-lock # A simple tool to lock the screen using various lock screen applications.
scrot # A command-line tool for taking screenshots in various formats.
flameshot # A powerful screenshot tool with a graphical interface and annotation capabilities.
pulseaudio # A sound server that allows for advanced audio management.
i3status # A status bar for the i3 window manager, displaying system information like CPU load and memory usage.
i3lock # A simple screen locker for the i3 window manager, providing a quick way to lock the screen.
copyq # An advanced clipboard manager with a searchable interface and support for storing snippets.
pcmanfm # A lightweight file manager for X11, known for its simplicity and speed.
unzip # A command-line utility for extracting files from ZIP archives.
keepassxc # A cross-platform password manager that securely stores and manages passwords.
obsidian # A note-taking and knowledge management application that helps organize thoughts and ideas.
distrobox # A tool for creating and managing containerized environments for different Linux distributions.
hugo # Hugo is a fast and flexible static site generator written in Go, ideal for building websites.
wget # A command-line utility for downloading files from the web, supporting HTTP, HTTPS, and FTP protocols.
barrier # A software KVM (keyboard, video, mouse) solution that allows sharing a single keyboard and mouse across multiple machines.
alacritty # A modern, GPU-accelerated terminal emulator that is fast and highly configurable.
gnupg # A complete and free implementation of the OpenPGP standard, allowing for encryption and signing of data.
waybar # A customizable status bar for Wayland
swww # A simple Wayland wallpaper setter
networkmanagerapplet # NetworkManager applet for managing network connections. It includes nm-applet and nm-connection-editor.
xwayland # Provides compatibility for X11 applications on Wayland
mesa # Open-source graphics driver for rendering
gnome.adwaita-icon-theme # Adwaita icon theme for GNOME applications
gtk3 # Toolkit for creating graphical user interfaces
# power-profiles-daemon allows users to manage power profiles on their system
# enabling easy switching between performance and power-saving modes (polybar).
power-profiles-daemon
];
nixpkgs.config.allowUnfree = true;
# Enables installation of packages that are not open source
# It includes NVDIA drivers or applications like plex and Google Chrome.
services.plex.enable = true; # Enable Plex Media Server.
# It is a full-media server which allows you to store your media and play it back (stream your content) across many different devices.
Flatpak is a utility for deploying and managing software on Linux systems. Instead of installing applications system-wide and relying on the host’s environment, Flatpak provides isolated containers or sandboxes for each application, improving security and reducing the chance of breaking your system.
sudo vim /etc/nixos/configuration.nix
# 1. Enable Flatpak support on the system.
services.flatpak.enable = true;
# 2. Rebuild your NixOS (apply changes):
sudo nixos-rebuild switch
Reboot and go to your terminal:
# 3. Add the Flathub repository, which is a central hub or app store for Flatpak applications.
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
# The --if-not-exists option ensures it won’t be added twice if you run the command again.
# 4. Installing applications with Flatpak
flatpak install -y flathub com.google.Chrome md.obsidian.Obsidian com.ktechpit.whatsie org.flameshot.Flameshot org.keepassxc.KeePassXC com.github.tchx84.Flatseal com.spotify.Client com.discordapp.Discord org.telegram.desktop org.libreoffice.LibreOffice flathub org.gnome.Boxes org.gimp.GIMP org.filezillaproject.Filezilla flathub org.videolan.VLC org.gnome.gedit com.anydesk.Anydesk
We have installed in one go:
Useful Flatpak commands:
flatpak list # List all installed Flatpak applications
flatpak update # Update your installed Flatpak applications so you can benefit from the latest features, bug fixes, and security patches.
flatpak uninstall # Uninstalled a Flatpack application.
Sometimes, Flatpak applications can’t find system fonts or may not scale properly on high-resolution (HiDPI) displays.
vim /etc/nixos/configuration.nix
fonts.fontDir.enable = true; # Enable fontDir in your NixOS configuration.
# It creates a symbolic link from the host's font directory into the Flatpak sandbox environment,
# allowing Flatpak applications to use your system fonts.
flatpak --user override --filesystem=host # Allow the Flatpaks to access the WHOLE filesystem.
# This is similar to enable "All system files" in Flatseal, a graphical utility to review and modify permissions from your Flatpak applications.
# vim hyperland.nix
wayland.windowManager.hyprland = {
extraConfig = let
modifier = "SUPER";
in ''
monitor=,highres,auto,2
# The env variables adjust how applications scale their interface, making text and icons appropriately sized on high-DPI screens.
[...] # Scaling Factors for Wayland/GTK/QT Apps
env = GDK_SCALE,2 # for GTK apps to increase their scaling by a factor of two.
env = QT_AUTO_SCREEN_SCALE_FACTOR,1 # for QT-based apps to adjust their scaling.
env = QT_SCALE_FACTOR,1.5
exec-once = [workspace 4 silent] sleep 2 && "flatpak run com.google.Chrome --force-device-scale-factor=2.0 --custom-chrome-frame"
Additional Tips