This page shows how to create and manage local restic backups for projects on an external drive. Page is designed to replicate initial installation and setup. The workflow is applicable to daily backup management as well.
Overview
- Find the backup drive partition with lsblk.
- Mount the backup SSD to a persistent local mount folder such as ~/mnt/restic-backup.
- Set REPO to a restic repository folder inside the mounted backup drive.
- Install restic and create the repository once with restic init.
- Backup with an exclude selected files logic.
- Inspect snapshots, verify integrity, and test restore.
- Apply cleanup with forget and prune.
Install
# Arch
sudo pacman -S restic
# Debian / Ubuntu
sudo apt install resticFind the drive with lsblk
Run lsblk first to see all block devices, filesystem types, labels, and mount points. This tells you the real device name to mount and whether the SSD is already mounted.
lsblk -fExample output:
NAME FSTYPE LABEL MOUNTPOINTS
nvme0n1
|-nvme0n1p1
`-nvme0n1p2 ntfs backupssdReading the output: the device to mount is the partition name, for example /dev/nvme0n1p2. The LABEL column shows the drive label, for example backupssd. If MOUNTPOINTS is empty, the drive is not mounted yet.
For this workflow, use a persistent mount folder inside the home directory, for example ~/mnt/restic-backup. This folder remains after reboot, unlike runtime paths under /run/media.
The REPO path is the mount path plus a subfolder name for the restic repository, for example ~/mnt/restic-backup/restic-projects.
Mount the SSD
If the drive is not yet mounted, mount it manually using the device name from lsblk. This workflow uses a persistent mount folder under the home directory instead of a temporary runtime path under /run/media.
# Set the partition name from lsblk
export DRIVE_NAME=nvme0n1p2
# Use a persistent local mount folder for this backup workflow
export MOUNT_PATH="$HOME/mnt/restic-backup"
# Create the mount folder if it does not exist yet
mkdir -p "$MOUNT_PATH"
# Mount the NTFS backup partition
sudo mount -t ntfs3 "/dev/$DRIVE_NAME" "$MOUNT_PATH"
# Confirm the disk is mounted and reachable
lsblk -f
ls "$MOUNT_PATH"If the mount succeeds, the SSD contents should appear under ~/mnt/restic-backup. The folder itself persists after reboot, but the disk must be mounted again unless an automatic mount rule is configured.
# Unmount after backup work is done
sudo umount "$HOME/mnt/restic-backup"Set environment variables
$HOME is available by default in any shell session. Use it to keep the mount and repository paths generic across machines.
echo "$HOME"Export MOUNT_PATH and REPO once per session. After export, $REPO can be used in all restic commands below.
export MOUNT_PATH="$HOME/mnt/restic-backup"
export REPO="$MOUNT_PATH/restic-projects"
echo "$MOUNT_PATH"
echo "$REPO"Example output:
/home/example_user/mnt/restic-backup
/home/example_user/mnt/restic-backup/restic-projectsInitialise the repository
After the initial installation make the restic backup folder and initialize restic. This istep is done only during the initial setup.
mkdir -p $REPO
restic -r $REPO initInspect project size before backup
Useful before the first backup to confirm the data size. Also use the file counts to validate rules are skipping folders like node_modules, .venv, and build output.
du -h --max-depth=2 ~/projects 2>/dev/null | sort -h
find ~/projects -type f | wc -lDry run before first backup
Scan the source and apply exclusions without writing any data. This is useful to again to confirm actual backup file size before committing.
restic -r $REPO backup ~/projects --exclude-file ~/projects/.backup/ignore.txt --dry-run -vDaily backup
Run the same command without the dry run flag to execute backup. Restic creates a new snapshot and reuses unchanged data from previous ones.
restic -r $REPO backup ~/projects --exclude-file ~/projects/.backup/ignore.txt
restic -r $REPO snapshotsInspect and verify
You can see the new list of snapshots and latest files to confirm the process was completed successfully.
restic -r $REPO snapshots
restic -r $REPO ls latest
restic -r $REPO checkRestore test
Another step in the backup process is to test the restorability. Make sure you simulate the backup restore after the first installation and periodically. The full restore procedure is provided under the resources section above.
Cleanup: forget old snapshots
Run to remove old snapshots by a given policy, then prune to free the actual storage.
restic -r $REPO forget --keep-last 7 --keep-weekly 4 --keep-monthly 6
restic -r $REPO pruneExclude file
Exclude file is optional, however it is especially useful for developers keeping the virtual environemnts and build related folders within the repositories. The following is an example exclude file list for a Python and Reach/Next.js development environemnt.
# Location: ~/projects/.backup/ignore.txt
# Adjust path to match your project root
**/.venv
**/venv
**/node_modules
**/.next
**/__pycache__
**/.pytest_cache
**/.mypy_cache
**/.ruff_cache
**/.turbo
**/.parcel-cache
**/.cache
**/dist
**/build
**/coverage
**/*.pyc
**/*.pyo