Beware that, when fighting monsters, you yourself do not become a monster… for when you gaze long into the abyss. The abyss gazes also into you, Friedrich W. Nietzsche
NixOS is a unique, innovative, and powerful Linux distribution that leverages the Nix package manager. Unlike traditional Linux distributions that update packages and system configurations in-place, NixOS uses a purely functional and declarative approach to define the system state, reducing the risk of system breakage.
NixOS is a Linux distribution that uses the Nix package manager to handle packages and system configuration in a purely functional manner. This approach ensures that builds are reproducible and that the system state can be reliably replicated or rolled back.
sudo nix-env ‐‐rollback is a command used to revert your system to the previous configuration. It’s a powerful tool for undoing unintended changes or recovering from failed package installations. Before rolling back, consider if there’s a more targeted solution, like uninstalling specific packages or reverting configuration files.
NixOS uses a declarative approach to manage system configurations, including filesystem mounts. This means you describe what you want the system to look like (e.g., drive X should be mounted at /mnt/data) rather than specifying the exact steps to achieve it (e.g., editing /etc/fstab and running mount -a).
Step 1. Identify UUIDs:
Using UUIDs (Universally Unique Identifiers) is the recommended approach since device names (/dev/sda, /dev/sdb) can change unpredictably between boots, but UUIDs remain consistent.
Run one of the following commands to list your storage devices and partitions along with their UUIDs:
your-user@nixos ~ % sudo fdisk -l or sudo blkid
Disk /dev/nvme0n1: 931,51 GiB, 1000204886016 bytes, 1953525168 sectors
[...]
# Example output (abbreviated):
Disk /dev/sda: 2,73 TiB, 3000592982016 bytes, 5860533168 sectors
Disk model: ST3000DM001-1ER1
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: E4F99EAD-36E4-4776-9C46-BFCD94A9BC78
[...]
Disk /dev/sdb: 1,82 TiB, 2000365289472 bytes, 3906963456 sectors
Disk model: Elements 2620
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: 83BDC65F-6ECB-4D07-8ED3-1B943B6B882E
We can identify the UUIDs (hard drive partitions on Linux systems rely on a UUID, universally unique identifier, for unique labeling), for the partitions:
Step 2: Create Mount Points. Before editing your NixOS configuration, create the directories where these partitions will be mounted: sudo mkdir -p /mnt/mydisk2, sudo mkdir -p /mnt/mydisk
Step 3. Edit configuration.nix. Add entries for each filesystem you want to mount in your NixOS configuration file.
fileSystems."/run/media/your-user/mydisk2" = {
device = "/dev/disk/by-uuid/cb8ee0c2-6afe-4853-ae39-0cc1dce73ef0";
# Using UUIDs ensures that the correct partition is mounted, even if the device names is changed later on.
fsType = "ext4"; # The ext4 or fourth extended filesystem is a widely-used file system for Linux.
options = [ "x-systemd.automount" "nofail" ];
};
fileSystems."/run/media/your-user/mydisk" = {
device = "/dev/disk/by-uuid/bd753b26-a4ec-4063-8d36-5215c358ed00";
fsType = "ext4";
options = [ "x-systemd.automount" "nofail" ];
};
Step 4. Rebuild NixOS. Apply the changes by rebuilding your NixOS configuration: sudo nixos-rebuild switch
.
BorgBackup is a deduplicating (a technique for eliminating duplicate copies of repeating data) authenticated, and compressing backup solution for various Unix-like operating systems.
Step 1: Install BorgBackup: sudo vim /etc/nixos/configuration.nix:
environment.systemPackages = with pkgs; [
# Add borgbackup to your system packages
borgbackup
];
Rebuild your NixOS Configuration to apply changes: sudo nixos-rebuild switch
.
Step 2: Prepare the Backup Repository.
ls /run/media/your-user/mydisk2
mkdir /run/media/your-user/nixos_backups
borg init --encryption=none /run/media/your-user/mydisk2/nixos_backups
# It sets up the repository where backups will be stored...
# --encryption=none ... and no encryption is used.
# If you prefer encryption, you can choose different modes like repokey.
Step 3: Create a backup script that tells Borg what to back up and where to store it: vim dotfiles/backup/backup_nixos.sh:
#!/bin/bash
set -e
# Backup source directories
SOURCES=(
/etc/nixos
/home/your-user
# List of directories you want to back up
)
# The location of your backup repository.
REPO="/run/media/your-user/mydisk2/nixos_backups"
# A unique name for each backup, using the current date and time.
BACKUP_NAME="nixos-$(date +%Y-%m-%d-%H%M%S)"
# Exclude patterns to skip unnecessary files and directories you don't want to back up
EXCLUDES=(
--exclude '/home/your-user/.cache'
)
# Run the backup with the command borg create.
# It creates a new backup archive in the repository.
borg create -v --stats \
"$REPO::$BACKUP_NAME" \
"${SOURCES[@]}" \
"${EXCLUDES[@]}"
# Prune (cleans up) old backups keeping only the last 4 weekly backups.
borg prune -v --list "$REPO" --keep-weekly=4
Make the script executable: chmod +x backup_nixos.sh
Step 4: Set up automatic weekly (daily) backups with Cron
services.cron = {
enable = true; # Ensure that cron is installed and enabled in your NixOS.
systemCronJobs = [
"0 19 * * TUE /home/your-user/dotfiles/backup/backup_nixos.sh >> /home/your-user/backup.log 2>&1"
];
};
The cron expression:
sudo nixos-rebuild switch
Check the backup log: cat /home/your-user/backup.log and make sure that your second drive is mounted before the backups run.
sudo blkid
Step 5: Test the Backup System: sh ./backup_nixos.sh
# You should see the output from Borg indicating that it's backing up files.
Creating archive at "/run/media/your-user/mydisk2/nixos_backups::nixos-2024-11-26-180540"
# List of archives or backups in your repository created by Borg
borg list /run/media/your-user/mydisk2/nixos_backups
Step 6. How to restore backups
borg list /run/media/your-user/mydisk2/nixos_backups
# To restore a specific file or directory, use the borg extract command.
cd ~
borg extract /run/media/your-user/mydisk2/nixos_backups::nixos-2024-12-14-121859 configuration.nix
# I am using /run/media/your-user/mydisk2/nixos_backups::nixos-2024-12-14-121859 ...
# but I mean: /path/to/repository::archive
# configuration.nix refers to a file to be restored.
# When Borg backs up a system, it records the file structure starting from the root directory (/).
Extracts configuration.nix from the specified archive into the current directory (configuration.nix will be extracted to ~/configuration.nix).
Borg extracts the file exactly as it is stored in the archive, relative to the root of the backed-up system, into your current working directory.
To extract configuration.nix to /etc/nixos/configuration.nix (which you generally should not do directly):
cd /etc/nixos # Changes the current directory to where configuration.nix resides.
borg extract /path/to/repository::archive configuration.nix
# Extracts configuration.nix into /etc/nixos/, overwriting the existing file.
# or...
borg extract -C /tmp /path/to/repository::archive configuration.nix # Extracts to a temporal location, e.g., /tmp/configuration.nix
sudo cp /tmp/configuration.nix /etc/nixos/configuration.nix # Then copy it to the desired location.
# Restore all Files from a particular backup to their original locations (you need to run the command with root permissions):
sudo borg extract /run/media/your-user/mydisk2/nixos_backups::nixos-2022-01-01-020000
By default, these backups are stored in a repository and indexed by archives (like nixos-2022-01-01-020000). To see the actual file structure and browse through their content, you can mount a given archive, then browse it with your favorite file manager.
borg mount /run/media/your-user/mydisk2/nixos_backups::nixos-2024-12-14-121859 /path/to/mountpoint
# After mounting, the entire backup’s file structure will be available at /path/to/mountpoint, where you can navigate using standard file management tools.
# Once you are done:
borg umount /path/to/mountpoint
You may want to use GUI front-ends for Borg:
Regular backups are critical!
#!/bin/bash
# ____ _
# | _ \ | |
# | |_) | __ _ ___| | ___ _ _ __
# | _ < / _` |/ __| |/ / | | | '_ \
# | |_) | (_| | (__| <| |_| | |_) |
# |____/ \__,_|\___|_|\_\\__,_| .__/
# | |
#
set -e # Exit on first error
# 1. Setting Variables
echo " 1. Setting Variables..."
BACKUP_DEST1="/run/media/${USER}/mydisk2" # Destination for the first backup
BACKUP_DEST2="/run/media/${USER}/mydisk" # Destination for the second backup
cowsay "My Backup"
# Checking if external drives are mounted before running the backup is critical.
# If they are not mounted, it aborts the process to prevent writing data to the wrong place.
if ! mountpoint -q "$BACKUP_DEST1"; then
echo "Error: $BACKUP_DEST1 is not mounted."
exit 1
fi
if ! mountpoint -q "$BACKUP_DEST2"; then
echo "Error: $BACKUP_DEST2 is not mounted."
exit 1
fi
Step 2. Backup using borgbackup to create deduplicated backups.
cd
echo "2. Backing up using borgbackup..."
# Launch a backup script
if ! sh /home/your-user/dotfiles/backup/backup_nixos.sh; then
echo "Failed to execute the backup script."
fi
# 3. Rysync directories to mydisk2 and mydisk
# Synchronizing the contents of the justtothepoint directory from home directory to the specified external disk (BACKUP_DEST1 and BACKUP_DEST2), enhancing redundancy and reliability.
# -a is archive mode, which preserves file attributes, permissions, and timestamps.
# -v Verbosely logging the progress of the synchronization.
# --exclude avoids copying unnecessary files. This is a neat optimization, e.g., cleanDestinationDir, disableFastRender, __pycache__, .venv.
# --delete ensures that the backup destination mirrors the source exactly.
echo "3. Back up directories to $BACKUP_DEST1..."
rsync -av --exclude 'cleanDestinationDir' --exclude 'disableFastRender' --delete "$HOME/justtothepoint/" "$BACKUP_DEST1/justtothepoint"
rsync -av --delete "$HOME/dotfiles/" "$BACKUP_DEST1/dotfiles"
rsync -av --delete "$HOME/Dropbox/" "$BACKUP_DEST1/Dropbox"
rsync -av --delete "$HOME/wallpapers/" "$BACKUP_DEST1/wallpapers"
rsync -av --exclude '__pycache__/' --exclude '.venv/' --delete "$HOME/myNewPython/" "$BACKUP_DEST1/myNewPython"
rsync -av --delete /etc/nixos/ "$BACKUP_DEST1/nixos_config"
echo "3. Back up directories to $BACKUP_DEST2..."
rsync -av --exclude 'cleanDestinationDir' --exclude 'disableFastRender' --delete "$HOME/justtothepoint/" "$BACKUP_DEST2/justtothepoint"
rsync -av --delete "$HOME/dotfiles/" "$BACKUP_DEST2/dotfiles"
rsync -av --delete "$HOME/Dropbox/" "$BACKUP_DEST2/Dropbox"
rsync -av --delete "$HOME/wallpapers/" "$BACKUP_DEST2/wallpapers"
rsync -av --exclude '__pycache__/' --exclude '.venv/' --delete "$HOME/myNewPython/" "$BACKUP_DEST2/myNewPython"
rsync -av --delete /etc/nixos/ "$BACKUP_DEST2/nixos_config"