JustToThePoint English Website Version
JustToThePoint en español
Colaborate with us

NixOS VIII. Backup

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

Introduction to NixOS

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.

  1. Immutable Design: It uses a configuration file (usually /etc/nixos/configuration.nix) to define the entire system state, including installed packages, services, and system settings. This makes the system “immutable” in the sense that you don’t manually modify system files. Instead, you declare what you want, and NixOS builds the system from that declaration.
  2. Atomic Updates: When you run nixos-rebuild switch, the system builds a new generation of the environment. If the build is successful, you can switch to this new environment atomically. This means that either the entire update is applied, or nothing changes at all, preventing partial updates that could leave the system in an inconsistent state: sudo nixos-rebuild switch, build and switch to the new generation. If anything goes wrong, you can easily roll back to a previous generation: sudo nix-env ‐‐rollback This rollback is seamless because each generation is stored separately.

    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.

  3. Purely Functional System Configuration: NixOS uses a functional paradigm for configuration. This means that changes are expressed as pure functions from a configuration to a system state, ensuring reproducible builds and easy rollback.

NixOS

Automate Mounting

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

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.

  1. Ensure your second (backup) drive is mounted, e.g., ls /run/media/your-user/mydisk2
  2. Create a directory on that drive to store your backups (backup repository): mkdir /run/media/your-user/nixos_backups
  3. Initialize the Borg Repository without encryption:
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:

  1. 0 19 * * TUE (minute hour day_of_month month day_of_week): This cron expression means the backup will run at 19:00 (7.pm) every Tuesday.
  2. /home/your-user/dotfiles/backup/backup_nixos.sh is the path to the backup script.
  3. our_script » /home/your-user/backup.log 2>&1 (2>&1 merges stderr into stdout) redirects both standard output and errors to a log file (backup.log).

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:

Script for backup the system

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"
Bitcoin donation

JustToThePoint Copyright © 2011 - 2025 Anawim. ALL RIGHTS RESERVED. Bilingual e-books, articles, and videos to help your child and your entire family succeed, develop a healthy lifestyle, and have a lot of fun. Social Issues, Join us.

This website uses cookies to improve your navigation experience.
By continuing, you are consenting to our use of cookies, in accordance with our Cookies Policy and Website Terms and Conditions of use.