Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,7 @@ You have two ways to exclude files and directories from your backups:

1. **`EXCLUDE_FILE`**: Point this to a text file (like `restic-excludes.txt`) containing one exclusion pattern per line.
2. **`EXCLUDE_PATTERNS`**: A space-separated list of patterns to exclude directly in the configuration file (e.g., `*.tmp *.log`).
3. **`EXCLUDE_CLOUD_FILES`**: Set to `true` to skip cloud-backed placeholder files (e.g., iCloud) on macOS.

#### Performance and behavior

Expand All @@ -504,7 +505,7 @@ You have two ways to exclude files and directories from your backups:
- `LIMIT_UPLOAD` — Restic `--limit-upload` (KiB/s).
- `SFTP_CONNECTIONS` — Sets `-o sftp.connections=<N>` for parallel SFTP connections.
- `READ_CONCURRENCY` — Restic `--read-concurrency <N>`.
- `COMPRESSION` — Restic `--compression auto|max|off|...` (requires Restic version with compression support).
- `COMPRESSION` — Restic `--compression auto|max|off|fastest|better` (requires Restic version with compression support).
- `PACK_SIZE` — Restic `--pack-size <MiB>`.
- `ONE_FILE_SYSTEM=true|false` — Restic `--one-file-system`.
- `RESTIC_CACHE_DIR=/var/cache/restic` — Use a persistent cache (recommended for speed).
Expand Down Expand Up @@ -654,6 +655,8 @@ If you prefer to manage the schedule manually instead of using the wizard, you c

Both update checks run after the script acquires its lock, to avoid concurrent updates.

> **Tip:** If you run into GitHub API rate limits (e.g., 403 Forbidden) during updates on shared IPs, set `GITHUB_TOKEN` in your `restic-backup.conf` to a Personal Access Token to authenticate the requests.

-----

## Security and best practices
Expand Down
10 changes: 9 additions & 1 deletion restic-backup.conf
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ ADDITIONAL_CRITICAL_DIRS=""
# Backup tag to identify snapshots
BACKUP_TAG="daily-$(hostname)"

# Compression level: auto, off, max
# Compression level: auto, max, off, fastest, better
COMPRESSION="max"

# Pack size for optimization (default: empty for auto)
Expand Down Expand Up @@ -139,6 +139,9 @@ PRUNE_AFTER_FORGET=true
# Automatically exclude folders containing a CACHEDIR.TAG file (true/false)
EXCLUDE_CACHES=true

# Automatically exclude cloud-backed placeholder files on macOS (true/false)
EXCLUDE_CLOUD_FILES=false

# Exclude folders containing any of these specific files.
# Use Bash array syntax for multiple files: (".nobackup" ".ignore_restic")
EXCLUDE_IF_PRESENT=(".nobackup")
Expand All @@ -157,3 +160,8 @@ RESTIC_FALLBACK_REPOSITORY="sftp:truenas-backup:/mnt/HDDs/Hatzner_VPS_Backups/ho
# Optional: If your secondary mirror uses a different restic password, specify it here.
# Leave blank to automatically use the primary RESTIC_PASSWORD_FILE.
RESTIC_FALLBACK_PASSWORD_FILE=""

# --- Updates ---
# Optional: Provide a GitHub Personal Access Token to prevent rate-limiting during auto-updates
GITHUB_TOKEN=""

19 changes: 15 additions & 4 deletions restic-backup.sh
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#!/usr/bin/env bash

# =================================================================
# Restic Backup Script v0.46 - 2026.05.24
# Restic Backup Script v0.47 - 2026.06.10
# =================================================================

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
set -euo pipefail
umask 077

# --- Script Constants ---
SCRIPT_VERSION="0.46"
SCRIPT_VERSION="0.47"
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
PROG_NAME=$(basename "$0"); readonly PROG_NAME
CONFIG_FILE="${SCRIPT_DIR}/restic-backup.conf"
Expand Down Expand Up @@ -196,7 +196,11 @@ check_and_install_restic() {
exit 1
fi
local release_info
release_info=$(curl -s "https://api.github.com/repos/restic/restic/releases/latest")
if [ -n "${GITHUB_TOKEN:-}" ]; then
release_info=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" "https://api.github.com/repos/restic/restic/releases/latest")
else
release_info=$(curl -s "https://api.github.com/repos/restic/restic/releases/latest")
fi
if [ -z "$release_info" ]; then
echo -e "${C_YELLOW}Could not fetch latest restic version info from GitHub. Skipping check.${C_RESET}"
return 0
Expand Down Expand Up @@ -294,7 +298,11 @@ check_for_script_update() {
echo -e "${C_BOLD}--- Checking for script updates ---${C_RESET}"
local SCRIPT_API_URL="https://api.github.com/repos/buildplan/restic-backup-script/releases/latest"
local release_info
release_info=$(curl -sL -H "Cache-Control: no-cache" -H "Pragma: no-cache" "$SCRIPT_API_URL")
if [ -n "${GITHUB_TOKEN:-}" ]; then
release_info=$(curl -sL -H "Authorization: Bearer $GITHUB_TOKEN" -H "Cache-Control: no-cache" -H "Pragma: no-cache" "$SCRIPT_API_URL")
else
release_info=$(curl -sL -H "Cache-Control: no-cache" -H "Pragma: no-cache" "$SCRIPT_API_URL")
fi
local remote_version
remote_version=$(echo "$release_info" | jq -r '.tag_name | sub("^v"; "")')
if [ -z "$remote_version" ] || [[ "$remote_version" == "$SCRIPT_VERSION" ]]; then
Expand Down Expand Up @@ -453,6 +461,9 @@ build_backup_command() {
if [ "${EXCLUDE_CACHES:-false}" = "true" ]; then
cmd+=(--exclude-caches)
fi
if [ "${EXCLUDE_CLOUD_FILES:-false}" = "true" ]; then
cmd+=(--exclude-cloud-files)
fi
if declare -p EXCLUDE_IF_PRESENT 2>/dev/null | grep -q "declare -a"; then
for f in "${EXCLUDE_IF_PRESENT[@]}"; do
cmd+=(--exclude-if-present "$f")
Expand Down
2 changes: 1 addition & 1 deletion restic-backup.sh.sha256
Original file line number Diff line number Diff line change
@@ -1 +1 @@
b8b5fb61ee330a2352eff74825366050c7ecfc512a0c6a20c306a594883dbfe6 restic-backup.sh
3a4ee8a56419fc70a756f0b4c3603c8b4cfadd49566778377eb0aed137d4deb7 restic-backup.sh