Building a Philosophy Workstation with NixOS: Learning Home Manager and Configuring Sway with Wayland
A NixOS tutorial on using Network Manager, Home Manager, and setting up a Graphical Environment with Wayland and Sway
This tutorial is Part I in a series on configuring a default Minimal installation of NixOS to a state where productive philosophy can be done. We will start from a text-only environment that has minimal amenities (e.g. where the previous installation guide left off), and slowly build up our configuration.nix
file until we have a graphical user interface, as well as all the applications that are conductive towards producing philosophy. In this series, we will complete the following:
- Configure networking using NetworkManager (e.g
nmcli
) - Install low-level systems applications (e.g.
git
,wget
,parted
, andvim
) - Learn about and use Home Manager to manage our user-level applications.
- Install and configure the Sway display manager with the Wayland display server
- Fine tune the Sway graphical environment, enabling buttons for brightness and volume control, and enabling audio (Part II).
- Install and configure VSCodium, LaTeX, Firefox, and other tools needed to produce philosophy (Part II).
This tutorial is designed for the philosophy student who's familiar and comfortable with Linux in general, but new to NixOS. It may also be suitable for Computer Science students and Software Developers, with some modifications. It will walk you through the process step-by-step and provide ample links and explanations.
The ontology of this tutorial is dialectical in nature. Hence we will not provide a complete configuration (which would only be true opinion, and not knowledge) – but take the reader step-by-step through the process of building a NixOS workstation.
Installing and Using NetworkManager for WiFi Connections
The first, and one of the most important steps of any Linux installation, is to ensure that we have WiFi connectivity. After all, the Internet is one of the most direct embodiments of our Mitsein!
Adding NetworkManager to configurations.nix
There are many ways to manage Internet connectivity in Linux. We will use NetworkManager, a high-level command line interface that simplifies the process – as well as comes with many GUI interfaces which we can add later on. In your /etc/nixos/configuration.nix
, add the appropriate options in the first level of nested brackets (right after imports and account configuration).
We will enable DHCP on both of our wired en0
as well as wireless wls6
interfaces – these options should already be there from your original installation.
Note how all of our options (e.g. such as hostname
, networkmanager.enable
, etc) are within the networking
namespace. This makes sense, as they all relate to configuring the networking of your NixOS installation. Do you wonder what other options are available? NixOS has a wonderful options search on their website, where you can look up any options. This is a good resource to keep in mind as you progress through this guide!
Now run a quick rebuild to allow NixOS to install NetworkManager
.
Now Network Manager should be available on the terminal via the nmcli
command. If you run sudo nmcli
, you should receive a colorful status output, where it lists various devices that are available (such as ethernet, wifi, and the odd loopback interface).
Adding the networkmanager
group to our User Account
Is using sudo
(or root
) a neccessary condition for accessing nmcli
? Or is the need privilege escalation only contingent on our account's lack of permission, which can be remedied in other ways? In fact, you can add the networkmanager
group to your user account, so you can access nmcli
without needing elevated privileges. Simply modify the extraGroups
directive in your users.users.[username]
option, and add networkmanager
as a group for your account:
users.users.myUserAccount = {
isNormalUser = true;
shell = pkgs.zsh;
extraGroups = [ "wheel" "networkmanager"];
};
Connecting to Wifi using nmcli
: Practical Steps
Now our configuration of NetworkManager is complete. All that remains is to learn the practical steps of connecting to wifi. I'll guide you through the commands that I use to connect to WiFI – but keep in mind that you'll always have more certain references at hand, through nmcli --help
and man nmcli
.
Scan for WiFi networks in a new location:
nmcli device wifi rescan
List available WiFi networks (these are the ones you just scanned!):
nmcli device wifi list
You should now see a colorful array of WiFI names (SSIDs), as well as their signal strength. Find the name of the network you wish to connect to, and then type:
nmcli device wifi connect WiFiName --ask
NetworkManager should ask for your password, and now you should be successfully connected to the network. You can test your connectivity using nmcli networking connectivity check
, or even just by pinging a nearby server (i.e. ping 8.8.8.8
).
Why do we invoke the command with the option --ask
? Check out the Linux manual entry for nmcli
in order to find out!
man nmcli
NetworkManager auto-magically saves all of your WiFi connections. In the future, when you return to a location where you have connected before, you don't need to enter the credentials again. Simply run the following in order to list all your previous connections:
nmcli connection show
And then run:
nmcli connection up <WiFi Name>
NetworkManager
should actually connect to known networks automatically – the above instructions are useful as a backup.
Connecting to Enterprise, Education, and Other Networks: A Complication
The above workflow works well for simple networks, namely the sort that you'll find at a coffee shop, or a friend's apartment. That's because they utilise a form of authentication called WPA-Personal (or WPA2, WP3). That's the type of WiFi network where you only need to enter a password.
Unfortunately, most Universities, Colleges, and Institutions of Philosophy utilise a more sophisticated WiFi authentication method, called WPA-Enterprise. This is the type that requires an username and password, or even additional settings like domain.
NetworkManager supports these more complicated types of connections, but you'll need to setup a connection profile. I'll write a seperate guide detailing this more involved procedure at a later date.
(If you really need help with this step, feel free to email me, and I'll let you know how I made my connection profile)
Installing Low-level Systems Applications
Congratulations! If you have successfully completed the previous steps, you should be able to access the internet. We're still in the command line right now, but we can make it more friendly, by installing some familiar tools. Right after your networking configuration, add the following stanza:
After a quick sudo nixos-rebuild --switch
, these additional packages should become installed, and available system-wide. Now all users will get to access vim
, parted
, git
, and wget
. This means we'll have a powerful editor available in the command line, as well as a way to check out git repositories and download files. Any number of programs can be installed on Nix this way! In fact, the NixOS website has a search function for packages analogous to the options search. It's a good way to find out what programs are available!
Introduction to Home Manager
But wait, is it really a good idea to install all programs on a system-wide basis? Perhaps there are programs that should only be available for the user who installs it. Likewise, many of the more advanced programs like git
or firefox
comes with a dizzying array of configuration options that are personal (such as setting an account name or email address). Is there any way we can install and configure programs only for the individual user?
The NixOS ecosystem does provide a powerful tool for managing settings and programs (in other words, an environment) on a per-user basis. This tool is called Home Manager, and it has many sophisticated uses. For our purpose, we will only use it to manage programs and configuration files for our user. Here's how to use Home Manager in your configurations.nix
.
Installing and Configuring Home Manager
First, install Home Manager following the instructions in it's manual. As with both Computing and Philosophy, we always follow upstream sources. You wouldn't read someone else's opinion about a Platonic dialogue, would you? After adding the Home Manager channel, we can then modify our configurations.nix
accordingly, adding the following directives:
Why do we set home-manager.useUserPackages
and home-manager.useGlobalPkgs
to true
? Check out the reasoning in the Home Manager documentation to find out. You may set them both to false
, if you like – Philosophy is practiced by contrarians, after all.
You should have noticed by now that all directives in your configurations.nix
file have different levels of scope, sort of like a domain name or Aristotelian category. That's because NixOS configuration is written in a programming language called the Nix Expression Language. It's closely related to Lisp and Scheme, which are other programming languages that are very keen on brackets, parantheses, and Philosophy. In practical terms, this means that you can group together, and re-arrange the Nix expressions as you wish. The above configuration can also be written like this, for example:
# Begin home-manager directives
home-manager = {
useUserPackages = true;
useGlobalPackages = true;
users.users.myUserAccount = { pkgs, ... }: {
# Everything inside here is managed by Home Manager!
programs.home-manager = {
enable = true;
};
};
};
As you work on and build up your configurations.nix
, keep this perculiar property in mind. It'll help you re-order your configuration files as you amass more options in time.
How to use Home Manager to Install and Configure Programs for your User
Now that we've setup NixOS to use home-manager, we can begin installing programs and configuring their settings on a per-user basis. Make sure to have rebuilt your system (sudo nixos-rebuild --switch
!), and follow along as we add some programs with Home Manager. Keep in mind that the following directives will be added within the home-manager.users.users.myUserAccount
brackets (i.e. where the # Everything inside here is managed by Home Manager!
comment lies). I'll let you know once we add files in the other bracket (where we originally installed the systems packages).
Installing using home.packages
As far as I can tell, there are two ways to install programs using Home Manager. Some programs like fortune
or gnumake
are simple, low-level, and do not have configuration options associated with them. These programs are installed just like the system-wide packages we installed earlier, but they will only be available for our current user:
From my observations, it seems that we use home.packages
to install these programs, because they have not been yet "wrapped up" by Home Manager contributors in a form that exposes all of their settings. These programs might be so simple and low-level that they don't have any options to be made available in the first place.
Installing via a program
directive
For more sophisticated programs, we install them by declaring a program directive, where we state that they are enabled (enable = true;
). I do not know why a priori some programs are available this way, and others not – but assume it is because the Home Manager contributors have not packaged everything in this manner yet.
As you can see, programs that have been packaged this way have all of their configuration options exposed. This means we can use Home Manager to manage their settings for us. This is very powerful, because if you configure your programs with all their customisations using Home Manager, then you can replicate your setup anywhere by simply copying your configurations.nix
file and running a sudo nixos-rebuild --switch
. Imagine making a very fancy, sophisticated setup – and even putting your configuration file into version control. Wouldn't that be a dream?
Putting our two examples together, this is how the Home Manager snippet of your configurations.nix
would look like, with both git
and some packages installed:
Remember to rebuild you configuration, using nixos-rebuild --switch
!
Finding More Home Manager Programs
How do we know what programs can be installed using the programs.[name].enable
directive? For a given program like program.git
, how do we find all of it's options? Regular NixOS has it's options search, and package search, as we've seen earlier. Does Home Manager possess a similar search function?
Yes, it does! There is the Home Manager Options Search, a community project maintained by other Home Manager users. It works the same way like the options and package search for regular NixOS.
Home Manager's manual also has an appendix which lists all the programs that it has packaged, along with their options. You can visit the link above and take a look! It's not as easy to navigate, but you can simply use Ctrl+F to search within the page.
For any new program that you want to install in your Home Manager, a good workflow seems to be:
- Search via the Options Search or look through the manual appendix, to see if it's available as a packaged
program
that you canenable
, and set it's configuration options. - If it is not within the Appendix, find it in NixOS's packages search, and then simply add it in the
home.packages
list.
I developed this workflow through a process of a trial and error. I'm still very new to NixOS myself, and this guide documents my understanding of Nix – I may be wrong in regards to best practices. If you know of a better way to find programs for Home Manager, please let me know!
Now you should be reasonably confident in adding new programs using Home Manager. Why not add tmux
, and neovim
? Here's how they might look like – this snippet is copied out of my configuration, but don't let my settings inform yours – check out their options in the Home Manager appendix and modify them your own way!
programs.tmux = {
enable = true;
keyMode = "vi";
shortcut = "a";
terminal = "screen-256color";
clock24 = true;
shell = "/etc/profiles/per-user/myUserAccount/bin/zsh";
};
programs.neovim = {
enable = true;
vimAlias = true;
};
Likewise, I installed the following packages. Do you recognise them?
home.packages = with pkgs; [
fortune
file
htop
exa
zenith
neofetch
irssi
gnumake
];
With all of these, you should have a pretty comfortable command-line environment with NixOS. Make sure to run nixos-rebuild --switch
!
Installing and Configuring Sway with Wayland
Now that we are confident with configuring NixOS on the command line, let's move on towards installing and building a graphical environment. There are as many schools of Desktop environments as there are Philosophy – but for this tutorial, we will go with Sway. Sway is a tiling window manager that uses the Wayland display server.
Adding a display server and window manager to our NixOS installation would give us a graphical user interface, and allow us to take our first steps away from the analytic consoles and command-prompts of yesteryear – and move into the brave new world of Postmodernism!
There are various steps involved here. Many of which I have sourced from different guides and mailing-lists. I admit I do not understand all the configuration – unfortunately, I can only offer the appearance of knowledge here, and not knowledge itself. If my explanations are lacking in any way, or you have some clarifications – please reach out and let me know.
Enable Hardware Support for Wayland
First, we must enable some hardware support options for Wayland and Sway. OpenGL is a graphics API that our hardware uses to render accelerated graphics. If we do not enable this option, we will run into a bug and Sway will not run.
Please note that these directives go into the top-level (i.e. OUTSIDE) of your home-manager bracket. Place them on the same level as your other system-wide configuration.
# Hardware Support for Wayland Sway
hardware = {
opengl = {
enable = true;
driSupport = true;
};
};
XDG Integration
Next, also in the top-level we must add the following XDG directives. XDG is a standard originating from freedesktop.org which formalises a set of common variables and methods for desktop applications to interact with each other. The following settings enable what's called a XDG Portal, which improves communication between bundled flatpak apps, and Wayland.
xdg = {
portal = {
enable = true;
extraPortals = with pkgs; [
xdg-desktop-portal-wlr
xdg-desktop-portal-gtk
];
};
};
Adding packages to HomeManager in Support of Sway
Now, it is time to go to the HomeManager level and add some packages that Sway will need to use. I found the list of these packages from the NixOS Wiki page on Sway, which you should also review as it contains additional information.
home.packages = with pkgs; [
# ...
# All of the below is for sway
swaylock
swayidle
wl-clipboard
mako
alacritty
wofi
waybar
];
Each of these packages serve a specific purpose.
swaylock
is a idle screen locker.swayidle
is an idle timer.wl-clipboard
allows you to copy-paste (i.e. a clipboard).mako
is a "notification daemon," which creates little floating popups when you receive messages.alacritty
is a rust-based terminal. This is very important, as it is the terminal that you'll be using within the Sway graphical environment.wofi
is an application launch menu. It's like the dash on Mac OS, where you get to search for the name of a program, and run it.wofi
is a Wayland descendent ofrofi
, which was a descendent ofdmenu
. Isn't Open Source interesting?waybar
is a status bar. Ultimately I did not use it, but uncomment it for your own configuration
Please be very careful with swaylock
right now. If you run it in the command line, you will get locked out of your computer. Even if you type your password correctly, it will not let you in. That's because swaylock
must be properly configured to accept your password and authenticate to your computer using PAM, which is like an API but for authentication. In order to properly get swaylock working, add the following directive to your system-wide configuration (i.e. not inside home-manager!):
# Allow swaylock to unlock the computer for us
security.pam.services.swaylock = {
text = "auth include login";
};
Later on, once you are inside Sway – you'll be able to lock your computer by running swaylock
on any terminal!
Adding and Configuring Sway with Wayland as a Program in Home Manager
Now we are ready to add and configure sway with Wayland. The instructions here are sourced from the NixOS Sway wiki page, once more. The following snippet goes inside your Home Manager (i.e. on the same level as programs.git
).
This is a lot of configuration, and it's not easy to understand at first. So just like with reading Hegel, we'll go through it line-by-line and unpack it.
First, we enable
sway. We also enable the wrapperFeatures
for gtk, because it lets applications decorate their windows using the gtk
toolkit, which is a common library used to make GUIs for programs.
Next, we begin the sway-specific configuration in config
. Sway has a large number of configuration options, all of which are documented in the Home Manager manual's appendix. If you have time, I highly recommend browsing it – but the following three are the most important:
We set the default terminal as alacritty
, otherwise you'll be faced with a horribly ugly default terminal. We'll also set the application launcher menu to wofi
. We specifically call wofi
with the --show run
option, since that's for listing applications and running them. wofi
has plenty of other options, such as --show ssh
for starting an SSH menu – but that's not what we need. The bars
option is a list [ ]
of multiple brackets { }
, each of which contains the configuration for a separate status bar. We will only need one status bar, which will be located towards the bottom of the screen. My configuration does not use waybar
, but you are welcome to uncomment it for yours.
Finally, we set some settings for our laptop's default display eDP-1
. Specifically, we set the pixel-scaling factor to 1
. If you have a high-resolution screen, you may wish to set it to 2
(so that the text is not too small).
Adding and Configuring Alacritty with Themes
Finally, the last thing we need to do is to configure our graphical terminal emulator, alacritty
. Although the configuration looks difficult at first, you can see that it is all entirely contained within the settings
brackets. The options are documented in Home Manager's manual, once again.
The most important setting here is probably the size
setting – it determines how big the text is in the terminal. If you have a high-resolution screen, the default size will probably be too small. As you build up your configuration.nix
file, this would be a good place to theme and make a really nice-looking terminal.
Rebuilding NixOS and Running Sway
Now everything should be all done! If your configuration file is correct (make sure that the top-level and home-manager-level directives are in their proper places), you should be able to rebuild your system and run now.
sudo nixos-rebuild --switch
After this is done, I recommend restarting your computer, just in case.
sudo reboot now
After logging in (making sure to select the newest version of you NixOS install from the boot manager), you will be greeted once again by a command line environment. But don't fear! All you need to do now is to run:
sway
And you should be in a graphical environment! Congratulations, you have successfully transcended the command prompt, and reached a transcendental aesthetic!
Help! I'm Stuck! How do I... get around in Sway?!
If you're like me, and you have never used a tiling window manager before, you probably have no idea how to get around. At all. And even worse, when you search for "sway documentation", you'll find no instructions on how to control the Window Manager!
Fortunately, Sway is based on i3, a venerable tiling Manager hailing from the Archlinux days. And it has both excellent documentation on it's project site, as well as a quick-reference cheat sheet to help you get around. Print out a copy and keep it with you – you'll become an expert in tiling window managers in no time!
Conclusion of Part I
You should now have a graphical environment in NixOS, that you put together yourself. It's still a very bare and basic space, but should serve as a good foundation for further customisation. In Part II of this guide, we will take this foundation and build upon it further. Specifically, we will install and configure FireFox together, as well as other applications like Element (Matrix Client) and Signal Desktop. I will also show you how to configure audio using the Pipewire service, and most importantly – install LaTeX and VSCodium.
I hope you enjoyed my tutorial. If you have any questions or comments, feel free to contact me – I would love to know if my guide has helped you in any way. I also write about Philosophy in my own time – let me know of your thoughts!