NixOS Reference - Oliver-Mustoe/Oliver-Mustoe-Tech-Journal GitHub Wiki
NOTE: Working with a commit in this case but really can do it with any Nixpkgs tar!!!
Can get a commit from here https://status.nixos.org/ for example, really any commit works.
Download the tar of the commit by putting it into the format https://github.com/NixOS/nixpkgs/archive/<COMMIT_HASH>.tar.gz
like https://github.com/NixOS/nixpkgs/archive/6e99f2a27d600612004fbd2c3282d614bfee6421.tar.gz
Then run nix-env -f "https://github.com/NixOS/nixpkgs/archive/<COMMIT_HASH>.tar.gz" -qaP --json --meta '*' > <OUTPUT_LOCATION>
(you can put the output anywhere, recommend outputting somewhere though as it takes a second)
With that you have a JSON formatted output with all relevant information for sea
From https://nix.dev/manual/nix/2.18/command-ref/nix-env/query
-
-f
- Specifies a path (can be a local path or a remote one like github, can point to a tar or a folder) -
-q
- Display information about packages -
-a
- Work with derivations in the active Nix expression -
--json
- Output in JSON -
--meta
- Output full meta information about the package
sudo nixos-rebuild
Using a configuration in a non-standard repository (the config WILL NEED TO POINT TO A hardware-configuration.nix IN A CORRECT PATH!)
sudo nixos-rebuild switch -I nixos-config=path/to/file
sudo nixos-rebuild switch --flake ./nixos-config/
nix flake metadata
Update a specific input in your lock file (check with metadata command above what you want to update!
nix flake lock --update-input nixos-cosmic
If changing bootloader, make sure to run the following before triggering a rebuild:
export NIXOS_INSTALL_BOOTLOADER=1
nix-store --gc
Causes some repeat files to be made into one, can reclaim A LOT of space
sudo nix store optimise --extra-experimental-features nix-command
NOTE: Does require a nix-store --gc
after to clean out the profiles!
# List generation
nix profile history --profile /nix/var/nix/profiles/system
# Delete generations older than 14 days
sudo nix profile wipe-history --profile /nix/var/nix/profiles/system --older-than 14d
The oldie but goodie is to log out and log back in. I have found that particularly when I am upgrading packages a log out and log back in is needed for the use of the new versions. Restart is the best option for a big upgrade like changing DE's.
When changing Desktop Environment (DE), I would recommend using boot
instead of switch
, and then restarting. This makes it so your current DE can build and setup your next DE, but wont crap itself while trying to.
For example:
sudo nixos-rebuild boot --flake ./nixos-config/
After changing the systems hostname, if a chromium reports some type of error of the "process being in use by another computer" (chromium did this after changing the hostname of my NixOS box) then all you have to do it delete the SingletonLock
file in ~/.config/chromium
:
rm ~/.confg/chromium/SingletonLock
If a flake.nix is in a github repo, and you try to run it but it says a file is not found, it means the file must be tracked by Git before you can use it :) https://github.com/NixOS/nix/issues/6642.
If your getting errors with bootloader switches, troubleshoot the following:
- Ensure that you have a compatible firmware (GRUB needs UEFI, and systemd-boot is needed for BIOS BuT can run on UEFI)
- As per “could not find any previously installed systemd-boot”, remount the /boot drive (check /boot with
lsblk
)
If trying to use WireGuard without using it in the Nix way, make sure that your firewall actually lets it thru as WireGuard seemingly cant access it :).
- https://nix.dev/ - Good general guide for nix activities (especially with nix-shell!)
- https://nixos.wiki/wiki/Flakes - Introduction to flakes
- https://nixos-and-flakes.thiscute.world/preface - Good guide to using flakes and home-manager
- https://nixos.wiki/wiki/Nvidia - Nvidia go burr
- https://ryantm.github.io/nixpkgs/#preface - nixpkgs deep dive
- https://nixos.org/manual/nixos/stable/#ch-development - modify and extend nixos
- https://leanpub.com/nixos-in-production - production go burr
- https://determinate.systems/posts/declarative-gnome-configuration-with-nixos/
- https://gitlab.com/engmark/root/-/blob/master/configuration.nix
- https://search.nixos.org/packages - Nixos packages and options
- https://noogle.dev/ - Nix options
- https://home-manager-options.extranix.com/ - Home manager options
- https://www.nixhub.io/ - Packages on NixOS (really granular with with different package versions and the github releases they came in!)
Below is what I am currently planning on reading regarding Nix/NixOS
- https://nixos.org/guides/nix-pills/ - An older introduction into the Nix, want to get a solid base in Nix and then jump more into NixOS details
- https://nixos-and-flakes.thiscute.world/preface - Have repeadetly read the beginning of this, but I want to make a concentrated effort to get through the whole thing at least once
- https://nixos.org/manual/nixos/stable/#ch-development - Have read some of this but I want to like fully read it with the knowledge of Nix and see if I can start almost porting system admin stacks (like ELK) to NixOS easily in a module. I may put something before this as I go.
Old notes page - may go back to one day :)
Below is the transcript to a presentation I made about Nix for my senior year independent study:
(1) What is a package manager?
A package manager keeps track of what software is installed on your computer, and allows you to easily install new software, upgrade software to newer versions, or remove software that you previously installed. As the name suggests, package managers deal with packages: collections of files that are bundled together and can be installed and removed as a group.
Thus, we can say that a package manager automates the installation/upgrading/removing of computer programs from a system in a consistent manner. Moreover, package managers often manage a database that includes the dependencies between the software artifacts and version information in order to avoid conflicts
Packages can depend on, recommend, suggest, break, conflict
Job of the package manager to present an interface which assists the user in managing the collection of packages installed on their system.
There can be different types of package managers, but the ones we are going to be focusing on are OS package managers for Linux.
(2) How does a normal package manager work
query for information about packages, fetch packages from repositories, install and uninstall packages using automatic dependency resolution, and update an entire system to the latest available packages.
When you execute a command to install a package, the package manager looks at configuration files on the local machine to determine the location of a repository that has a given package on the internet. Then the installation command downloads the package along with its dependencies from the internet. Finally, the package manager installs and configures the application on the local machine.
(3) So whats the issue?
If a package B conflicts with another package C, then the two packages cannot be installed at the same time. For instance, fb-music-hi conflicts with fb-music-low because they provide alternate sets of music for the game Frozen Bubble.
There are some attempts to minimize this issue with traditional package managers, such as Debian’s alternative systems, so theoretically possible but painful in practice.
That stacks as well, as software development keeps progressing and builds on top of itself it becomes more and more likely that a dependency will break with another dependency. This is especially true in Linux open source projects as they are heavily component-based.
This creates dependency hell, where different versions of libraries are needed and it becomes the users problem to fix.
Even more installing software from traditional package managers can create version issues. Say you develop an application on A version 1 but apt only has version 2 in its repositories, this means you either have to port your application to A version 2 (which depending on breaking changes could entirely stall a project or deployment) or have to add a repository (that may not even work)
As the software landscape increases it is readily apparent that traditional package managers are not equipped with the tools to optimally manage the packages of modern Linux systems
(4) The solution - Nix
(5) What is Nix?
Nix is a lot of things. First it's a functional language that is used in a functional package manager then was then used to create its own operating system (NixOS)
For this presentation we will mainly be focusing on the package manager
But we will also be talking about the programming language a little as its needed for context
(6) How does nix work?
In essence, the Nix package manager builds packages, called “derivations”, from build instructions made in the Nix language and stores them in a path inside the Nix store.
The Nix store is a storage system in your filesystem with its root at /nix/store by default. The Nix daemon stores several things in the Nix store but the most important for us is the the products of derivations: a folder containing build outputs such as /nix/store/<hash>-my-package/
This structure is actually very important, broken down the path describes:
The root path is /nix/store by default.
The input hash is derived from the inputs (sources, dependencies, compiler flags, etc.) to the derivation used to build the package
The package name is provided by the package creator
This allows each package to have its own unique subdirectory, where any inputs changes creates a new package. Meaning that 2 packages with slightly different dependencies become entirely new packages.
(7) How does nix work cont.
But how do we keep track of what packages in what places? How do I run my applications?
The solution Nix uses is to create directory trees of symlinks to activated packages. These are called user environments and they are packages themselves.
Looking at this you can see that for example alice is using the default profile. Whats also really cool about Nix is the default-42 it has there. When you do operations that change the user environment a new user environment is actually generated and “default.nix” is a simple symlink to the new generation (seen by the switch.)
This makes sense as you can see in the store the user environments are themselves symlinking to other packages, so changing generations is just changeling symlinks.
Nix with this allows you to rollback a generation, as “default-42” is not automatically deleted you can add a package to your environment > for whatever reason decide you dont like it > and Nix allows you to just rollback if you want.
(8) Ok ok…so how does it work overall?
Looking at a high level, this is a flowchart of what happens when you attempt to add a package to your user profile.
First it looks to see if that package is in your channel. Channels are a mechanism that allows you to point at a repository of Nix code. The most popular (and default channel) is nixpkgs. This repository contains over 80,000 packages…technically the build instructions for those packages. So when you are making a package you import the channel, so whenever you attempt to get a package you're getting its build instructions from the channel. If not, cant install as you dont have the build instructions.
Then you check if that package (using the nix store path of the package) see if your package already exists. If so use it, if not…
Check if the inputs are in the local nix store. As we looked at the hash earlier, a Nix package defines all of its dependencies with the hash. So you can easily check if you have all of the inputs. If not then you would attempt to get the dependencies an inputs, which would do a recursive loop down attempting to get all of firefoxes dependencies.
Once you have all the dependencies. You check if the package is in the cache server. To speed up build times, Nix caches packages in a cache server for easy and fast downloading. If not found, then you must build the package from scratch
Finally, you get your package at the Nix store path.
(9) Nix in action