Initial commit: restic backup configuration
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
4
.envrc
Executable file
4
.envrc
Executable file
@@ -0,0 +1,4 @@
|
||||
if ! has nix_direnv_version || ! nix_direnv_version 3.0.6; then
|
||||
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.6/direnvrc" "sha256-RYcUJaRMf8oF5LznDrlCXbkOQrywm0HDv1VjYGaJGdM="
|
||||
fi
|
||||
use flake
|
||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
.password
|
||||
.direnv
|
||||
67
backup.sh
Executable file
67
backup.sh
Executable file
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
#export RESTIC_REPOSITORY="sftp:glen@thalassa.local:/Users/glen/backups/restic-starbak"
|
||||
export RESTIC_REPOSITORY="sftp:glen@192.168.0.247:/Users/glen/backups/restic-starbak"
|
||||
export RESTIC_PASSWORD_FILE="${SCRIPT_DIR}/.password"
|
||||
|
||||
EXCLUDE_FILE="${SCRIPT_DIR}/excludes.txt"
|
||||
|
||||
# Force macOS system ssh — the nix restic wrapper prepends nix openssh to PATH,
|
||||
# which lacks macOS network entitlements and fails inside tmux
|
||||
SFTP_OPTS=(-o "sftp.command=/usr/bin/ssh glen@192.168.0.247 -s sftp")
|
||||
|
||||
if [ ! -f "$RESTIC_PASSWORD_FILE" ]; then
|
||||
echo "Error: Password file not found at $RESTIC_PASSWORD_FILE"
|
||||
echo "Create it with: head -c 32 /dev/urandom | base64 > ${RESTIC_PASSWORD_FILE}"
|
||||
echo "Then: chmod 600 ${RESTIC_PASSWORD_FILE}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "${1:-backup}" in
|
||||
init)
|
||||
restic "${SFTP_OPTS[@]}" init
|
||||
;;
|
||||
backup)
|
||||
restic "${SFTP_OPTS[@]}" backup \
|
||||
/Users/glen \
|
||||
--exclude-file="$EXCLUDE_FILE" \
|
||||
--exclude-caches \
|
||||
--one-file-system \
|
||||
--verbose
|
||||
;;
|
||||
snapshots)
|
||||
restic "${SFTP_OPTS[@]}" snapshots
|
||||
;;
|
||||
prune)
|
||||
restic "${SFTP_OPTS[@]}" forget \
|
||||
--keep-hourly 24 \
|
||||
--keep-daily 7 \
|
||||
--keep-weekly 4 \
|
||||
--keep-monthly 12 \
|
||||
--keep-yearly 3 \
|
||||
--prune
|
||||
;;
|
||||
check)
|
||||
restic "${SFTP_OPTS[@]}" check
|
||||
;;
|
||||
stats)
|
||||
# per-snapshot sizes; pass snapshot ID for a specific one
|
||||
restic "${SFTP_OPTS[@]}" stats "${2:-latest}"
|
||||
;;
|
||||
diff)
|
||||
# diff two snapshots: ./backup.sh diff <id1> <id2>
|
||||
restic "${SFTP_OPTS[@]}" diff "${2:?snapshot1 ID required}" "${3:?snapshot2 ID required}"
|
||||
;;
|
||||
mount)
|
||||
MOUNT_POINT="${2:-/tmp/restic-mount}"
|
||||
mkdir -p "$MOUNT_POINT"
|
||||
restic "${SFTP_OPTS[@]}" mount "$MOUNT_POINT"
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {init|backup|snapshots|prune|check|stats [id]|diff <id1> <id2>|mount [path]}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
104
excludes.txt
Normal file
104
excludes.txt
Normal file
@@ -0,0 +1,104 @@
|
||||
# ============================================
|
||||
# Restic exclude list for macOS user data backup
|
||||
# Mirrors Time Machine standard exclusions + extras
|
||||
# ============================================
|
||||
|
||||
# --- macOS system/app caches ---
|
||||
Library/Caches
|
||||
Library/Logs
|
||||
Library/Cookies
|
||||
Library/HTTPStorages
|
||||
Library/Saved Application State
|
||||
Library/WebKit/MediaKeys
|
||||
Library/Containers/*/Data/Library/Caches
|
||||
Library/Containers/*/Data/Library/Logs
|
||||
Library/Group Containers/*/Library/Caches
|
||||
Library/Application Support
|
||||
Library/Containers
|
||||
|
||||
# --- Spotlight & indexing ---
|
||||
.Spotlight-V100
|
||||
.fseventsd
|
||||
|
||||
# --- Trash ---
|
||||
.Trash
|
||||
|
||||
# --- macOS metadata ---
|
||||
.DS_Store
|
||||
.TemporaryItems
|
||||
.DocumentRevisions-V100
|
||||
|
||||
# --- Nix store symlinks (reconstructable) ---
|
||||
.nix-defexpr
|
||||
.nix-profile
|
||||
# Skip files that are nix store symlinks
|
||||
.zshrc
|
||||
.zshenv
|
||||
.manpath
|
||||
|
||||
# --- Build artifacts & dependency caches ---
|
||||
node_modules
|
||||
.gradle
|
||||
.ivy2
|
||||
.m2
|
||||
.sbt
|
||||
.npm
|
||||
.cache
|
||||
target
|
||||
__pycache__
|
||||
*.pyc
|
||||
.tox
|
||||
.venv
|
||||
venv
|
||||
.data
|
||||
|
||||
# --- Go ---
|
||||
go/pkg
|
||||
|
||||
# --- IDE/editor state ---
|
||||
.vscode/extensions
|
||||
.vscode-server
|
||||
|
||||
# --- Git large objects (restic deduplicates, but no point backing up pack files) ---
|
||||
.git/objects/pack
|
||||
|
||||
# --- Large/reconstructable/synced ---
|
||||
big-files
|
||||
Seafile
|
||||
cloud
|
||||
Downloads
|
||||
|
||||
# --- Application-specific transient data ---
|
||||
Library/Application Support/Google/Chrome/Default/Service Worker
|
||||
Library/Application Support/Google/Chrome/Default/Code Cache
|
||||
Library/Application Support/Google/Chrome/Default/GPUCache
|
||||
Library/Application Support/Google/Chrome/Default/IndexedDB
|
||||
Library/Application Support/Google/Chrome/ShaderCache
|
||||
Library/Application Support/Slack/Service Worker
|
||||
Library/Application Support/Slack/Code Cache
|
||||
Library/Application Support/Slack/GPUCache
|
||||
Library/Application Support/Discord/Code Cache
|
||||
Library/Application Support/Discord/GPUCache
|
||||
|
||||
# --- Photos library (synced from iCloud, very large) ---
|
||||
Library/Photos
|
||||
|
||||
# --- Mail downloads (re-downloadable) ---
|
||||
Library/Mail/V*/MailData/Envelope Index*
|
||||
|
||||
# --- Swap/sleep/VM ---
|
||||
.SleepImage
|
||||
.swap*
|
||||
|
||||
# --- Claude Code ---
|
||||
#.claude.json.backup
|
||||
|
||||
# --- SSH sockets ---
|
||||
.ssh/sockets
|
||||
|
||||
# --- atuin (shell history sync, reconstructable) ---
|
||||
#.atuin
|
||||
|
||||
# --- zsh compiled/session state ---
|
||||
.zcompdump*
|
||||
.zsh_sessions
|
||||
27
flake.lock
generated
Normal file
27
flake.lock
generated
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1778794387,
|
||||
"narHash": "sha256-BL04pOS9453Awkeb9f90XBJXBSkWxN+vB7HIgnL0iMM=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "8a1b0127302ea51e05bf4ea5a291743fac442406",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
20
flake.nix
Normal file
20
flake.nix
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
description = "Restic backup for starbak -> thalassa.local";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs }:
|
||||
let
|
||||
system = "aarch64-darwin";
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in
|
||||
{
|
||||
devShells.${system}.default = pkgs.mkShell {
|
||||
packages = [
|
||||
pkgs.restic
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user