-
Notifications
You must be signed in to change notification settings - Fork 0
Backup
NullString1 edited this page Jan 13, 2026
·
2 revisions
Guide to NullOS's automated backup system using Restic.
NullOS includes Restic for encrypted, incremental backups to various backends.
Configuration File: modules/services/backup.nix
Features:
- Encrypted backups
- Incremental (only changed files)
- Automated scheduling
- Multiple retention policies
- Various storage backends
Backs up:
-
/mdatadirectory -
/home/${username}directory
Schedule:
- 1 minute after boot
- Every hour thereafter
Retention:
- Last 10 backups
- Daily for 7 days
- Weekly for 4 weeks
- Monthly for 6 months
# modules/services/backup.nix
{
services.restic.backups.nsdata = {
repository = vars.resticRepository;
passwordFile = "/etc/nixos/secrets/restic-password";
paths = [
"/home/${vars.username}"
];
exclude = [
"/home/${vars.username}/.cache"
"**/node_modules"
];
pruneOpts = [
"--keep-last 7"
"--keep-daily 7"
"--keep-weekly 4"
"--keep-monthly 6"
];
timerConfig = {
OnCalendar = "daily";
};
};
}In variables.nix:
resticRepository = "sftp:user@server:/backups/laptop";Supported backends:
- Local:
/mnt/backup - SFTP:
sftp:user@server:/path - S3:
s3:s3.amazonaws.com/bucket - B2:
b2:bucket-name - Azure:
azure:container-name:/ - REST:
rest:https://backup.server
sudo mkdir -p /etc/nixos/secrets
echo "your-strong-password" | sudo tee /etc/nixos/secrets/restic-password
sudo chmod 600 /etc/nixos/secrets/restic-password# In variables.nix
resticRepository = "sftp:user@backup-server.com:/backups/nslapt";sudo nixos-rebuild switch --flake .#hostnamesystemctl status restic-backups-nsdatasudo systemctl start restic-backups-nsdatasystemctl status restic-backups-nsdata
journalctl -u restic-backups-nsdata -fsudo restic -r sftp:user@server:/backups snapshotssudo restic -r sftp:user@server:/backups checksudo restic -r sftp:user@server:/backups ls latestsudo restic -r sftp:user@server:/backups restore latest \
--target /tmp/restore \
--include /home/user/important-file.txtsudo restic -r sftp:user@server:/backups restore latest \
--target /tmp/restoresudo restic -r sftp:user@server:/backups restore latest \
--target /Warning: Be careful with this! It will overwrite files.
The default configuration excludes:
- Cache directories
- Build artifacts (
target/,node_modules/) - IDE files
- Temporary files
- Large development tools
exclude = [
# Existing exclusions...
"/home/${vars.username}/Downloads"
"**/.git"
"*.tmp"
];pruneOpts = [
"--keep-last 10" # Keep last 10 backups
"--keep-daily 7" # Keep 7 daily backups
"--keep-weekly 4" # Keep 4 weekly backups
"--keep-monthly 6" # Keep 6 monthly backups
"--keep-yearly 2" # Keep 2 yearly backups
];pruneOpts = [
"--keep-last 14"
"--keep-daily 14"
"--keep-weekly 8"
"--keep-monthly 12"
"--keep-yearly 5"
];pruneOpts = [
"--keep-last 5"
"--keep-daily 3"
"--keep-weekly 2"
"--keep-monthly 3"
];timerConfig = {
OnBootSec = "1m"; # 1 minute after boot
OnUnitActiveSec = "1h"; # Every hour
};timerConfig = {
OnCalendar = "daily";
Persistent = true;
};timerConfig = {
OnCalendar = "02:00"; # 2 AM daily
Persistent = true;
};timerConfig = {
OnCalendar = [ "02:00" "14:00" ]; # 2 AM and 2 PM
};- Generate SSH key:
ssh-keygen -t ed25519 -f /root/.ssh/restic_backup- Copy to server:
ssh-copy-id -i /root/.ssh/restic_backup user@backup-server- Configure repository:
resticRepository = "sftp:user@backup-server:/backups";resticRepository = "s3:s3.amazonaws.com/my-backup-bucket";
# Set credentials
environmentFile = "/etc/nixos/secrets/restic-s3-env";Content of /etc/nixos/secrets/restic-s3-env:
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
systemd.services.restic-backups-nsdata.serviceConfig = {
Nice = 19; # Lowest CPU priority
IOSchedulingClass = "idle"; # Lowest I/O priority
};extraOptions = [
"--limit-upload 1000" # KB/s upload limit
"--limit-download 1000"
"--pack-size 32" # MB pack size
];services.restic.backups.nsdata = {
# ... existing config ...
# Run script after backup
backupPrepareCommand = "echo 'Backup starting'";
backupCleanupCommand = "echo 'Backup finished'";
};#!/usr/bin/env bash
LAST_BACKUP=$(sudo restic -r $REPO snapshots --json | jq -r '.[0].time')
AGE_HOURS=$(( ($(date +%s) - $(date -d "$LAST_BACKUP" +%s)) / 3600 ))
if [ $AGE_HOURS -gt 48 ]; then
notify-send "Backup Warning" "Last backup was $AGE_HOURS hours ago"
fiservices.restic.backups = {
home = {
repository = "sftp:server:/backups/home";
paths = [ "/home" ];
timerConfig.OnCalendar = "daily";
};
projects = {
repository = "s3:bucket/projects";
paths = [ "/mdata/projects" ];
timerConfig.OnCalendar = "hourly";
};
config = {
repository = "/mnt/external/config";
paths = [ "/etc/nixos" ];
timerConfig.OnCalendar = "weekly";
};
};- Boot from NixOS live USB
- Mount partitions:
mount /dev/sdXn /mnt
mount /dev/sdXm /mnt/boot- Restore NixOS config:
restic -r sftp:server:/backups restore latest \
--target /mnt \
--include /etc/nixos- Restore home:
restic -r sftp:server:/backups restore latest \
--target /mnt \
--include /home- Reinstall NixOS:
nixos-install --root /mnt- Test Restores Regularly - Verify backups work
- Monitor Backup Success - Check logs weekly
- Off-site Backups - Use remote repository
- Encrypt Repository - Always use password
- Document Recovery - Keep recovery notes
- Version Configuration - Git for NixOS config
- Multiple Destinations - Redundant backups
Check logs:
journalctl -u restic-backups-nsdata -n 50Ensure service runs as correct user:
services.restic.backups.nsdata.user = vars.username;sudo restic -r sftp:server:/backups unlockPrune old backups:
sudo restic -r sftp:server:/backups prune- Managing Secrets - Secure password storage
- Variables Reference - Backup variables
- Recovery - System recovery procedures