NixOS & My Configs
Well Hello There!
Howdy! Been a while, hasn’t it? While you’ve been off, I don’t know, working, living life, struggling to keep up with the verbiage anyone “younger than you” uses, binging Baldur’s Gate 3… where was I? Oh, yes. While you’ve been off having fun I’ve been mixing things up on my desktop and laptop daily drivers and I’m now running NixOS! Until now I’ve been running Arch variants with little issue and much success. So if it ain’t broke, why fix it?
NixOS
First, a brief overview of NixOS. NixOS is a Linux distribution built on top of the Nix package manager. Its declarative configuration allows reliable system upgrades via several official channels of significant size and stability. NixOS has tools dedicated to DevOps and deployment tasks.[8][9]
In short, some of the benefits of NixOS over other Linux distributions are:
1. Abstraction: The different software packages making up a system can all be configured using the single Nix language syntax.
2. Reproducible builds: A replica of a current system can be created on any machine with one config file.
3. Atomic upgrades: System upgrades involve less risk of breakage, and if something does go wrong, it is simple to roll back to the previous state.
4. Immutability: The software making up a given system configuration cannot be changed once it has been built, preventing accidental or malicious modifications.
5. Nix package manager: Packages can be installed without affecting the rest of the system, and can be tested without installing.
A Little Background
Now, the ‘reproducible build’ portion is what I was striving for with my Arch Configs, however, it was becoming a bit to maintain and due to spending less of my time messing with CSS, Yuck, and Window Managers/Compositing, I wanted to shift to something usable, a bit familiar, and something I could repeatably deploy (if I broke something, or just felt like reformatting for one reason or another). This is where I landed on NixOS.
What I’ve Done
I’ve installed NixOS on both my laptop and desktop and am currently differentiating the builds based on the hardware-configuration.nix file. I had a spat where I was trying to use Home Manager, however, was running into various issues with the config files and getting my programs up and running. I have most of my go-to applications installed, and, with a quick *“nix-env -qPa | grep |
I’ve also backed up my configurations, and will keep “live” copies on GitHub - nixos-configs. It’s not necessary due to the ability to boot from derivations (essentially snapshots) at boot time, however, having a backup copy I can see from the web can be helpful.
What I’d Like To Do
I’d like to test more with Home Manager as a way to differentiate user based configurations, so NixOS could be deployed on (for example) my wife or son’s PC with a baseline config, and user specific configs separated. I may also look into Flakes for this, as I need to look into and learn Flakes anyway. I wouldn’t actually install Linux on my son or wife’s PCs, both of them have turned their nose up at the… learning opportunities. A shame, truly.
As part of my exploration through NixOS there will likely be upcoming posts that go into more depth on the trials and tribulations I face. Look forward to it.
My Configs
This brings us to my configs. If you try using the configurations you’ll need to make changes to the user, hard drive mounting, packages to install, etc… I don’t recommend using the configs 1:1. You can, however, take snippets that are relevant for you, such as the steam specific configurations, getting Lutris installed and working, enabling AMDGPU kernel module, etc. My configs can be found on GitHub - nixos-configs.
Configuration.nix
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).
{ config, pkgs, ... }:
# Main
{
# Imports
imports = [
./hardware-configuration.nix
];
## Boot Configurations
# Bootloader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
## 32Bit Support
# Add support for 32Bit - opengl, pulseaudio
hardware.opengl.driSupport = true;
hardware.opengl.driSupport32Bit = true;
hardware.pulseaudio.support32Bit = true;
# Vulkan Support - 32Bit, OpenCL
hardware.opengl.extraPackages = with pkgs; [
amdvlk
rocm-opencl-icd
rocm-opencl-runtime
];
# For 32 bit applications
# Only available on unstable
hardware.opengl.extraPackages32 = with pkgs; [
driversi686Linux.amdvlk
];
## Locale/Region
# Set your time zone.
time.timeZone = "America/New_York";
# Select internationalisation properties.
i18n.defaultLocale = "en_US.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "en_US.UTF-8";
LC_IDENTIFICATION = "en_US.UTF-8";
LC_MEASUREMENT = "en_US.UTF-8";
LC_MONETARY = "en_US.UTF-8";
LC_NAME = "en_US.UTF-8";
LC_NUMERIC = "en_US.UTF-8";
LC_PAPER = "en_US.UTF-8";
LC_TELEPHONE = "en_US.UTF-8";
LC_TIME = "en_US.UTF-8";
};
## Networking
# Hostname
networking.hostName = "Gwyn"; # Define your hostname.
# Enable networking
networking.networkmanager.enable = true;
# Enables wireless support via wpa_supplicant.
# networking.wireless.enable = true;
# Configure network proxy if necessary
# networking.proxy.default = "http://user:password@proxy:port/";
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
## Firewall
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
## Desktop Environment/Window Management/Graphics
# Enable the X11 windowing system.
services.xserver.enable = true;
services.xserver.videoDrivers = [ "amdgpu" ];
# Enable the KDE Plasma Desktop Environment.
services.xserver.displayManager.sddm.enable = true;
services.xserver.desktopManager.plasma5.enable = true;
# Configure keymap in X11
services.xserver = {
layout = "us";
xkbVariant = "";
};
# HIP libraries
systemd.tmpfiles.rules = [
"L+ /opt/rocm/hip - - - - ${pkgs.hip}"
];
## Packages
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
nixpkgs.config.permittedInsecurePackages = [
"openssl-1.1.1u"
"python-2.7.18.6"
"electron-12.2.3"
];
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs; [
vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed>
lutris
(lutris.override {
extraPkgs = pkgs: [
wineWowPackages.stable
winetricks
];
})
wget
firefox
clinfo
neofetch
file
neovim
git
fontconfig
freetype
flatpak
openssl
fnm
ripgrep
tldr
unzip
btop
htop
bat
gparted
ranger
viewnior
cava
steam
steam-run
onlyoffice-bin
etcher
flameshot
vscodium
mangohud
protonup-ng
wine
python3Full
python.pkgs.pip
qemu
virt-manager
jetbrains.pycharm-community
discord
telegram-desktop
teams-for-linux
ncspot
wezterm
spotify
krita
kdeconnect
kate
thunderbird
conda
];
# Enable ZSH
programs.zsh.enable = true;
## Audio
# Enable sound with pipewire.
sound.enable = true;
hardware.pulseaudio.enable = false;
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;
# use the example session manager (no others are packaged yet so this is enabled by default,
# no need to redefine it in your config for now)
#media-session.enable = true;
};
## Services
# Enable CUPS to print documents.
services.printing.enable = true;
# Enable touchpad support (enabled default in most desktopManager).
# services.xserver.libinput.enable = true;
# Enable automatic login for the user.
services.xserver.displayManager.autoLogin.enable = true;
services.xserver.displayManager.autoLogin.user = "kennethp";
# Virtualization Services (libvirtd // virt-viewer)
virtualisation.libvirtd.enable = true;
services.flatpak.enable = true;
# Enable the OpenSSH daemon.
services.openssh.enable = true;
## User Configurations
# Define a user account. Don't forget to set a password with ‘passwd’.
users.users.kennethp = {
isNormalUser = true;
description = "Kenneth Perry";
extraGroups = [ "networkmanager" "wheel" "kvm" "input" "disk" "libvirtd" ];
};
# Set Default Shell to ZSH
users.defaultUserShell = pkgs.zsh;
# Add zsh to /etc/shells
environment.shells = with pkgs; [ zsh ];
# Fonts
fonts = {
fonts = with pkgs; [
noto-fonts
nerdfonts
noto-fonts-cjk
noto-fonts-emoji
font-awesome
source-han-sans
source-han-sans-japanese
source-han-serif-japanese
];
fontconfig = {
enable = true;
defaultFonts = {
monospace = [ "Meslo LG M Regular Nerd Font Complete Mono" ];
serif = [ "Noto Serif" "Source Han Serif" ];
sansSerif = [ "Noto Sans" "Source Han Sans" ];
};
};
};
# Some programs need SUID wrappers, can be configured further or are
# started in user sessions.
programs.mtr.enable = true;
programs.gnupg.agent = {
enable = true;
enableSSHSupport = true;
};
## Gaming
# Steam Firewall Configurations
programs.steam = {
enable = true;
remotePlay.openFirewall = true; # open ports in firewall for Remote Play
dedicatedServer.openFirewall = true; # open ports in firewall for Dedicated Server
};
## Default Settings for Stateful Data pulled from...
system.stateVersion = "23.05";
## Backups & Upgrades
# Backup system config
system.copySystemConfiguration = true;
# System Upgrades
system.autoUpgrade.enable = true;
system.autoUpgrade.allowReboot = true;
## Garbage Collection
# Automatic Garbage Collection
nix.gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 3d";
};
# Adding requirements for steam.
# Add Steam
nixpkgs.config.allowUnfreePredicate = true;
nix.settings = {
substituters = ["https://nix-gaming.cachix.org"];
trusted-public-keys = ["nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4="];
};
}
Hardware-configuration.nix
Do not modify this file! It was generated by ‘nixos-generate-config’
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ "amdgpu" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "nvme" ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
boot.kernelParams = [
"video=DP-1:1920x1080@144"
"video=DP-2:1920x1080@144"
"video=DP-3:1920x1080@60"
];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/e623756c-d31a-4cfe-8b51-842896f5b9a0";
fsType = "ext4";
};
fileSystems."/mnt/Games" =
{ device = "/dev/disk/by-uuid/304e90e3-da1c-4bc6-8ec3-3fd1c70938ce";
fsType = "btrfs";
# options = [ ];
};
fileSystems."/mnt/Elements" =
{ device = "/dev/disk/by-uuid/9ff98d32-f6ef-4226-ad80-04f14e3b842f";
fsType = "btrfs";
# options = [ ];
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/0225-D1BB";
fsType = "vfat";
};
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp5s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
# Reduce Swappiness
boot.kernel.sysctl = { "vm.swappiness" = 0;};
}
And That’s It
And that’s mostly it! More tinkering, more learning… primarily by throwing myself into the fire with a “sink or swim” mentality, but hey… whatever works. I’d like to thank you for reading this update, feel free to join the NOC Thoughts Discord, and check back for updates!