What is NixOS?#
Reference: Wikipedia, NixOS Homepage
Nix is a tool that uses a unique approach to package management and system configuration. It enables the creation of reproducible, declarative, and reliable systems.
NixOS is a Linux distribution built on top of the Nix package manager. It uses declarative configuration and allows for reliable system upgrades. Nix provides several official software package "channels," including the current stable version and an unstable version that follows the latest developments. NixOS has tools specifically designed for DevOps and deployment tasks.
Why NixOS?#
Now, let's say you have a requirement: you want to test a project on a local test server and then deploy it on a cloud server (e.g., AWS) after testing. How can you ensure that your tests are valid?
In other words, how can you ensure that the environments of the two servers are consistent? You might think of using Docker, but the downside of Docker is that its images are immutable, and updating an image requires rebuilding it, which can be cumbersome. So, is there a way to maintain environment consistency without sacrificing flexibility? The answer is NixOS.
The package manager of NixOS is quite special. It is declarative, and all packages are located in /etc/nixos/configuration.nix
, where you can declare the packages you need and then run nixos-rebuild switch
to install them. If you want to maintain environment consistency, you just need to copy /etc/nixos/configuration.nix
to another server and then run nixos-rebuild switch
.
Using NixOS to deploy open-source projects is a good exercise for DevOps. This article introduces how to install a minimal NixOS for servers.
Preparation#
Since it is a server, a desktop environment will not be used, so we will use the minimal version of NixOS. The download link for the NixOS image is available at https://nixos.org/download.html.
The author's test server uses ESXi (ESX) as the virtualization platform, and the NixOS version used is 22.11
.
The virtual machine is configured as follows:
- CPU: 4vCPU (EPYC 7302)
- RAM: 8GB
- Disk: 50GB (HDD)
- UEFI boot
Installation#
The installation of the minimal image does not have a graphical interface, only a command-line interface, which may be a bit challenging for Linux beginners. However, as long as you follow the steps below, there shouldn't be too many problems.
Power on the virtual machine, enter the UEFI interface, select NixOS 22.11.4426 Installer
(default option), and enter the installation environment.
Due to version differences, it may vary.
If everything goes smoothly, you should enter the command-line interface after <<< NixOS Stage 1 >>>
and <<< NixOS Stage 2 >>>
.
Enter sudo su
to switch to the root user for subsequent operations.
Partitioning#
Enter cfdisk
to enter the partitioning interface and partition according to the following scheme:
- Use GPT partition table.
- First, create a
/boot
partition with a size of at least512MB
and a file system ofEFI System
. - If the memory is small, create a swap partition with a size twice that of the memory and a file system of
Linux swap
. - Create a
/
partition using the remaining space and a file system ofLinux filesystem
.
The first partition must be
EFI System
because NixOS requires an EFI partition for booting.
Here is an example of partitioning:
After partitioning, be sure to Write and then Quit, otherwise the partitioning will not take effect.
You can use the lsblk
command to check the partitioning.
Next, format the partitions.
mkfs.ext4 -L nixos /dev/sda3
: Format the/
partition and give it a label for easier operations.- If there is a swap partition, use the command
mkswap -L swap /dev/sda2
to format the swap partition. mkfs.fat -F 32 -n boot /dev/sda1
: Format the/boot
partition.
Note: The above partitioning is for the author's partitioning. If your partitioning is different, modify the partition numbers in the commands accordingly.
Next, mount the partitions.
mount /dev/disk/by-label/nixos /mnt
mkdir -p /mnt/boot
mount /dev/disk/by-label/boot /mnt/boot
swapon /dev/sda2
Enter lsblk
, and you should see output similar to the following:
Generate Files#
Next, generate the NixOS configuration file.
nixos-generate-config --root /mnt
Now, enter nixos-install
to start the installation.
The installation process requires an internet connection, so make sure the network is working properly. The expected duration of the installation process is 5-10 minutes, depending on factors such as network speed and CPU performance.
In the final step of the installation process, you will be prompted to enter a root password. After entering the password, the installation process will be completed.
Enter reboot
to restart the system and then remove the installation media.
(Temporary) Add User#
After the restart, you will enter the command-line interface. Log in as the root user using the password you set earlier.
nixos login: root
password:
When entering the password, no characters will be displayed, which is normal.
It is recommended to create a new user for everyday operations, as the root user should only be used for system administration.
Using a non-root user is a good practice to avoid security risks and destructive mistakes.
However, the operations shown here are not the best practices for NixOS because NixOS's user management is declarative and users should not be created on the command line.
Please refer to the next section for the correct approach to adding a user to the sudoers list.
useradd -c 'admin' -m nk
passwd sh # Set the password
The parameters of the
useradd
command are as follows:
-c
: User's comment
-m
: Create the user's home directory
nk
: Username (can be customized)
Now, you can use the exit
command to exit the root user and then log in with the new user.
nk
is the username. If your username is notnk
, please modify it.
Finally, enter uname -a
, and you should see output similar to the following:
Linux nixos 5.15.133 #1-NixOS SMP Wed May 24 16:36:55 UTC 2023 x86_64 GNU/Linux
If the kernel version you see is not
5.15.133
, don't panic. This is because the NixOS kernel is dynamically generated, and a new kernel is generated with each installation.
Add User to Sudoers List#
To facilitate operations, add the new user to the sudoers list. You might think of modifying the sudoers list, but in NixOS, there is no need to modify the sudoers list. You just need to add the user to the wheel
group. In NixOS, the correct way to do this is by modifying the /etc/nixos/configuration.nix
file.
You might want to use vim to modify the configuration file, but NixOS does not have vim installed by default (otherwise, why would you want to install it?), so you need to temporarily install vim using
nix-shell -p vim
. More about package management will be discussed later.
Here are the specific steps:
-
Find the
users.users
field in the configuration file (in the minimal installation configuration file, this field is commented out). -
Create a new user, such as
nk
, and add them to thewheel
group. Write the following configuration:
users.users.nk = {
isNormalUser = true;
extraGroups = [ "wheel" ];
};
- Save the configuration file and then execute the
nixos-rebuild switch
command to make the configuration take effect.
Remember to use the
passwd
command to set the password for the new user.
Installation of Common Tools#
The uniqueness of NixOS lies in the peculiarity of its package manager. We need to have a basic understanding of the NixOS package manager before proceeding.
NixOS has three ways of installing packages:
nix-env
: Installs packages to the user directory, only effective for the current user.nix-shell
: Temporarily installs packages, only effective for the current shell.- Modifying
.nix
configuration files: Installs packages to the system directory, effective for all users.
Using nix-env
as you would use apt
has some drawbacks:
- Dependency resolution issues: The
nix-env
command attempts to automatically resolve package dependencies and install them. However, this automatic resolution can lead to inconsistent or unpredictable results. - Loss of environment isolation and version management: Manually managing package environments using the
nix-env
command can lead to environment confusion or conflicts. - Loss of shareability and reproducibility: Managing packages using the
nix-env
command may not be as explicit and readable. Configuration files can contain more detailed documentation and comments, allowing for better recording and sharing of package environment information.
Considering the purpose of using NixOS, the preferred method is to modify the .nix
configuration file.
Installing by Modifying the Configuration File#
As a server, it is obvious that most people will need to install the following software:
- openssh
- vim
- wget
- curl
Find the environment.systemPackages
field in the default NixOS configuration file and add the above packages to it. Make the following modifications:
You might want to use vim to modify the configuration file, but NixOS does not have vim installed by default (otherwise, why would you want to install it?), so you need to temporarily install vim using
nix-shell -p vim
.
Add the following content to the environment.systemPackages
field:
environment.systemPackages = with pkgs; [
vim
wget
curl
openssh
];
This part is commented out by default, so you need to uncomment it and add the content mentioned above.
environment.systemPackages = with pkgs;
is the default syntax and should not be modified.
This way, all the software packages except openssh will be installed. The installation of openssh is a bit more complicated and requires further modification of the configuration file.
Configuring openssh#
Add the following content to the services.openssh
field:
This part is not included in the minimal installation of NixOS, so you need to add it yourself.
services.openssh = {
enable = true;
permitRootLogin = "no"; // Optional: Disable root user login
passwordAuthentication = true; // Optional: Enable password authentication
};
After saving the configuration file, execute the nixos-rebuild switch
command to make the configuration take effect.
You can run the following command to check the status of openssh:
sudo systemctl status sshd
If the SSH service is running, you should see its status as "active".
Considering that this configuration file may be needed in the future, it has been placed on IPFS for the author and readers to use.
[Download Link for the Final Configuration File](https://ipfs.io/ipfs/bafybeih4viwvdlbcndpieybhjeq6nxaafagubycn64rhex7pb3hvb63spi/