nixos configuration
so. doll is finally a nixer. oh boy. you wanna know what would make this even worse? if doll literated this bitch up!!!!!!!!!!!! ayyyyyyyyyyyyyyyyyyyyyyyyyyyyy
Table of Contents
Goals
Documentation
the whole entire reason doll is doing a literate configuration in the first place is to increase the ratio of documentation vs code.
a big problem with writing code is that eventually you get to a point where you look back at your code and go "wait. what the fuck. why did i do that. why did i do any of this." now imagine having that problem with the code that runs your entire computer. that. would be bad.
thus, in making our nixos config literate, we literally write down paragraphs about all of our decisions so that in the nebulous near future in which we come back to our config not knowing what the hell we were doing, we can look back on those paragraphs and remember what the hell we were doing. which, of course, was witchcraft. it was always witchcraft.
Minimalism
the benefit of having to lay out every single program that you are installing is that it is very easy to know all of the programs you have installed… and think about whether they really need to be there.
doll notices that over time, as it uses its computer, it gets into a habit of installing a bunch of programs in order to solve some sort of issue (whether technical, practical,
or fantastical) and then never going back through to remove said programs that are left over in the aftermath. this innevitably creates bloat, and since it usually runs machines
that are limited in storage (both this machine nyxtrix and its previous machine crimson were only 256 gb,,,,), that bloat can add up fast.
the declarative process of nixos means that in order to change the programs one has installed, they are required to see all of the applications they have installed. every time one changes their system, the consequences of their actions are laid out in front of them, and one always has the opportunity to look upon the march of progress and make judgement calls on what new daemons are no longer of use within their COMP. and doll thinks that's pretty neat.
Hardware
this is the automatically generated hardware configuration from nixos-generate-config.
It doesn't contain much. Most of the real goodies are in a dependency doll will talk
about later.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}
Main Configuration
this is the main configuration file for nixos. later on, doll will try to split this up into multiple files, but for now, just one is fine.
# ========== configuration.nix - main configuration - © 2026 millicent ==========
Design
currently, our nixos config is firmly in channel land. as a beginner to nixos, it is
recommended that we start with channels and then move our way to flakes
once we are comfortable with channels. thus, our config is currently in
/etc/nixos/configuration.nix and not ~/nixos/flake.nix for example.
Beginning Boilerplate & Imports
{ config, lib, pkgs, ... }:
{
imports =
[ # Include tweaks from NixOS-Hardware.
<nixos-hardware/lenovo/thinkpad/t480s>
# Include the results of the hardware scan.
./hardware-configuration.nix
];
Boot
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# Use ZFS filesystem
boot.supportedFilesystems = [ "zfs" ];
boot.initrd.systemd.enable = true;
boot.zfs.forceImportRoot = false;
Filesystem
# Configure filesystem paths
## Root
fileSystems."/" = {
device = "door/root";
fsType = "zfs";
};
## Nix Configuration
fileSystems."/nix" = {
device = "door/nix";
fsType = "zfs";
};
## Var
fileSystems."/var" = {
device = "door/var";
fsType = "zfs";
};
## Home
fileSystems."/home" = {
device = "door/home";
fsType = "zfs";
};
## Boot Partition
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/C605-9D58"; # UUID for /dev/sda1
fsType = "vfat";
options = [ "fmask=0077" "dmask=0077" ];
};
## ZFS shenanigans
## - TODO huh???
services.zfs = {
autoScrub.enable = true;
trim.enable = true;
};
Swap
# Swap
# - ZFS does not like swap partitions very much. We have made one /just/ in case, but we
# will mostly use ZRAM for swap instead.
## Swap Partition
swapDevices = [
{
device = "dev/disk/by-partuuid/b974352a-22c7-4601-85da-bf6df7feb7d7"; # UUID for /dev/sda3
randomEncryption.enable = true; # no swap skimming today, buckeroo
}
];
## ZRAM
zramSwap = {
enable = true;
algorithm = "zstd";
};
Networking
# Networking
networking = {
hostId = "3b86203e"; # head -c 8 /etc/machine-id
hostName = "nyxtrix";
nftables.enable = true;
firewall.enable = false;
networkmanager.enable = true;
};
Core System
Settings
# System Settings
system.stateVersion = "26.05"; # latest stable as of 2026-08-20
time.timeZone = "America/Chicago"; # eh close enough
console.keyMap = "us";
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";
};
Services
# System Services
services = {
libinput.enable = true; # libinput is based
fwupd.enable = true; # LVFS firmware updates
printing.enable = true; # CUPS!
flatpak.enable = true; # unfortunately, flatpak is based
tailscale.enable = true; # unfortunately, tailscale is based
power-profiles-daemon.enable = true; # performance & power saving profiles
upower.enable = true; # being able to see battery status
## OpenSSH
## - basically, allow SSH'ing into this, but REQUIRE use of a key
openssh = {
enable = true;
settings = {
PasswordAuthentication = false;
KbdInteractiveAuthentication = false;
PermitRootLogin = "no";
};
};
};
Graphical Environment
# Graphical Environment
## - awwwwww you know what it isssssss
## wayland niri wayland niri wayland niri wayland niri
services.xserver = {
enable = true; # BUT IT SAYS XSE- ssshhhhhhhhh
## keyboard language
xkb = {
layout = "us";
variant = "";
};
## silly: just. yeet x11. only wayland.
excludePackages = [ pkgs.xterm ];
};
## niri
programs.niri.enable = true;
## display manager: greetd (for now)
services.greetd = {
enable = true;
settings = {
default_session = {
command = "${config.programs.niri.package}/bin/niri-session";
user = "millicent";
};
};
};
## By default, NixOS strips out part of the path given to the niri.service unit.
## That's silly. We're gonna let niri have the whole path because it's a good girl
systemd.user.services.niri.enableDefaultPath = false;
## for defaults sake, we are installing polkit, gnome-keyring, and alacritty.
## we will edit this later, don't worry
security.polkit.enable = true;
services.gnome.gnome-keyring.enable = true;
## TODO add systemPackages [ ... alacritty ... ]
Sound
insert joke here.
# Sound
services.pulseaudio.enable = false; # FUC U
security.rtkit.enable = true;
services.pipewire = { # YEAAAAA
enable = true;
alsa.enable = true; # for maximum compatability
alsa.support32Bit = true; # "
pulse.enable = true; # pipewire-pulse it think
jack.enable = true; # pipewire-jack it think 2
};
Packages
System Packages
# Packages
## enabling unstable
nixpkgs.config = {
allowUnfree = true;
packageOverrides = pkgs: {
unstable = import <nixos-unstable> {
config = config.nixpkgs.config;
};
};
};
## system packages
environment.systemPackages = with pkgs; [
## the duhs
zip
unzip
wget
lm_sensors # for additional hw support
whois
dig # forget what this is for, think DNS?
gnupg # unfortunately, GPG is still used sometimes
wireguard-tools
reaction # dependency for wireguard-tools
git
doas # sudo but better
## programming languages
python314
python314Packages.pip
gcc
gdb
valgrind
go
cargo
rustc
## shell & DE
unstable.noctalia # chill shell
kdePackages.dolphin # file manager
pwvucontrol # for audio management
## extras
kitty # cute terminal with pictures
chromium # for handshake specifically
librewolf # LET THE BROWSER. BE TRANS!!!!!
neovim # vim. but slightly cooler
vesktop # discord. but slightly cooler
vscode # boooooooo
signal-desktop #mom,,,
mixxx # untzuntzuntzuntzuntz
];
Fonts
## fonts!
fonts.packages = with pkgs; [
atkinson-hyperlegible-next # sans
ioskeley-mono.normal-NF # mono
drafting-mono # fancy mono
];
Emacs
## emacs
## - the default emacs given by stable is a fairly outdated version.
## - thus, we are using a community overlay to grab the latest
## - tagged version and make sure it is the pure GTK version for wayland.
services.emacs = {
enable = true;
defaultEditor = true;
package = pkgs.emacs-unstable-pgtk;
};
nixpkgs.overlays = [
(import (builtins.fetchTarball {
url = "https://github.com/nix-community/emacs-overlay/archive/master.tar.gz";
}))
];
Docker
## docker (rootless)
virtualisation.docker = {
# Consider disabling the system wide Docker daemon
enable = false;
rootless = {
enable = true;
setSocketVariable = true;
# Optionally customize rootless Docker daemon settings
daemon.settings = {
dns = [ "1.1.1.1" "8.8.8.8" ];
registry-mirrors = [ "https://mirror.gcr.io" ];
};
};
};
Flakes?
# NixOS Flakes
# - for now, we are keeping this /off/, just so we can get used to
# - configuring our system the nix way. once we are more settled in,
# - then we will enable flakes.
# nix.settings.experimental-features = [ "nix-command" "flakes" ];
User Account
# User Account
users.users.millicent = {
isNormalUser = true;
description = "Millicent Kasanova";
extraGroups = [ "networkmanager" "wheel" "docker" ];
};
}