-
Choose an install method from the following README
-
This is a starter repo attempting to save you some time and effort. It is used for both encrypted and unencrypted setups so pay attention to paths etc.
-
If you run into any problems or run into problems open an issue and I'll try to get to it ASAP.
❗ There are 2
disk-config's, thedisk-config.nixis for an unencrypted setup anddisk-config2.nixis for encryption. Carefully review what's there to ensure you've chosen the correct one. If you choosedisk-config2.nix, uncomment theboot.initrdsetting in the includedconfiguration.nix.
Then set an environment variable for the experimental-features, this enables you
to use nix-shell -p to add packages:
export NIX_CONFIG='experimental-features = nix-command flakes'Add git and an editor of your choice and optionally yazi:
nix-shell -p git helix yazi
# This makes yazi open helix when opening a file instead of nano
export EDITOR='hx'
git config --global user.name "YourUsername"
git config --global user.email "YourGitEmail"After you've set up git clone the repo:
git clone https://github.com/saylesss88/my-flake.git-
After cloning this repo, change the
flake.nix,users.nix, andconfiguration.nixto your wanted hostname and user. -
Run
lsblkand make sure the device is correct indisk-config.nix. Change line #6,device = "/dev/nvme0n1"accordingly. Also, decide if you want a swapfile as defined, 2G over the size of your RAM is safe.
-
There have been some recent changes to this repo, giving the option of an unencrypted setup with
disk-config.nixand for an encrypted disk setup withdisk-config2.nix. The process is mainly the same, just with the added step of asking for your encryption passphrase when you format the disk with disko. -
Click here for Unencrypted Impermanence
-
Click here for Encrypted Impermanence
❗ Note: Impermanence is destructive by nature, it is very easy to mess up a single thing and break your system and have to start completely over. Be careful!
initialHashedPassword: Runmkpasswd --method=yescrypt > /tmp/pass.txt, then enter your desired password. Use a unique password here as they are susceptible to brute force attacks. Example output:
- Open the
users.nixor wherever you need the hashed password and move your cursor to the line where you need it and type:r /tmp/pass.txtto read it into your current file.
- Run the disko command:
❗ WARNING: This will wipe your whole disk! Disko doesn't work with dual boot. Also, ensure that you choose the correct
disk-config.nixordisk-config2.nix. This is very important!
# the following command is for an unencrypted disk
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode destroy,format,mount ~/my-flake/disk-config.nix
# OR the following for encryption
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode destroy,format,mount ~/my-flake/disk-config2.nix-
Check the output of
mount | grep /mntyou should see the subvolumes listed. -
Generate your configurations:
sudo nixos-generate-config --no-filesystems --root /mnt- Disko handles the
fileSystemsattribute for us. It's still important to generate your ownhardware-configuration.nixand replace the one that comes with the repo.
-
Add your
networking.hostName,git,vim, whatever else you want to yourconfiguration.nixand runsudo nixos-rebuild switchto apply them. -
Replace
my-flake'shardware-configuration.nixwith the/mnt/etc/nixos/hardware-configuration.nixthat you just generated.
rm ~/my-flake/hardware-configuration.nix
sudo mv /mnt/etc/nixos/hardware-configuration.nix ~/my-flake- Move the flake to
/mnt/etc/nixos/:
sudo mv ~/my-flake /mnt/etc/nixos/- Install NixOS replace #hostname with your hostname:
sudo nixos-install --flake /mnt/etc/nixos/my-flake#hostname
# or
sudo nixos-install --flake /mnt/etc/nixos/my-flake .#hostnameThis is essential if you plan on using impermanence with this encrypted setup.
We take a snapshot of /root while it's a clean slate, right after we run disko
to format the disk. I recommend following this for both setups, although we use
a different method for unencrypted impermanence this will give you more options.
To access all of the subvolumes, we have to mount the Btrfs partitions top-level.
- Unlock the LUKS device, if not already unlocked as it should be from running disko:
sudo cryptsetup open /dev/disk/by-partlabel/luks cryptroot- Mount the Btrfs top-level (
subvolid=5):
sudo mount -o subvolid=5 /dev/mapper/cryptroot /mnt- List the contents:
ls /mnt
# you should see something like
root home nix persist log lib ...- Now we can take a snapshot of the
rootsubvolume:
sudo btrfs subvolume snapshot -r /mnt/root /mnt/root-blank- Verify Your Blank Snapshot:
Before continuing, make sure your blank snapshot exists. This is crucial for impermanence to work properly.
sudo btrfs subvolume list /mntYou should see output containing both root and root-blank subvolumes:
ID 256 gen ... path root
ID 257 gen ... path root-blankCheck that the snapshot is read only, this ensures that our snapshot will remain
the same as the day we took it. It was set ro in disko but lets check anyways:
sudo btrfs property get -ts /mnt/root-blank
# output should be
ro=true- Make sure to unmount:
sudo umount /mntYou will be prompted to enter a new password and shown if the install was successful, if it was reboot.
After reboot the flake will be at /etc/nixos/my-flake. You can move it to your
home directory and then change the permissions:
sudo mv /etc/nixos/my-flake ~
sudo chown -R $USER:users ~/my-flakeOr you can clone an existing repo and just move the disk-config.nix and
hardware-configuration.nix into place.
⚠️ Pick the correct impermanence!
- The first rebuild after activating impermanence sometimes erases you from the password database. To prevent this you can run the following:
The following is a one time operation, copying all of your important files to a persistant location.
sudo mkdir -p /persist/etc
sudo mkdir -p /persist/var/lib
sudo mkdir -p /persist/var/log
sudo mkdir -p /persist/home
sudo mkdir -p /persist/root
sudo cp -a /etc/. /persist/etc/
sudo cp -a /var/lib/. /persist/var/lib
sudo cp -a /var/log/. /persist/var/log
sudo cp -a /home/. /persist/home/
sudo cp -a /root/. /persist/root/- For impermanence, uncomment the 2 lines in the
flake.nix. And the 1 line in theconfiguration.nixthat importsimpermanence.nix.
This is included in the repo, just shown here for clarity. Ensure to uncomment
the line ./impermanence.nix in the configuration.nix for the following
unencrypted impermanence setup:
{lib, ...}: {
# Reset root subvolume on boot
boot.initrd.postResumeCommands = lib.mkAfter ''
mkdir /btrfs_tmp
mount /dev/disk/by-partlabel/disk-main-root /btrfs_tmp # CONFIRM THIS IS CORRECT FROM findmnt
if [[ -e /btrfs_tmp/root ]]; then
mkdir -p /btrfs_tmp/old_roots
timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S")
mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp"
fi
delete_subvolume_recursively() {
IFS=$'\n'
for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do
delete_subvolume_recursively "/btrfs_tmp/$i"
done
btrfs subvolume delete "$1"
}
for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +30); do
delete_subvolume_recursively "$i"
done
btrfs subvolume create /btrfs_tmp/root
umount /btrfs_tmp
'';
# Use /persist as the persistence root, matching Disko's mountpoint
environment.persistence."/nix/persist" = {
hideMounts = true;
directories = [
"/etc" # System configuration (Keep this here for persistence via bind-mount)
"/var/spool" # Mail queues, cron jobs
"/srv" # Web server data, etc.
"/root"
];
files = [
];
};
}This is included with the repo, it's just included here for clarity. Ensure that
you uncomment the line ./impermanenceLUKS.nix for the following encrypted
impermanence setup:
This is a different way of doing things, where we take an initial snapshot of
the root subvolume before the install and reboot giving us a clean slate
to roll our system back to making it a bit more robust.
{
config,
lib,
...
}: {
boot.initrd.postDeviceCommands = lib.mkAfter ''
echo "Rollback running" > /mnt/rollback.log
mkdir -p /mnt
mount -t btrfs /dev/mapper/cryptroot /mnt
# Recursively delete all nested subvolumes inside /mnt/root
btrfs subvolume list -o /mnt/root | cut -f9 -d' ' | while read subvolume; do
echo "Deleting /$subvolume subvolume..." >> /mnt/rollback.log
btrfs subvolume delete "/mnt/$subvolume"
done
echo "Deleting /root subvolume..." >> /mnt/rollback.log
btrfs subvolume delete /mnt/root
echo "Restoring blank /root subvolume..." >> /mnt/rollback.log
btrfs subvolume snapshot /mnt/root-blank /mnt/root
umount /mnt
'';
environment.persistence."/persist" = {
directories = [
"/etc"
"/var/spool"
"/root"
"/srv"
"/etc/NetworkManager/system-connections"
"/var/lib/bluetooth"
];
files = [
# "/etc/machine-id"
# Add more files you want to persist
];
};
security.sudo.extraConfig = ''
Defaults lecture = never
'';
}Although, just adding the disk-config2.nix works for prompting you for your
encryption passphrase adding the following is a more robust way of ensuring Nix
is aware of this:
boot.initrd.luks.devices = {
cryptroot = {
device = "/dev/disk/by-partlabel/luks";
allowDiscards = true;
};
};- Apply the changes:
sudo nixos-rebuild switch --flake ~/my-flake- I recently did this and skipped the
cp -astep and it wouldn't even let me reboot from the command line. However after I force shut it down and booted back up, it regenerated the necessary files and rebuilt without an issue. - I recently did this and skipped the
cp -astep and it wouldn't even let me reboot from the command line. However after I force shut it down and booted back up, it regenerated the necessary files and rebuilt without an issue.