NixOS beginner tutorial: zero to flakes
Are you new to NixOS and want to learn how to manage your desktop installation declaratively? If so, this beginner-friendly tutorial is perfect for you! NixOS is a unique Linux distribution that centers around the Nix package manager. With NixOS, you can create a configuration file just once, and then easily apply it to multiple different systems. It also comes with incredible amount of customizability, 80 000+ packages, and is nearly impossible to break. In this tutorial, you will get started with declarative system management in NixOS.
Note that you should already have some basic understanding of linux to use this distro, and it probably should not be your first one.
OS Installation
NixOS used to have a tedious manual installation, but thanks to the adoption of the popular calamares installer, installing the distro has become straight forward.
The hard part begins after booting up your system for the first time. NixOS has a package management system that is very different from other distros.
While it is technically possible to install packages using the
command nix-env -iA packageName
, I highly advise against doing so, because
you are going to miss out on many advantages of NixOS.
Right after first installation of NixOS, you are going to get a default
configuration file at /etc/nixos/configuration.nix
. Open it nano or other
provided code editor.
Example:
|
|
Of course you are going to have much more options defined there, however the one that we are interested in right now is “users”. NixOS is going to use your username from the installation phase, but you can define more users.
The .nix syntax might seem a little strange at first, but until you are doing anything advanced, you can think of it as json with functions.
Installing new desktop environments and other software
Now let’s say you don’t like KDE, how would you install GNOME? It’s only the matter of changing one line:
|
|
Or what if you want to install some package like neovim? Just add it to your user’s array of packages like follows:
|
|
To apply these changes you are going to need to rebuild the system. To do it use this command in your terminal:
|
|
What it will do is create a new NixOS generation and switch to it. Reboot, and
while your system is loading, you will be able to select previous or current generation.
This is possible because NixOS does not actually remove packages unless you tell it to, so
all your NixOS generations will add up until you run nix-collect-garbage --delete-older-than 10d
The new generation is clean of all KDE packages, and will function as if you had just installed GNOME.
Temporarily installing software
To try out software on any other distro, you’d have to pollute your environment with packages and dependencies or spinning up containers. Nix simplifies this task a lot, because you can just declare environments that contain variables and packages you need at the moment.
To get a shell with python and nodejs installed run this command:
|
|
You will be dropped into a shell that contains those packages, and when you exit it, they will no longer pollute your system. Later they will get garbage collected just like generations.
You can also declare those environments in a .nix file as shown on the NixOS wiki.
Nixpkgs and Nixpkgs-unstable
NixOS has two main channels that you can install software from: nixpkgs and nixpkgs-unstable. First one has stable packages that are updated every six months, while second is a rolling release.
You can search for new packages here.
Manipulating your channels is done through these commands:
|
|
BUT WAIT! You might ask:
- Why would I manage my channels manually if I’m using nix?
- What if one of my systems has a newer channel version and breaks another one?
- Can’t I just declare it in a file so it does it automatically?
The answer is of course you can! That’s where the great experimental feature comes into play, and it is called…
NIX FLAKES
Nix flakes is a concept that every newcomer eventually stumbles upon. It might be a hard concept to grasp in the beginning, but it fixes all the problems mentioned above.
They allow you to specify your code’s dependencies, and provide you with lock file just like any other modern package manager would.
Being an experimental feature, flakes first need to be included in your configuration.nix as follows:
|
|
After rebuilding your system, you should have access to nix flakes. Now let’s change configuration.nix file to flake.nix
Doing it is only the matter of adding flake.nix to our /etc/nixos/ directory:
|
|
As you can see, we specify dependencies in “inputs”, and then outputs contains “nixosConfigurations”. We define the channel we want to use in inputs. “nixosConfigurations” is the first place where NixOS is going to look for your configuration, so that’s where we put out configuration.nix module.
To rebuild your system you should now use:
|
|
You can now also temporarily install software from different channels:
|
|
Next steps
You should now have some basic understanding of how to work with NixOS, but the journey is far from over. NixOS gives incredible power to those who are not afraid to put in the hours.
Nix flakes are very useful for defining shell environments, derivations and home-configurations.
I highly recommend to look into those, and also reading through nix pills to better understand the nix language.
Nix and NixOS have so much more to them, and it is impossible to tell everything in just one blog post. It really is a fascinating ecosystem whose ideas may be too good to be denied.