My main flake and documentation for it.
I am trying to achieve a minimal NixOS installation for productivity. I use Qtile as my window manager, Neovim for text and code editing, Firefox for browsing and Lf for file management. I am mainly using these systems for internet browsing, text editing, coding, and LaTeX compilation.
Bugs
- Zathura bottom status bar is not transparent.
- Look Into: The mini greeter seems to act up on first boot. Maybe just ditch the mini greeter?
- Sometimes there is a significant slowdown after the machine is powered on for a long time and/or had been suspended for a long/multiple times.
- In some cases missing optional applications are not handled with care. This is manly an issue on minimal configurations.
Features
- Impermanence, for some parts at least.
- Locking, password prompt after suspend.
- Clean up python parts.
- Handle missing low priority packages.
- Finish installation documentation.
- Proper Tmux setup for Kmscon, with some status bar.
- Try the Wayland backed for Qtile.
There are also items marked with TODO inside comments. There are also NOTE, WARN and BUG labels used.
The images below are generated from the Qtile configuration with this script. There is a GitHub action set up that regenerates the images if needed.
The table below summarizes the support for programming languages. Syntax highlighting is handled by tree-sitter, and is enabled automatically. The language server and formatter is primarily designed and set up to be used with Neovim.
| Language | Installed | Formatter | LSP Server |
|---|---|---|---|
| Bash | S | ✓ | X |
| Haskell | ✓ | ✓ | ✓ |
| Java | ✓ | ✓ | ✓ |
| Julia | ✓ | X | X |
| LaTeX | ✓ | ✓ | |
| Lua | ✓ | ✓ | ✓ |
| Nix | S | ✓ | ✓ |
| Python | ✓ | ✓ | ✓ |
| Rust | ✓ | ✓ | ✓ |
A letter 'S' means that the feature is part of the root system. A tick means the feature is available but needs to be enabled with the configuration option of the language. Rows can only be enabled or disabled at once at the moment. A cross means that the feature is not present at the moment but may be implemented later. If there is no mark it means that the feature is not applicable.
Note
For further guidance, look at the official installation documentation, the NixOS wiki on Btrfs with encryption, and this helpful video.
For the installation it is recommended to use the ISO image generated from this
configuration with using the command below.
An ISO image will be generated into./result/iso/. The size should be about
~1.5 GiB.
nix build github:samunemeth/System#iso
Alternatively, you can also get the official minimal ISO image. In this case you might need to install some packages during the setup process.
I recommend using Ventoy for booting either of the ISO images. It makes it so you only have to copy the ISO onto a partition on a pen drive without the need to erase the drive and burn the image.
Warning
There are missing steps in this guide at the moment, marked with 'MISSING STEPS'.
- Boot the installation media, then switch to the root user with:
sudo -i - If you only have a wireless connection do one of the following:
- If you are using the custom ISO image use network manager's TUI:
nmtui - If you are using the official ISO image,
connect to a Wi-Fi network with the following commands:
sudo systemctl start wpa_supplicant wpa_cli add_network set_network 0 ssid "<SSID>" set_network 0 psk "<PASSWORD>" enable_network 0 quit
- If you are using the custom ISO image use network manager's TUI:
- Do a network sanity check with
ping:ping google.com - If you are using the official ISO, get some packages for the
installation by generating a dev shell from this flake.
A message should confirm that you are in a dev shell.
nix develop github:samunemeth/System#setup - Check disk and partition names, mount points, labels, and file system types
with the following command any time during the installation:
lsblk -o +LABEL,FSTYPE,FSVER - Create the needed partitions:
If asked, select
cfdisk /dev/<OS-DISK>GPTpartition table. I recommend a boot partition between 512 MiB and 1 GiB, a main partition of at least 16 GiB, and a swap partition the same size as the RAM. - Create a Luks encrypted Btrfs main partition:
cryptsetup luksFormat /dev/<NIXOS-PART> --label lb_luks_nixos -v --verify-passphrase cryptsetup open /dev/disk/by-label/lb_luks_nixos mkfs.btrfs /dev/mapper/enc --label lb_nixos - Create the needed sub volumes on the Btrfs partition:
mount -t btrfs /dev/mapper/enc /mnt btrfs subvolume create /mnt/root /mnt/home /mnt/nix umount /mnt - Mount the Btrfs sub volumes to the appropriate places, with compression:
mount -o subvol=root,compress=zstd /dev/mapper/enc /mnt mkdir -p /mnt/{home,nix} mount -o subvol=home,compress=zstd /dev/mapper/enc /mnt/home mount -o subvol=nix,compress=zstd,noatime /dev/mapper/enc /mnt/nix - If you just created a boot partition, format it now:
If you already have a boot partition, make sure it is labelled:
mkfs.fat -F 32 -n lb_boot /dev/<BOOT-PART>It should work after this as long as it has enough space. (Windows usually creates a small boot partition, and resizing it is not the easiest or safest thing to do, so I recommend installing Linux before Windows for dual booting setups.)fatlabel /dev/<BOOT-PART> lb_boot - Mount the boot partition:
mkdir -p /mnt/boot mount /dev/disk/by-label/lb_boot /mnt/boot - If you created a swap partition, format it with Luks encryption:
(If you use the same passphrase for the swap as the main partition, you will only have to enter it once during boot.)
cryptsetup luksFormat /dev/<SWAP-PART> --label lb_luks_swap cryptsetup luksOpen /dev/disk/by-label/lb_luks_swap swap mkswap /dev/mapper/swap -L lb_swap - MISSING STEPS What do we do with the swap now? Do we just leave it?
- Check mount points, and file systems now for good measure.
- Clone this repository into the installer's home directory, and change into it:
The following commands are all run from the working directory.
cd ~ git clone https://github.com/samunemeth/System.git cd System - If you are creating a new host, it is most easily done by coping an
existing host's directory and adapting it:
Otherwise, you can override an existing one if reinstalling.
cp -r ~/System/hosts/<SOURCE-HOST> ~/System/hosts/<HOST> - Generate the hardware configuration for the system directly to the new host's
directory:
mv ~/System/hosts/<HOST>/hardware-configuration.nix hardware-configuration.nix.old nixos-generate-config --root /mnt --dir ~/System/hosts/<HOST>/ - MISSING STEPS Generating a new hardware configuration might not be necessary if only file system labels are used.
- MISSING STEPS You need to add all the extra mount options, and file system support.
- You will have to add these changes in git:
git add . - After all the changes are made and committed, you can finally install the
system from the flake:
nixos-install --flake ~/System#<HOST> - Get some host ssh keys for your machine. This can be done in two different
ways:
- Generate some new host ssh keys for your new machine:
In this case, the new keys need to be added to the
ssh-keygen -A -f /mnt.sops.yamlfile, and the keys need to be updated. - MISSING STEPS
- Copy some existing keys from an external drive.
- MISSING STEPS
- Generate some new host ssh keys for your new machine:
- Make sure that the keys have the correct permissions:
chmod 0400 /etc/ssh/ssh_host_* - As the changes are still not pushed to GitHub, you will need to move the
current git repository to the new users home.
Give the user ownership of the repository, and change remote URL:
cp -r ~/System /mnt/home/<USER>/ nixos-enter cd /home/<USER> chown -R <USER>:users System su <USER> cd ~/System git remote set-url origin git@github.com:samunemeth/System.git - Everything should be ready to use, you can boot into the installation.
reboot - If the login screen does not work, you can switch to a virtual
terminal by pressing
ctrl+alt+f2, logging in and disabling the mini greeter with the following in your host'sconfiguration.nix:services.xserver.displayManager.lightdm.greeters.mini.enable = lib.mkForce false;
- If you have a fingerprint reader, enroll a fingerprint to your user:
sudo fprintd-enroll $USER - Everything should be set! Rebuild with
nrsand reboot to see if everything works as expected.
To use sops encrypted secrets while rebuilding your machine, or editing the
secrets file, you will need an age key that is authorized in the .sops.yaml
file. You can either:
- Use a standalone age key placed in the location
~/.config/sops/age/keys.txt. This is practical when using a master key for a file, during installation or temporarily. Sops and sops-nix both automatically detect them. - Use an age key derived from an SSH host key.
This way, your machine only
requires its host keys to persist. This is probably better for everyday use,
as the host keys are owned by root, and therefore harder to 'peek' at.
Sops-nix automatically derives the age keys from the host SSH keys, however
sops needs them supplied directly. For this purpose, a
nesshell function is provided for convenience.
Get an age public key of your machines host ssh key:
# With ssh-to-age installed:
sudo ssh-to-age -i /etc/ssh/ssh_host_ed25519_key.pub
# With ssh-to-age not installed yet:
nix-shell -p ssh-to-age --run 'sudo ssh-to-age -i /etc/ssh/ssh_host_ed25519_key.pub'This is useful when adding the key to .sops.yaml for example.
To get a private key, add the -private-key flag to the previous ssh-to-age
commands. Sops checks the SOPS_AGE_KEY environment variable for additional
or derived age keys to use for editing.
The following snippet adds a host ssh key derived age key to sops:
export SOPS_AGE_KEY=$(sudo ssh-to-age -private-key -i /etc/ssh/ssh_host_ed25519_key)This is the same snippet used in the nes shell function.
Note that you may need to prefix the paths in the snippets above with
/mnt if you are running them during the installation.
To update the secrets.yaml file with new keys or settings, use the
updatekeys option with the sops or nes commands.
SSH host keys can also be transferred, if the operating system needs to be
reinstalled. This way, there is no need to modify .sops.yaml.
Some Wi-Fi networks are declared in the Nix configuration and secrets.yaml file.
To add a network, create and identifier for it, in this example, let that be `WORK.
If WORK is a regular network:
Then add it to the normal_networks list in the networks.yaml file, then append
the following to the wireless-env key in the secrets.yaml file:
WORK_SSID=<SSID>
WORK_MGMT=<MGMT-METHOD>
WORK_PASS=<PASSWORD>
Replace <SSID>, <MGMT-METHOD> and <PASSWORD> accordingly.
Where <MGMT-METHOD> is usually either wpa-psk or sae. You can find out the
exact value by saving the network imperatively and looking at the generated configuration.
If WORK is an enterprise network:
Then add it to the normal_networks list in the networks.yaml file, then append
the following to the wireless-env key in the secrets.yaml file:
WORK_SSID=<SSID>
WORK_IDEN=<USERNAME>
WORK_PASS=<PASSWORD>
Replace <SSID>, <USERNAME> and <PASSWORD> accordingly.
Setting up a WPA enterprise network imperatively does not work with nmtui
or networkmanager_dmenu for some reason.
Here are some command for setting up such a network:
nmcli connection add type wifi con-name "<SSID>" ssid "<SSID>"
nmcli connection modify "<SSID>" wifi-sec.key-mgmt wpa-eap 802-1x.eap peap 802-1x.phase2-auth mschapv2 802-1x.identity "<IDENTITY>" 802-1x.password "<PASSWORD>"
nmcli connection up "<SSID>"Replace <SSID>, <IDENTITY> and <PASSWORD> accordingly.
To list all the connections saved, and their configuration file location, use the following command:
sudo nmcli -f NAME,DEVICE,FILENAME connection showTo generate Nix snippets from your saved networks, check out this tool.
Say that you accidentally deleted your boot partition, or the boot entries for NixOS in your boot partition.
You could also perform other fixes similarly, for example a missing root password. Of course, the disk has to be decrypted for it.
- Boot a live medium that you would use for installing a new system.
- Make sure you are running as root:
sudo -i
- Do the steps from the setup guide for mounting all the partitions in the correct places.
- Enter the mounted system:
nixos-enter
- Run the command for installing a bootloader for a new system:
The path to the flake is relative to the root of the machine entered, so the
NIXOS_INSTALL_BOOTLOADER=1 /nix/var/nix/profiles/system/bin/switch-to-configuration boot --flake /home/<USER>/System#<HOST>
/mntprefix needs to be omitted. Replace the path with the path to your flake. - Exit and reboot:
exit reboot
Based on the NixOS wiki's bootloader page.
There are a plethora of versions for Nvidia drivers depending on the GPU type, and they all take up a few GiB of space. When using a laptop that has a dual GPU setup, there are different option for sharing the load, but in the end, using only the integrated graphics might be beneficial for power usage while doing everyday tasks. Power usage improved from 33W to 20W during video playback when disabling the dedicated GPU, without a measurable loss in speed or quality.
If the offloading option was stricter, it would be probably better to use that. (Now the dGPU wakes up sometimes for no apparent reason). In this state, it just increases power usage too much to be worth keeping it on all the time. Using a specialization may be a good idea if the dGPU is sometimes required.
I have tried investigating what is causing the dGPU wakeup, but have found to definite answer. Kmscon definitely runs on the dGPU if available, but without Kmscon wakeup still happen. Investigating this in detail would be a nice side quest for the future.
Removing the Nouveau kernel module seems to increase power usage by about 10W. I assume that without any drivers the dGPU cannot be put into sleep, and therefore consumes more power.
Look at modules/nvidia.template.nix for information on the settings. The template is based on the following sources:
Sometimes stuff gets stuck in /tmp, and prevents packages from being garbage
collected. Just clear the /tmp directory and reboot:
sudo rm -rf /tmp/*
sudo rebootThis should be solved later with impermanence.
Using Lanzaboote, secure boot is possible with this configuration. There are general instructions for installation, that coves almost everything needed for installation. It is important that you cannot have Lanzaboote enabled for the first boot. This means, that you have to enable it later in the setup cycle. This is why it is not included in the above setup instructions.
In addition, some extra information how to get secure boot keys enrolled on machines that I used:
- On my HP ZBook, secure boot setup mode is enabled while having 'Secure Boot' disabled and after enabling 'Clear Secure Boot keys'. After enrolling, secure boot is enabled automatically.
Installing Windows after NixOS can cause the bootloader to become darker, but this usually goes away after a few reboots. No idea what causes it.
On HP laptops the BIOS option 'Verify Boot Block on every boot' causes issues, as NixOS modifies the boot partition a lot.
Here I have collected some useful resources I have used to create this configuration. For general Linux questions, it is usually a good idea to consult the Arch Wiki.
For looking for packages or configuration options respectively.
- Nix Packages for looking up packages.
- MyNixOS for looking up configuration options.
- Noogle for looking up
pkgsandlibfunctions.
Wiki's for Nix language basics.
- Luks Encrypted Swap
- https://nixos.wiki/wiki/Hibernation
- https://blog.tiserbox.com/posts/2025-03-10-enable-hibernation-on-nix-os.html
- https://sawyershepherd.org/post/hibernating-to-an-encrypted-swapfile-on-btrfs-with-nixos/
- https://discourse.nixos.org/t/btrfs-swap-not-enough-swap-space-for-hibernation/36805
- NixOS/nixpkgs#276374
- https://haseebmajid.dev/posts/2024-07-30-how-i-setup-btrfs-and-luks-on-nixos-using-disko/
Resources for configuring Firefox with Nix.
- Available Policies
- Current Policies:
about:policies#documentation - Available Preferences
- Available Preferences Detailed
- Current Preferences:
about:config - Some Examples
- Declarative Bookmarks
Guides, threads, wiki's that I have found useful.
- Hibernation
- Bluetooth
- Some Dude's Configuration
- Declarative WiFi with Sops
- How to Dual Boot Windows and NixOS
- YubiKeys on NixOS
- Reference for Writers
- Using Wrappers
- Wrapping Neovim
- Neovim Wrapper Source
- Erase Your Darlings
- List of Keyboard Variants on Linux
- Dmenu Patch for Line Height
My convertible HP laptop has a full IMU built-in for whatever reason. The following command outputs the monitor orientation in degrees for example.
watch-sensor /sys/bus/iio/devices/iio:device2/in_incli_x_raw 0.00001Would be fun to create a script that runs a compass or whatever. Note that the compass is not the best, considering the laptop has magnets in it.
NOTE: Some stuff relating to tablet mode on convertibles: libinput # Exposing for other system info. My convertible hp laptop has there messages when folding over and back: -event15 SWITCH_TOGGLE +4.283s switch tablet-mode state 1 event15 SWITCH_TOGGLE +12.837s switch tablet-mode state 0 Maybe add rot8 for automatic rotation? Needs a systemd service, and probably not supported by all laptops.


