NixOs Native Flake Deployment With LUKS Drive Encryption and LVM
In this series of tutorials, I will not cover Nix or NixOS. You can probably find many tutorials with detailed descriptions of the advantages of using nix declarative, functional configuration management language.
I will tackle a specific problem I was trying to solve, and as a result, I can share and expand on potential options available.
Some time back, I was looking to reinstall my NixOS “that I was running for the past four years” with a new nix feature like a flake and make it more flexible from a storage management standpoint “using LVM” and to secure with full disk encryption “using LUKS.”
Flake
Flakes are a new feature in the Nix ecosystem. Flakes replace stateful channels and introduce a more intuitive and consistent CLI interface.
LVM
A Linux, Logical Volume Manager (LVM) is a device mapper framework that provides logical volume management for the Linux kernel. The main advantage is using LVM multiple Disk management becomes very easy, and adding new disk storage is a breeze. A good description for LVM you can find in Chris Titus Blog Post
LUKS
LUKS stands for ”Linux Unified Key Setup.” I will use cryptsetup to use to encrypt the entire disk using LUKS2. For more information on specifications for LUKS2
Before you start a good recommendation, use hypervisor VirtualBox or QEMU/KVM to get familiarised with the setup and available options. In the below example, I am using QEMU/KVM.
Installation
Prerequisites
Download latest NixOS ISO image Download min Minimal ISO image.
Make sure you have a git repository with all configuration files. In the below example, I will use my Github systst repository.
Setup Virtualization with QEMU/KVM
1st step is to create a Virtual Machine that will install NixOS using nix flakes.
Download min Minimal ISO image.
virt-install \
--name nixos \
--boot uefi \
--ram 8196 \
--vcpus 4 \
--network bridge:virbr0 \
--os-type linux \
--os-variant nixos-unstable \
--disk path=/var/lib/libvirt/images/nixos.qcow2,size=30 \
--console pty,target_type=serial \
--cdrom ~/Downloads/iso/nixos-minimal-21.05.1555.6b940846e99-x86_64-linux.iso
Note: Adjust
--cdrom
and-disk path
locations. Feel free to adjust--ram
and--vcpus
accommodate underlying hardware.
Hard Drive Preparation
Once VM is up and running, we will need to identify the drive NixOS will be installed on by running;
[nixos@nixos:~]$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 614.2M 1 loop /nix/.ro-store
sr0 11:0 1 661M 0 rom /iso
vda 253:0 0 30G 0 disk
Note: We will use vda disk that was provisioned with 30G of free storage.
Note: Good proactive to have a minimum of 20G of storage due to the nature of NixOS to create derivation for recovery.
Drive Partitioning
Once we know on what drive we will use, install nixos is time to create the necessary partitions. Will become root for easier access to the resources requiring root access.
[nixos@nixos:~]$ sudo -i
[root@nixos:~]# export ROOT_DISK=/dev/vda
[root@nixos:~]# parted -a opt --script "${ROOT_DISK}" \
mklabel gpt \
mkpart primary fat32 0% 512MiB \
mkpart primary 512MiB 100% \
set 1 esp on \
name 1 boot \
set 2 lvm on \
name 2 root
[root@nixos:~]# fdisk /dev/vda -l
fdisk /dev/vda -l
Disk /dev/vda: 30 GiB, 32212254720 bytes, 62914560 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 4E4E582E-8CC3-4901-93B4-3D8DD429FA7E
Device Start End Sectors Size Type
/dev/vda1 2048 1048575 1046528 511M EFI System
/dev/vda2 1048576 62912511 61863936 29.5G Linux LVM
Note: I am installing the nixos on UEFI partition type
fat32
with 512 Mib of the allocated storage. The rest of the storage is allocated for the root partition.
Note: Except partitioning the disk I labeled the partition/dev/vda1
asboot
and/dev/vda1
asroot
that will help us later in the system setup.
Partition Encryption
The next step is to encrypt the root partition. I will use cryptsetup
with luksFormat
.
[root@nixos:~]# cryptsetup luksFormat /dev/disk/by-partlabel/root
WARNING!
========
This will overwrite data on /dev/disk/by-partlabel/root irrevocably.
Are you sure? (Type 'yes' in capital letters): YES
Enter passphrase for /dev/disk/by-partlabel/root:
Verify passphrase:
Note: Make sure you use a secure password.
Open encrypted partition:
[root@nixos:~]# cryptsetup luksOpen /dev/disk/by-partlabel/root root
Enter passphrase for /dev/disk/by-partlabel/root:
Setting Up LVM
System readout of volumes and partitions:
[root@nixos:~]# lvmdiskscan
/dev/loop0 [ <614.18 MiB]
/dev/gpt-auto-root [ 29.48 GiB]
/dev/vda1 [ 511.00 MiB]
/dev/vda2 [ <29.50 GiB]
1 disk
3 partitions
0 LVM physical volume whole disks
0 LVM physical volumes
Create a physical volume from /dev/mapper/root
that is mapped to /dev/vda2
:
[root@nixos:~]# pvcreate /dev/mapper/root
Physical volume "/dev/mapper/root" successfully created.
Create a volume group from /dev/mapper/root
:
[root@nixos:~]# vgcreate vg /dev/mapper/root
Volume group "vg" successfully created
Create a 4 GB logical volume on volume group vg
that will be used for swap partition:
[root@nixos:~]# lvcreate -L 4G -n swap vg
Logical volume "swap" created.
Create a logical volume on the volume group vg
using all the rest of the storage space that will be used for the root partition:
[root@nixos:~]# lvcreate -l '100%FREE' -n root vg
Logical volume "root" created.
View volumes and partitions created:
[root@nixos:~]# lvdisplay
--- Logical volume ---
LV Path /dev/vg/swap
LV Name swap
VG Name vg
LV UUID BEZroA-bKry-jAz2-dW2v-jQDY-uqUB-bIdJQa
LV Write Access read/write
LV Creation host, time nixos, 2021-07-20 14:44:52 +0000
LV Status available
# open 0
LV Size 4.00 GiB
Current LE 1024
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 254:1
--- Logical volume ---
LV Path /dev/vg/root
LV Name root
VG Name vg
LV UUID KJHdcu-CLvf-saWV-Kp3r-qSTw-HcMg-7SePkt
LV Write Access read/write
LV Creation host, time nixos, 2021-07-20 14:46:11 +0000
LV Status available
# open 0
LV Size 25.48 GiB
Current LE 6523
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 254:2
Partition Formatting
Formatting the boot
partition with FAT32:
[root@nixos:~]# mkfs.fat -F 32 -n boot /dev/disk/by-partlabel/boot
mkfs.fat 4.1 (2017-01-24)
mkfs.fat: warning - lowercase labels might not work properly with DOS or Windows
Formatting the root
partition with EXT4 file system:
[root@nixos:~]# mkfs.ext4 -L root /dev/vg/root
mke2fs 1.46.2 (28-Feb-2021)
Creating filesystem with 6679552 4k blocks and 1671168 inodes
Filesystem UUID: e78f4a6b-5d85-458a-9757-f722d657c091
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000
Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
Formatting the swap
partition:
[root@nixos:~]# mkswap -L swap /dev/vg/swap
Setting up swapspace version 1, size = 4 GiB (4294963200 bytes)
LABEL=swap, UUID=3feeb8e9-9843-401b-93dc-128047b8c08b
Mounting Newly Created Partitions and Swap Activation
[root@nixos:~]# mount /dev/disk/by-label/root /mnt
[root@nixos:~]# mkdir -p /mnt/boot
[root@nixos:~]# mount /dev/disk/by-label/boot /mnt/boot
[root@nixos:~]# swapon /dev/vg/swap
[root@nixos:~]# swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 4194300 0 -2
NixOS Installation Options
We have a few available options to use nix flakes.
Base Example
Bellow, you can find the most basic example where you can use flake and ingest configuration.nix
as a module.
{
description = "NixOS configuration";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-21.05";
};
outputs = { nixpkgs, ... }: {
nixosConfigurations = {
nixtst = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./configuration.nix
];
};
};
};
}
Home Manager Integration
If you are a single user for underlying hardware and want to have a single management workspace, you can integrate the system config with the home manager config under the same nix flake.
{
description = "NixOS configuration and Home Manager configuration";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-21.05";
home-manager.url = "github:nix-community/home-manager";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = { home-manager, nixpkgs, ... }: {
nixosConfigurations = {
nixtst = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./configuration.nix
home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.mudrii = import ./users/$USER/home.nix;
}
];
};
};
};
}
Full Flake Integration
Another option is to get rid of configuration.nix and add all entries into flake.nix.
{
description = "NixOS configuration";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-21.05";
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs = { nixpkgs, nixpkgs-unstable, ... }: {
nixosConfigurations = {
nixtst = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
({ config, pkgs, ... }:
let
overlay-unstable = final: prev: {
unstable = nixpkgs-unstable.legacyPackages.x86_64-linux;
};
in
{
imports =
[ ./hardware-configuration.nix ];
fileSystems."/" = { options = [ "noatime" "nodiratime" ]; };
boot = {
kernelPackages = pkgs.linuxPackages_latest;
loader = {
efi.canTouchEfiVariables = true;
grub = {
enable = true;
version = 2;
efiSupport = true;
enableCryptodisk = true;
device = "nodev";
};
};
initrd.luks.devices = {
crypt = {
device = "/dev/vda2";
preLVM = true;
};
};
};
time.timeZone = "Asia/Singapore";
networking = {
useDHCP = false;
interfaces.enp1s0.useDHCP = true;
hostName = "nixtst"; # Define your hostname.
};
security = {
sudo = {
enable = true;
wheelNeedsPassword = false;
};
};
...
..
.
Note: Full example can be found here.
Mix and Match
In the below example, I am using a combination of available options.
The reason is to have a structure to allow for multi-user support. Some users may not have root access but should manage the user packages using a separate implementation of the Home Manager that will cover in a separate tutorial.
{
description = "NixOS configuration";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-21.05";
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs = { nixpkgs, nixpkgs-unstable, ... }: {
nixosConfigurations = {
nixtst = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
({ config, pkgs, ... }:
let
overlay-unstable = final: prev: {
unstable = nixpkgs-unstable.legacyPackages.x86_64-linux;
};
in
{
nixpkgs.overlays = [ overlay-unstable ];
imports =
[
./hardware-configuration.nix
./configuration.nix
./packages.nix
./users/admin_users.nix
./users/dev_users.nix
];
}
)
];
};
};
};
}
Note: I added nixpkgs.overlays to allow some packages to be installed selected from the unstable branch.
*.nix Dissected
hardware-configuration.nix
The only change in hardware-configuration.nix is the device from by-uuid to by-label that adds portability and adds swap device to the mix.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[
(modulesPath + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "sr_mod" "virtio_blk" ];
boot.initrd.kernelModules = [ "dm-snapshot" ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" = {
device = "/dev/disk/by-label/root";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-label/boot";
fsType = "vfat";
};
swapDevices =
[{ device = "/dev/disk/by-label/swap"; }];
nix.maxJobs = lib.mkDefault 4;
}
configuration.nix
fileSystems
fileSystems SSD optimization for EXT4:
fileSystems."/" = { options = [ "noatime" "nodiratime" ]; };
boot.loader
Adding latest Linux kernel with kernelPackages = pkgs.linuxPackages_latest;
.
Allowing grub support for UEFI and LUKS encryption.
boot = {
kernelPackages = pkgs.linuxPackages_latest;
loader = {
efi.canTouchEfiVariables = true;
grub = {
enable = true;
version = 2;
efiSupport = true;
enableCryptodisk = true;
device = "nodev";
};
};
initrd.luks.devices = {
crypt = {
device = "/dev/vda2";
preLVM = true;
};
};
};
networking
Please change to your desired hostname and correct the interface name.
networking = {
useDHCP = false;
interfaces.enp1s0.useDHCP = true; # Add correct network interface name to find out run "ip a"
hostName = "nixtst"; # Define your hostname.
};
console
and fonts
I am adding default system-wide encoding and adding additional fonts, useful for the modern shell.
i18n = {
defaultLocale = "en_US.UTF-8";
supportedLocales = [ "en_US.UTF-8/UTF-8" ];
};
console = {
font = "Lat2-Terminus16";
keyMap = "us";
};
fonts = {
fontDir.enable = true;
enableGhostscriptFonts = true;
fonts = with pkgs; [
powerline-fonts
nerdfonts
];
};
services
We are enabling ssh on port 2022 but disabling root login and password authentication.
services = {
openssh = {
enable = true;
permitRootLogin = "no";
passwordAuthentication = false;
ports = [2022];
};
};
virtualisation
Adding docker as an example:
virtualisation = {
docker = {
enable = true;
autoPrune.enable = true;
enableOnBoot = true;
};
};
nix
Optimizations
Allowing unfree allowUnfree = true;
packages like Nvidia drivers etc.
Make nix compatible with flakes pkgs.nixFlakes;
.
Garbage collection and optimization gc
and optimise
.
nixpkgs = {
config = {
allowBroken = true;
allowUnfree = true;
};
};
nix = {
package = pkgs.nixFlakes;
useSandbox = true;
autoOptimiseStore = true;
readOnlyStore = false;
allowedUsers = [ "@wheel" ];
trustedUsers = [ "@wheel" ];
extraOptions = ''
experimental-features = nix-command flakes
keep-outputs = true
keep-derivations = true
'';
gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 7d --max-freed $((64 * 1024**3))";
};
optimise = {
automatic = true;
dates = [ "weekly" ];
};
};
system
Configure system auto-update compatible with flakes you will need to change Github repo to point to your repo location.
system = {
stateVersion = "21.05"; # Did you read the comment?
autoUpgrade = {
enable = true;
allowReboot = true;
flake = "github:mudrii/systst";
flags = [
"--recreate-lock-file"
"--no-write-lock-file"
"-L" # print build logs
];
dates = "daily";
};
};
Note: Complete content of the configuration.nix file can be found in Github.
packages.nix
System-Wide Packages
With environment.systemPackages
we specify packages that will be installed for all users.
systemPackages = with pkgs; [
git
gh
kubernetes
kubernetes-helm
kubeseal
helmfile
helmsman
unstable.kind
kube3d
argo
argocd
kustomize
k9s
kubectx
binutils
gnutls
wget
curl
bind
mkpasswd
direnv
nix-direnv
];
shellAliases
We can specify system-wide shell aliases for all users.
shellAliases = {
cp = "cp -i";
diff = "diff --color=auto";
dmesg = "dmesg --color=always | lless";
egrep = "egrep --color=auto";
fgrep = "fgrep --color=auto";
grep = "grep --color=auto";
mv = "mv -i";
ping = "ping -c3";
ps = "ps -ef";
sudo = "sudo -i";
vdir = "vdir --color=auto";
};
programs
We specify native nix application to be installed and/or enable/disable. We can add package-specific configurations for all users like nano editor.
programs = {
ssh.startAgent = false;
vim.defaultEditor = true;
fish.enable = true;
nano.nanorc = ''
unset backup
set nonewlines
set nowrap
set tabstospaces
set tabsize 4
set constantshow
'';
};
users
To manage multiple users, I decided to segregate admin users having root access with non-admin users. The only difference is in the wheel
group allocation.
You can specify packages that will install only for the user and add ssh public keys and generate the password.
users = {
mutableUsers = false;
users.mudrii = {
isNormalUser = true;
extraGroups = [ "wheel" "docker" ];
shell = pkgs.fish;
# mkpasswd -m sha-512 password
hashedPassword = "$6$ewXNcoQRNG$czTic9vE8CGH.eo4mabZsHVRdmTjtJF4SdDnIK0O/4STgzB5T2nD3Co.dRpVS3/uDD24YUxWrTDy2KRv7m/3N1";
openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8/tE2+oIwLnCnfzPSTqiZaeW++wUPNW5fOi124eGzWfcnOQGrjuwir3sZDKMS9DLqSTDNtvJ3/EZf6z/MLN/uxUE8lA+aKaSs0yopE7csQ89Aqkvp5fvCpz3BJuZgpxtwebPZyTc7QRGQWE4lM3fix3aJhfj827bdxA+sCiq8OnNiwYSXrIag1cQigafhLy6tYtCKdWcxzJq2ebGJF2wu2LU0zArb1SAOanhEOXxz0dG1I/7yMDBDC92R287nWpL+BwxuQcDv0xh/sWnViKixKv+B9ewJnz98iQPcg3WmYWe9BYAcaqkbgMqbwfUPqOHhFXmiQWUpOjsni2O6VoiN mudrii@nixos" ];
packages = with pkgs; [
python39Full
(
python39.withPackages (
ps: with ps; [
#poetry
pip
powerline
pygments
pygments-markdown-lexer
xstatic-pygments
pylint
numpy
pynvim
]
)
)
];
};
};
Prerequisites
Before starting the installation, we need to use git nf Flakes that we cat use nix-shell that allows us to use binaries that are not installed in the system.
[root@nixos:~]# nix-shell -p git nixFlakes
these paths will be fetched (12.56 MiB download, 75.48 MiB unpacked):
/nix/store/0f92b8kgaki9s5rwdj81pni3wj7ca8k6-git-2.31.1-doc
/nix/store/39j27lcvm8sn17k4589v7kxwic58qgsg-libcpuid-0.5.1
/nix/store/3bk9dhdkzg11qm9g1zkv7vxqkvcaqnp6-lowdown-0.8.4-lib
/nix/store/3ghvl0b0bd0pmrkczciy1i9gzlmi47mp-perl5.32.1-CGI-Fast-2.15
/nix/store/47qr4rksqfi8kgc3kwjvrjy9ym1bj89g-gettext-0.21
/nix/store/54dmlydl9lwvrmjjcgf5xrsydhnvasd0-nix-2.4pre20210601_5985b8b
/nix/store/8sxrh4g1zan8lriwfqzw6iimqcaj4asi-perl5.32.1-CGI-4.51
/nix/store/a95f72avd2r70w1rszb6mvyiabydr2nc-perl5.32.1-FCGI-0.79
/nix/store/b9bisjs01ijfw60g8qjk59v843bkldbx-nlohmann_json-3.9.1
/nix/store/c3vb6fvq802hckzz8xrgc6ja39k51af4-git-2.31.1
/nix/store/ln6mp01fyp2dlxfihrnj64js699yzvvn-boehm-gc-8.0.4-dev
/nix/store/p1m2imc7xbp5lf9298v2yndb3gqcr4la-libarchive-3.5.1-lib
/nix/store/p4qkqk2rxcyxfhyv6gzj7inc388azgli-perl5.32.1-HTML-TagCloud-0.38
/nix/store/ppwys502zs735azzksgs5wdya4rar626-nix-2.4pre20210601_5985b8b-dev
/nix/store/qima3mpp9bb5gnarr5z1dw7zvlaj0r8d-nix-2.4pre20210601_5985b8b-man
/nix/store/wzach25vwapl3sa6f7gylqank3jhhsin-bash-interactive-4.4-p23-dev
/nix/store/x24qskawy3d4mj2vqpl0hr5pdhpa8d6i-perl5.32.1-FCGI-ProcManager-0.28
/nix/store/zqf5dhf2pr6sxfgdpbq7gs1ajzknv2hm-perl5.32.1-TermReadKey-2.38
copying path '/nix/store/0f92b8kgaki9s5rwdj81pni3wj7ca8k6-git-2.31.1-doc' from 'https://cache.nixos.org'...
copying path '/nix/store/x24qskawy3d4mj2vqpl0hr5pdhpa8d6i-perl5.32.1-FCGI-ProcManager-0.28' from 'https://cache.nixos.org'...
copying path '/nix/store/p4qkqk2rxcyxfhyv6gzj7inc388azgli-perl5.32.1-HTML-TagCloud-0.38' from 'https://cache.nixos.org'...
copying path '/nix/store/wzach25vwapl3sa6f7gylqank3jhhsin-bash-interactive-4.4-p23-dev' from 'https://cache.nixos.org'...
copying path '/nix/store/ln6mp01fyp2dlxfihrnj64js699yzvvn-boehm-gc-8.0.4-dev' from 'https://cache.nixos.org'...
copying path '/nix/store/47qr4rksqfi8kgc3kwjvrjy9ym1bj89g-gettext-0.21' from 'https://cache.nixos.org'...
copying path '/nix/store/p1m2imc7xbp5lf9298v2yndb3gqcr4la-libarchive-3.5.1-lib' from 'https://cache.nixos.org'...
copying path '/nix/store/39j27lcvm8sn17k4589v7kxwic58qgsg-libcpuid-0.5.1' from 'https://cache.nixos.org'...
copying path '/nix/store/3bk9dhdkzg11qm9g1zkv7vxqkvcaqnp6-lowdown-0.8.4-lib' from 'https://cache.nixos.org'...
copying path '/nix/store/qima3mpp9bb5gnarr5z1dw7zvlaj0r8d-nix-2.4pre20210601_5985b8b-man' from 'https://cache.nixos.org'...
copying path '/nix/store/b9bisjs01ijfw60g8qjk59v843bkldbx-nlohmann_json-3.9.1' from 'https://cache.nixos.org'...
copying path '/nix/store/8sxrh4g1zan8lriwfqzw6iimqcaj4asi-perl5.32.1-CGI-4.51' from 'https://cache.nixos.org'...
copying path '/nix/store/a95f72avd2r70w1rszb6mvyiabydr2nc-perl5.32.1-FCGI-0.79' from 'https://cache.nixos.org'...
copying path '/nix/store/zqf5dhf2pr6sxfgdpbq7gs1ajzknv2hm-perl5.32.1-TermReadKey-2.38' from 'https://cache.nixos.org'...
copying path '/nix/store/3ghvl0b0bd0pmrkczciy1i9gzlmi47mp-perl5.32.1-CGI-Fast-2.15' from 'https://cache.nixos.org'...
copying path '/nix/store/c3vb6fvq802hckzz8xrgc6ja39k51af4-git-2.31.1' from 'https://cache.nixos.org'...
copying path '/nix/store/54dmlydl9lwvrmjjcgf5xrsydhnvasd0-nix-2.4pre20210601_5985b8b' from 'https://cache.nixos.org'...
copying path '/nix/store/ppwys502zs735azzksgs5wdya4rar626-nix-2.4pre20210601_5985b8b-dev' from 'https://cache.nixos.org'...
Repo Clone
Now we can clone the repository where we have out configuration files needed for the nixos flake installation.
[nix-shell:~]# git clone https://github.com/mudrii/systst.git /mnt/etc/nixos
Cloning into '/mnt/etc/nixos'...
remote: Enumerating objects: 229, done.
remote: Counting objects: 100% (229/229), done.
remote: Compressing objects: 100% (160/160), done.
remote: Total 229 (delta 127), reused 149 (delta 57), pack-reused 0
Receiving objects: 100% (229/229), 67.03 KiB | 4.47 MiB/s, done.
Resolving deltas: 100% (127/127), done.
NixOs Flake Installation
The nixos-install
script supports native NixOS Flake installation.
[nix-shell:~]# nixos-install --root /mnt --flake /mnt/etc/nixos#nixtst
building the flake in git+file:///mnt/etc/nixos?ref=master&rev=72a8edfd9d6bea0a314d561cdc15c4d72d8b9fb6...
copying channel...
installing the boot loader...
setting up /etc...
/etc/tmpfiles.d/journal-nocow.conf:26: Failed to resolve specifier: uninitialized /etc detected, skipping
All rules containing unresolvable specifiers will be skipped.
updating GRUB 2 menu...
installing the GRUB 2 EFI boot loader into /boot...
Installing for x86_64-efi platform.
/nix/store/gsf4bnf0pg5k8pyzbprx5l26gnq9w93n-grub-2.06-rc1/sbin/grub-install: warning: cannot open directory `/nix/store/gsf4bnf0pg5k8pyzbprx5l26gnq9w93n-grub-2.06-rc1/share/locale': No such file or directory.
Installation finished. No error reported.
setting up /etc...
/etc/tmpfiles.d/journal-nocow.conf:26: Failed to resolve specifier: uninitialized /etc detected, skipping
All rules containing unresolvable specifiers will be skipped.
setting up /etc...
/etc/tmpfiles.d/journal-nocow.conf:26: Failed to resolve specifier: uninitialized /etc detected, skipping
All rules containing unresolvable specifiers will be skipped.
setting root password...
New password:
Retype new password:
passwd: password updated successfully
installation finished!
Post-Installation
Once installation is completed, we can reboot the OS and log in as a user we declared in our configuration files.
[nix-shell:~]# reboot
System Update and Management
Once we have our system up and running is a good practice to keep the system up to date.
System update requires a two-step process:
- Flake update to lock the flake on the latest GitHub commit.
- nix rebuild switches to update the system.
Following the below steps will keep your system up to date:
mudrii@nixtst ~> sudo nix flake update /etc/nixos/
warning: updating lock file '/etc/nixos/flake.lock':
* Updated 'nixpkgs': 'github:nixos/nixpkgs/4181644d09b96af0f92c2f025d3463f9d19c7790' -> 'github:nixos/nixpkgs/63ee5cd99a2e193d5e4c879feb9683ddec23fa03'
* Updated 'nixpkgs-unstable': 'github:NixOS/nixpkgs/967d40bec14be87262b21ab901dbace23b7365db' -> 'github:NixOS/nixpkgs/16105403bdd843540cbef9c63fc0f16c1c6eaa70'
warning: Git tree '/etc/nixos' is dirty
mudrii@nixtst ~> sudo nixos-rebuild switch --flake /etc/nixos/#nixtst
warning: Git tree '/etc/nixos' is dirty
building the system configuration...
warning: Git tree '/etc/nixos' is dirty
updating GRUB 2 menu...
NOT restarting the following changed units: systemd-fsck@dev-disk-by\x2dlabel-boot.service
activating the configuration...
setting up /etc...
reloading user units for mudrii...
setting up tmpfiles
reloading the following units: dbus.service
In the follow-up tutorial, we will cover home manager installation and configuration using native flake implementation.