/change the last file path depending on project :scriptsdir: ../doc/scripts/matching :imagesdir: ../content/img :icons: font :source-highlighter: pygments
If you are here then I expect you to have at least a basic understanding of the benfeits that the Nixos operating system and the ZFS file system provide. If not, then let me be the first one to tell you that you have reached the end of the internet and it is probably time you go to bed. You are reading about a system setup that probably only .000000001% of all computer users use, but they happen to the smart users and I plan to follow in their footsteps and leave a trail of breadcrumbs behind.
As for myself, I see many benefits of functional progamming and in general removing the amount of "inplace" changes, or mutation, in all levels of my technology stack. I have moved from using a traditional Linux system to Nixos, from Python to Clojure, plan to use a database like Datomic instead of traditional mutating DBs such as Postgres, and I see the filesystem as just another step in this evolution.
I am a beginner at ZFS, so I hope this guide doesn’t have too many errors or omissions. I have done my best to prevent any so included each and every step you will need to take to get this working. I want it to be a hand holding guide for the beginner like me who has trouble following the Nixos guides because they assume too much pre-existing knowledge from the reader. I used a combination of many guides in order to piece this one together, they are as follows:
Also, this guide is for me. If I want to install this setup on another machine, then I don’t want to have to research this information all over again. So, I borrowed, and in many cases outright plagerized, the information in the links above in making my guide. I hope the original authors don’t mind too much :)
Hopefully one of you can use this guide and one day contribute to creating a damn graphical installer for Nixos.
By following this guide you will install the Nixos operating system on top of the ZFS file system. Within the ZFS partition you will have a home and nixos data pool. This is so we can take snapshots of the home datapool for backup and rollback purposes, but not comsume disk space copying the Nix store. Nixos will handle the backup and rollbacks of the OS through the declarative approach and Nixos magic.
This diagram [partitions] provides a sketch of what the final system will look like.
In order to create bootable usb containing the installer you will need two things:
-
An image of the Nixos minimal installer.
-
A way to create a bootable usb with the image.
The first step is easy, download the minimal installer from the Nixos site here. Remember to download the minimal installer to use with these instructions.
The second step is also easy but highly variable. So, I am going punt and provide a link on this process because there is a myrid of different approches. Don’t worry, I will hold your hands step by step once we actually pull up the installer. In the meantime, here is an article providing you many options depending on your current OS.
Now place the USB device in your computer and restart. During the boot process press whatever key your computer requires, mine is F1, to get into the boot menu. If you are having trouble please consult this article. Once in the boot menu, ensure the following are selected:
-
Boot order will use the usb device before the harddrive
-
Disable safe boot (if applicable)
-
Ensure UEFI mode is enabled (if applicable)
Now exit the boot menu.
Once the install process starts you will be greated with a Nixos splash screen with a list of options, just choose the first install option. Well, that will be the last graphical part you will see in this process. Next, you will see a lot of activity with terminal green colors, and when finished it will end with a simple green Nixos prompt. You are logged-in automatically as nixos.
[nixos@nixos:~]$
For the remainder of this document we will drop down in a root shell. The commands in the remainder of the document assume the # prompt. I excluded the prompt character from the code snippets so there is no confusion.
sudo -i
Now your prompt should be in red and end with a "#"
Networking is necessary for the installer, since it will download lots of stuff (such as source tarballs or Nixpkgs channel binaries).
Tip
|
Use a wired connection if possible. |
A wired connection is preferred, but I provide the Wifi instructions below in case you don’t have access to ethernet. If you are using a wired connection then you can skip the rest of this section.
The $SSID and $PASSPHRASE are variables in the command below, enter your information in their place.
wpa_passphrase $SSID $PASSPHRASE > /etc/wpa_supplicant.conf
Lets check to make sure that worked. We will open the wpa_supplicant file and make sure the minimal config is there.
nano /etc/wpa_supplicant.conf
network={ ssid="MYSSID" #psk="passphrase" psk=59e0d07fa4c7741797a4e394f38a5c321e3bed51d54ad5fcbd3f84bc7415d73d }
Great, now exit Nano Ctrl+X. You should be back at the red root prompt now.
systemctl restart wpa_supplicant.service
Lets verify that worked by pinging Facebook. If you want additional instructions, they can be found here.
ping www.facebook.com
You will start to see lines appear as it pings the website. This command will run forever unless you stop it, so press Ctrl+C to stop the command.
If everything works at is should, we should now have wifi.
Time to destroy some valuable data! Just kidding. You won’t make a mistake, and more importantly, you have 3 copies of your data on at least 2 different types of storage media and in 2 different physical locations that are unlikely to be hit by the same disaster right? Right?!
Warning
|
Jokes aside, this process will wipe anything on the disk. Consider yourself warned. |
This section will cover the following steps:
-
How to create a blank partition table (delete current)
-
Determine if you have BIOS or EFI
-
Setup partition table based on findings in step above
We are going to use the linux program sgdisk to help us with this task. More information can be found here.
Identify the disk we are going to partition. You will probably see two, one for the harddrive and the other for the USB drive. The one you want will probably be something like sda or nvme0n1. You will also see the usb drive labeled something like sbd, but that will be a much smaller size and it not what we want. The example below uses sda.
lsblk
Combine this with the prefix /dev/
sgdisk --zap-all /dev/sda
You should get a nice terminal output that reads "GPT data structures destroyed! You may now partition the disk using fdisk or other utilities."
A simple way to find out if you are running UEFI or BIOS is to look for a folder /sys/firmware/efi. The folder will be missing if your system is using BIOS.
ls /sys/firmware/efi/
If you see folders and files returned then you have EFI.
Okay, now we need to setup the partitions using the by-id aliases for devices, otherwise ZFS can choke on imports. *
Issue this command to find the disk on your system. We want to find Id of /dev/sda (or whatever your disk is):
ls -l /dev/disk/by-id/
total 0 lrwxrwxrwx 1 root root 9 Jul 16 09:02 ata-HFS5124-33200d_F15110000d6930F35 -> ../../sda lrwxrwxrwx 1 root root 9 Jul 16 09:02 usb-3600050e02e433200d7110000d6930000 -> ../../sdb lrwxrwxrwx 1 root root 10 Jul 16 09:02 usb-3600050e02e433200d7110000d6930000-part1 -> ../../sda1 lrwxrwxrwx 1 root root 10 Jul 16 09:02 ubs-3600050e02e433200d7110000d6930000-part2 -> ../../sda2
We are going to have to reference this ID a lot in the next steps and I don’t want to have to write it out a bunch of times or make a mistake, so lets put it in a variable. The command below is my attempt of using "commmandline-foo" to populate the variable "SDA_ID". This regular expression identifies the beginning of the id (denoted by '^[ata]'). This works because I don’t have any partitions yet. Remember to use your prefix if it isn’t the same as mine.
SDA_ID="$(ls /dev/disk/by-id/ | grep '^[ata]')"
Lets see if we got what we want (it should be a single value):
echo $SDA_ID
You should see the value of the sda drive from above. Now we will combine the id with the device path and the /by-id/ flag to create the $DISK variable.
DISK=/dev/disk/by-id/$SDA_ID
Just like when we created the blank partition table, we are going to use the linux program sgdisk to help us with creating our paritions. More information can be found here.
Caution
|
ZFS on Linux has issues when you place the swap mount within the ZFS partition, so the instrustions below will create a dedicated swap partition. |
Before you follow the steps below you should probably calculate the amount of space you are going to need for the swap partition. My machine has 16GB of memory so I am going with 20GB. In order to calculate your swap you can refer to this article.
These are the instructions for folks with EFI based computers, if you tested and have BIOS then skip to the next section. If not then issue these three seperate commands to create the partition table.
sgdisk -n 0:0:+1GiB -t 0:EF00 -c 0:boot $DISK //(1) sgdisk -n 0:0:+20GiB -t 0:8200 -c 0:swap $DISK //(2) sgdisk -n 0:0:0 -t 0:BF01 -c 0:ZFS $DISK //(3)
-
Partition 1 will be the EFI boot partition.
-
Partition 2 will be the swap partition.
-
Partition 3 will be the main ZFS partition, using up the remaining space on the drive.
To make the next steps easier to understand lets again make some variables:
BOOT=$DISK-part1 SWAP=$DISK-part2 ZFS=$DISK-part3
Creating a partition scheme for BIOS-based computers is much like the EFI instructions, but we will also need a partition for grub. If you completed the previous steps for EFI then you can skip this section.
sgdisk -n 0:0:+1MiB -t 0:ef02 -c 0:grub $DISK //(1) sgdisk -n 0:0:+1GiB -t 0:ea00 -c 0:boot $DISK //(2) sgdisk -n 0:0:+20GiB -t 0:8200 -c 0:swap $DISK //(3) sgdisk -n 0:0:0 -t 0:BF01 -c 0:ZFS $DISK //(4)
-
Partition 1 will be the BIOS boot partition .
-
Partition 2 will be the boot partition.
-
Partition 3 will be the swap partition.
-
Partition 4 will be the main ZFS partition, using up the remaining space on the drive.
To make the next steps easier to understand lets again make some variables:
BOOT=$DISK-part2 SWAP = $DISK-part3 ZFS=$DISK-part4
Below is the basic structure we will be creating. Notice than the ZFS pools and datasets are all contained within the disk we labeled as ZFS . We will have a home data set that we will snapshot and a nixos dataset that we will not snapshot as Nixos does a good job at keeping that information in sync and it isn’t necessary to backup.
+-----+ +---|ZFS | | +-+---+ | +---|----------ZFS--------+ | | | /-----------+ | | | +---| rpool | | | | +-+---------/ | | | | | | | +---home | | | +---root | | | | | | | +---nixos | | +-------------------------+ | +-----+ +---|SWAP | | +-----+ | | +-----+ +---|BOOT | +-----+
Dataset | mountpoint | Snapshots |
---|---|---|
home |
rpool/home |
Yes |
nixos |
rpool/root/nixos |
No |
This is going to be a single disk on our laptop and it will use encryption. Note the "-O" is the letter O not zero.
zpool create -o ashift=12 -o altroot="/mnt" -O mountpoint=none -O encryption=aes-256-gcm -O keyformat=passphrase rpool $ZFS
It will then ask for you to create a passphrase:
Enter passphrase: Re-enter passphrase:
Issue the following three commands to create the data sets shown in in the diagram. Note that the home pool will have automatic snapshots turned on.
zfs create -o mountpoint=none rpool/root //(1) zfs create -o mountpoint=legacy rpool/root/nixos //(2) zfs create -o mountpoint=legacy -o com.sun:auto-snapshot=true rpool/home //(3) zfs set compression=lz4 rpool/home //(4)
-
Creating the root directory within zpool
-
Creating the nixos data pool.
-
The home data pool is going to get automatic snapshots.
-
We will use compression on the home folder to cut down on the size. The ZFS literature says that the performance impact is minimal for the benefits.
We are going to mount each of the filesystems.
mount -t zfs rpool/root/nixos /mnt //(1) mkdir /mnt/home //(2) mount -t zfs rpool/home /mnt/home
-
root
-
home
Now we need to setup our boot EFI as a non-ZFS partition.
mkfs.vfat $BOOT mkdir /mnt/boot mount $BOOT /mnt/boot
In this section we are going to add the necessary entries to the Nixos configuration files to fully use the ZFS filesystems we created. In addition, We will also add some software to make our initial login feel more welcoming, but it will still be a barebones desktop environment. At the expense of brevity, I am going to include the full configuration files so there is no ambiguity on what edits I am making and where. I apologize to all those of you who are reading this on their smart watch.
Nixos is configured off of two main configuration files, which are:
-
hardware-configuration.nix - for hardware configuration
-
configuration.nix - for software, etc
During the install Nixos will use the information in these files to configure the entire system. To start this process we must first have the system create a default configuration for both files.
nixos-generate-config --root /mnt
Before we start editing the configuration files, lets first get our machines networking host id, which is needed by ZFS.
head -c 8 /etc/machine-id
Write down the shell output as we will need it in a moment. Yes, like on a piece of paper or something.
Lets open the hardware-configuration.nix file and see what we have.
nano /mnt/etc/nixos/hardware-configuration.nix
{ config, lib, pkgs, ... }:
{
imports =
[ <nixpkgs/nixos/modules/installer/scan/not-detected.nix>
];
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usb_storage" "sd_mod" "sdhci_pci" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "rpool/root/nixos";
fsType = "zfs";
};
fileSystems."/home" =
{ device = "rpool/home";
fsType = "zfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/3173-2880";
fsType = "vfat";
};
swapDevices = [
{ device = "/dev/disk/by-uuid/"d08158aa-677a-4984-83fe-c938edb7021e";}
];
nix.maxJobs = lib.mkDefault 4;
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
}
This looks good, so lets exit the Nano editor by pressing Ctrl+X
Lets open the configuration.nix file and add the necessary ZFS information. In the future, after we create your user then you will have to prefix this command with sudo as you won’t be root.
nano /mnt/etc/nixos/configuration.nix
Below is my configuration.nix file after making the edits. Please review each of the callouts and add them to your file.
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
];
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# Add ZFS support.
boot.supportedFilesystems = ["zfs"]; //(1)
boot.zfs.requestEncryptionCredentials = true; //(2)
networking.hostId = "238330f5"; //(3)
# networking.hostName = "nixos"; # Define your hostname.
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
# Configure network proxy if necessary
# networking.proxy.default = "http://user:password@proxy:port/";
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
# Select internationalisation properties.
# i18n = {
# consoleFont = "Lat2-Terminus16";
# consoleKeyMap = "us";
# defaultLocale = "en_US.UTF-8";
# };
# Set your time zone.
# time.timeZone = "Europe/Amsterdam";
# List packages installed in system profile. To search, run:
# $ nix search wget
# environment.systemPackages = with pkgs; [
# wget vim
# ];
# Some programs need SUID wrappers, can be configured further or are
# started in user sessions.
# programs.mtr.enable = true;
# programs.gnupg.agent = { enable = true; enableSSHSupport = true; };
# List services that you want to enable:
# Enable the OpenSSH daemon.
# services.openssh.enable = true;
# ZFS services
services.zfs.autoSnapshot.enable = true; //(4)
services.zfs.autoScrub.enable = true; //(5)
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
# Enable CUPS to print documents.
# services.printing.enable = true;
# Enable sound.
# sound.enable = true;
# hardware.pulseaudio.enable = true;
# Enable the X11 windowing system.
# services.xserver.enable = true;
# services.xserver.layout = "us";
# services.xserver.xkbOptions = "eurosign:e";
# Enable touchpad support.
# services.xserver.libinput.enable = true;
# Enable the KDE Desktop Environment.
# services.xserver.displayManager.sddm.enable = true;
# services.xserver.desktopManager.plasma5.enable = true;
# Define a user account. Don't forget to set a password with ‘passwd’.
# users.users.jane = {
# isNormalUser = true;
# extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
# };
# This value determines the NixOS release with which your system is to be
# compatible, in order to avoid breaking some software such as database
# servers. You should change this only after NixOS release notes say you
# should.
system.stateVersion = "19.09"; # Did you read the comment?
}
-
Enable ZFS
-
Prompt User for password to unencrypt root ZFS filesystem.
-
Put the network Id that we found in the Networking step
-
Enable auto snapshots for the home folder, that was a parameter we set when we created it. I added the comment to let you know these entries were related to ZFS.
-
Autoscrub will attempt to repair silent data corruption by checking the itengrity of all the stored data against the stored checksums.
Now save your edits in Nano by pressing Ctrl+O
It will ask to if you want to change the filename, so just press Enter
In the last section we edited the configuration.nix file for the entries needed for ZFS. I spit the two sections so you would’t be confused as to what edits were related to ZFS and which ones where just preference. In this section we will make some additional edits that will give us a better initial experience when we actually install and start to use the system. I also included some features that a beginner may not know about but may be useful, so many of these changes are optional.
Okay, so you should still have Nano open to the configuration.nix file. Lets make some additional edits, at the end your file should look like this:
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
];
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# Add ZFS support.
boot.supportedFilesystems = ["zfs"];
boot.zfs.requestEncryptionCredentials = true;
networking.hostId = "238330f5";
networking.hostName = "nixos"; # Define your hostname.
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
# Configure network proxy if necessary
# networking.proxy.default = "http://user:password@proxy:port/";
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
# Select internationalisation properties. //(1)
i18n = {
consoleFont = "Lat2-Terminus16";
consoleKeyMap = "us";
defaultLocale = "en_US.UTF-8";
};
# Set your time zone.
time.timeZone = "US/Eastern"; //(1)
fonts.fonts = with pkgs; [ //(2)
fira
fira-code
powerline-fonts
];
nixpkgs.config.allowUnfree = true; //(3)
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs; [ //(4)
# Commandline tools
coreutils
gitAndTools.gitFull
man
tree
wget
vim
mkpasswd
# GUI Apps
chromium
];
# Some programs need SUID wrappers, can be configured further or are
# started in user sessions.
# programs.mtr.enable = true;
# programs.gnupg.agent = { enable = true; enableSSHSupport = true; };
# List services that you want to enable:
# Enable the OpenSSH daemon.
# services.openssh.enable = true;
# ZFS services
services.zfs.autoSnapshot.enable = true;
services.zfs.autoScrub.enable = true;
# To use lorri for development
services.lorri.enable = true; //(5)
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
# Enable CUPS to print documents.
# services.printing.enable = true; //(6)
# Enable sound.
# sound.enable = true;
hardware.pulseaudio.enable = true; //(7)
# Tlp power managment
services.tlp.enable = true; //(8)
# Flatpak enable
services.flatpak.enable = true; //(9)
# Enable the X11 windowing system. //(10)
services.xserver.enable = true;
services.xserver.layout = "us";
# services.xserver.xkbOptions = "eurosign:e";
# Enable touchpad support.
services.xserver.libinput.enable = true; //(11)
# Enable the KDE Desktop Environment.
# services.xserver.displayManager.sddm.enable = true;
# services.xserver.desktopManager.plasma5.enable = true;
# Enable the Gnome desktop environment //(12)
services.xserver.displayManager.gdm.enable = true;
services.xserver.desktopManager.gnome3.enable = true;
# Define a user account. Don't forget to set a password with ‘passwd’.
# users.users.jane = {
# isNormalUser = true;
# extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
# };
# This value determines the NixOS release with which your system is to be
# compatible, in order to avoid breaking some software such as database
# servers. You should change this only after NixOS release notes say you
# should.
nix.gc.automatic = true; //(13)
nix.gc.dates = "03:15";
system.stateVersion = "19.09"; # Did you read the comment?
}
It goes without saying that you will first need to uncomment these sections:
-
Update international setting and timezone, and update according to your preferences.
-
This setting allows you to install additional fonts. I have included a few that are widely used for programming and add "bling" to your terminal.
-
This will allow you to install packages from the Nix repo that have an "unfree" license.
-
Add packages that you want to use. Make sure to include the mkpasswd because you will need it later. I didn’t add much so you may want to go to nix package search and add more.
-
Enable lorri if you want to do any development on Nixos. Watch video for more information.
-
Enable printing service.
-
Enable pulse audio
-
Optional: Add tlp power management service
-
Enable flatpak to download software which isn’t in the nixos repos. Browse Flathub for software here. This is sort of an escape hatch until you start to write your own nix packages and submit them for inclusion in the nix repo :).
-
Optional: Enable touchpad for laptop
-
Set desktop environment to Gnome. If you want KDE, then just uncomment that section. If you want XFCE then read the manual here.
-
Turn on automatic garbage collection and run everyday at 3:15am.
If you see any other options above that you need enable please feel free to do so. Next, we will setup the user after installation so we can created a hashed password to put in the configuration file.
Now lets install the system. If you receive any errors you will want to open up the configuration .nix file and correct any issues. Do your best to decipher the error message as it will usually try to give you a hint as to the issue along with a line number. Also, open nano with the "c" flag (nano -c …) so you can see the line number in the editor, this will help you get an idea where the error is in the file.
nixos-install
After it finishes installing, it will ask you for your root password, make sure you remember it! Now, remove the USB drive and type:
reboot
The system will reboot then prompt you to provide your password to the ZFS encrypted pool "rpool". Provide the password and the system will continue to the login screen. You don’t have a user yet, so you will have to login as root.
username = type "root" password = type the root password you entered in the nixos-install step
Now you should see a desktop environment, so lets setup a user.
To setup a user we will want to create a hashed password. To do this open up the terminal application. Next we will open the configuration file. This time we will use vim because it can get access to the shell, which we will need for the hasshedPassword. If you have never used vim before it can seem a little crazy becuase in order to actually type you must first press i. This put you in "insert mode"; to exit insert mode press esc.
vim /etc/nixos/configuration.nix
Make the user section look like mine below (other parts may not totally be in sync with the section above), but change the user "ben" to whatever you want your username to be:
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
];
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# Add ZFS support.
boot.supportedFilesystems = ["zfs"];
boot.zfs.requestEncryptionCredentials = true;
networking.hostId = "238330f5";
networking.hostName = "nixos"; # Define your hostname.
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
# Configure network proxy if necessary
# networking.proxy.default = "http://user:password@proxy:port/";
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
# Select internationalisation properties.
i18n = {
consoleFont = "Lat2-Terminus16";
consoleKeyMap = "us";
defaultLocale = "en_US.UTF-8";
};
# Set your time zone.
time.timeZone = "US/Eastern";
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs; [
# Commandline tools
coreutils
gitAndTools.gitFull
man
tree
wget
vim
mkpasswd
# GUI Apps
chromium
gnome3.gnome-tweaks
gnome3.dconf-editor
];
# Some programs need SUID wrappers, can be configured further or are
# started in user sessions.
# programs.mtr.enable = true;
# programs.gnupg.agent = { enable = true; enableSSHSupport = true; };
# List services that you want to enable:
# Enable the OpenSSH daemon.
# services.openssh.enable = true;
# ZFS services
services.zfs.autoSnapshot.enable = true;
services.zfs.autoScrub.enable = true;
# To use lori for development
services.lorri.enable = true;
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
# Enable CUPS to print documents.
# services.printing.enable = true;
# Enable sound.
# sound.enable = true;
hardware.pulseaudio.enable = true;
# Tlp power managment
services.tlp.enable = true;
# Flatpak enable
services.flatpak.enable = true;
# Enable the X11 windowing system.
services.xserver.enable = true;
services.xserver.layout = "us";
# services.xserver.xkbOptions = "eurosign:e";
# Enable touchpad support.
services.xserver.libinput.enable = true;
# Enable the KDE Desktop Environment.
# services.xserver.displayManager.sddm.enable = true;
# services.xserver.desktopManager.plasma5.enable = true;
# Enable the Gnome desktop environment
services.xserver.displayManager.gdm.enable = true;
services.xserver.desktopManager.gnome3.enable = true;
# Define a user account. Don't forget to set a password with ‘passwd’.
users.mutableUsers = false; //(1)
users.users.ben = { //(2)
isNormalUser = true;
extraGroups = [ "wheel" "video" "audio" "disk" "networkmanager"]; //(3)
hashedPassword = "$6$PG6zSaJ3kiXexR$wqSjTiGuV64lNIo5Hz6.X3BRQD2R124Kv4EwP1YeJRz0LwfLkLcShmVljeO8jDzYU/PZS5W3oQsxnwo/WeEKE."; //(4)
};
# This value determines the NixOS release with which your system is to be
# compatible, in order to avoid breaking some software such as database
# servers. You should change this only after NixOS release notes say you
# should.
system.stateVersion = "19.09"; # Did you read the comment?
}
-
Users will be defined in the configuration file only
-
Change the username, in this case "ben"
-
Add the user to groups.
-
Type hashedPassword = " (put your cursor after the quote character). Next, type esc to exit Vim’s insert mode, then : to bring up Vim’s command area. Type the command:
r! mkpasswd -m sha-512
Vim will prompt you to enter a password. It will only ask you once, so make sure you enter is correctly! Once you enter it the string should appear around your cursor within the editor itself. Make sure the hashed password is wrapped in quotes and the line ends with a semicolon. Also, make sure to uncomment the "#}" that ends the users block of code. A video demonstrating creating a hashed password can be found here
Now save the file by ensuring you are not in insert mode esc, then press : and execute the following command (write and quit):
wq
Now you should be back at the terminal prompt. Whenever you make a change to configuration.nix and it want it to be the default going forward, then issue this command:
nixos-rebuild switch
Now lets reboot and check it out:
reboot
Great!! At this point you have a system user.
One last consideration before you go offf and start adding software, is to determine if you want to use the stable or unstable branch. When you first install NixOS, you’re automatically subscribed to the NixOS channel that corresponds to your installation source. For instance, if you installed from a 19.09 ISO, you will be subscribed to the nixos-19.09 channel. This stable branch and is great if you are doing development work, but many times you want the most up to date software, similar to a rolling release linux distribution like Arch Linux. You can find additional information about channels in chapter 4 of the Nixos manual. For those that like the bleeding edge and want to subscribe to the unstable branch, issue this command:
sudo nix-channel --add https://nixos.org/channels/nixos-unstable nixos
To see which NixOS channel you’re subscribed to, run the following as root:
sudo nix-channel --list | grep nixos
However the change has still not taken effect. To do that you will need one last command:
sudo nixos-rebuild switch --upgrade
Now, when you reboot you will have a new system that will use the unstable branch.
We now should have a working Nixos system with a rocking ZFS file system. Now that you have system installed your configuration files will be located here:
/etc/nixos/configuration.nix
/etc/nixos/hardware-configuration.nix
I hope this guide helped you, and please let me know if any part was confusing so I can updated it to be more clear.