1
0
Fork
You've already forked restic-scripts
0
No description
  • Shell 100%
2026年07月02日 19:53:04 +02:00
home.excludes feat: externalize includes and excludes 2026年05月25日 12:11:21 +02:00
home.includes feat: externalize includes and excludes 2026年05月25日 12:11:21 +02:00
install feat: default to include stacks in backup with opt out 2026年05月25日 12:27:53 +02:00
README.md Include a list of installed packages into the backup 2026年07月02日 19:53:04 +02:00
restic-backup Include a list of installed packages into the backup 2026年07月02日 19:53:04 +02:00
restic-helper Initial commit. 2026年05月25日 11:45:03 +02:00
sys.excludes Include a list of installed packages into the backup 2026年07月02日 19:53:04 +02:00
sys.includes Include a list of installed packages into the backup 2026年07月02日 19:53:04 +02:00

Quick Start

Clone the repository, then run the installer as root from the repo directory:

sudo ./install

The installer will prompt for your storage box hostname, username, SSH port, and an optional healthchecks.io URL, then handle every setup step automatically.

For day-to-day operations use restic-helper:

restic-helper run # trigger a backup now
restic-helper status # show timer and service status
restic-helper logs # show recent backup logs
restic-helper snapshots # list all snapshots
restic-helper restore latest --target /tmp/restore # restore latest snapshot

This tutorial will guide you through setting up automated, encrypted backups using restic to a Hetzner Storage Box on Debian 13.

Prerequisites

  • Debian 13 server
  • Hetzner Storage Box with SSH/SFTP access
  • Root access to the server
  • Account at https://healthchecks.io (optional)

1. Install Required Packages

apt update
apt install restic openssh-client curl

2. Generate SSH Key for Restic

Create a dedicated SSH key pair for restic backups:

ssh-keygen -t ed25519 -f /root/.ssh/id_restic -C "restic-backup"

When prompted, leave the passphrase empty (press Enter twice).

Convert the public key to RFC4716 format (required by Hetzner for port 22):

ssh-keygen -e -f /root/.ssh/id_restic.pub > /root/.ssh/id_restic_rfc.pub

3. Configure SSH for Storage Box

Create SSH config entry for easier access:

cat > /root/.ssh/config << 'EOF'
Host storagebox
 HostName u000000-sub0.your-storagebox.de
 User u000000-sub0
 Port 23
 IdentityFile /root/.ssh/id_restic
 IdentitiesOnly yes
 Compression yes
EOF

Replace u000000-sub0 with your actual Storage Box username and u000000-sub0.your-storagebox.de with your Storage Box hostname.

Set correct permissions:

chmod 600 /root/.ssh/config

4. Upload SSH Key to Storage Box

Upload your SSH public key to the Storage Box:

ssh-copy-id -p 23 -s -i /root/.ssh/id_restic u000000-sub0@u000000-sub0.your-storagebox.de

Replace the username and hostname with your actual values.

Test the connection:

ssh storagebox

You should connect without being asked for a password. Type exit to disconnect.

5. Configure Restic Repository

Create the repository configuration file:

echo "sftp:storagebox:/home/" > /root/.restic-repo
chmod 600 /root/.restic-repo

6. Set Up Systemd Credentials

Create a secure directory for credentials:

mkdir -p /etc/credstore.encrypted
chmod 700 /etc/credstore.encrypted

Generate a strong password and encrypt it with systemd-creds:

openssl rand -base64 32 | \
 tee >(systemd-creds encrypt --name=restic-password - \
 /etc/credstore.encrypted/restic-password)

Set correct permissions:

chmod 600 /etc/credstore.encrypted/restic-password

7. Initialize Restic Repository

Initialize the restic repository on the Storage Box:

export RESTIC_REPOSITORY=$(cat /root/.restic-repo)
restic init --password-command "systemd-creds decrypt /etc/credstore.encrypted/restic-password -"

You should see a message confirming the repository was created.

8. Create Backup Configuration Directory

Create the directory for backup configuration files and install the defaults:

mkdir -p /etc/backup
cp sys.includes /etc/backup/sys.includes
cp sys.excludes /etc/backup/sys.excludes
cp home.includes /etc/backup/home.includes
cp home.excludes /etc/backup/home.excludes

The .includes files list paths to back up (one per line). The .excludes files list paths or patterns to skip. Edit these to customise what gets backed up without touching the script itself.

Optionally, configure healthchecks.io monitoring by saving your ping URL:

echo "https://hc-ping.com/your-uuid-here" > /etc/backup/healthcheck.url

9. Install Backup Script

cp restic-backup /usr/local/sbin/restic-backup
chmod 750 /usr/local/sbin/restic-backup

The script backs up:

  • /etc, /root, /srv, /usr/local, /var/spool, plus the distro package database (/var/lib/dpkg on Debian/Ubuntu, /var/lib/rpm on Fedora) — tagged sys
  • /home (or paths in /etc/backup/home.includes) with exclusions from /etc/backup/home.excludes — tagged home
  • Each Docker stack that has a .backup.conf file in its directory — tagged with the stack name

Per-stack backup behaviour is controlled by .backup.conf files in each stack directory under /srv/stacks/. See Per-Stack Configuration below.

10. Install Restic Helper Script

cp restic-helper /usr/local/sbin/restic-helper
chmod 750 /usr/local/sbin/restic-helper

This script uses systemd-run to inject the encrypted credentials, so it works correctly both interactively and from scripts.

11. Create Systemd Service

Create the systemd service unit:

cat > /etc/systemd/system/restic-backup.service << 'EOF'
[Unit]
Description=Backup to Hetzner Storage Box
After=docker.service network-online.target
Wants=network-online.target
[Service]
Type=oneshot
User=root
Environment=HOME=/root
LoadCredentialEncrypted=restic-password:/etc/credstore.encrypted/restic-password
ExecStart=/usr/local/sbin/restic-backup
# Security Hardening
PrivateTmp=yes
ProtectSystem=strict
ReadWritePaths=/srv /var/lib/docker /var/log /var/backups
# Timeout (important for large backups)
TimeoutStartSec=3h
# Don't restart on failure
Restart=no
EOF

12. Create Systemd Timer

Create the timer for automated daily backups:

cat > /etc/systemd/system/restic-backup.timer << 'EOF'
[Unit]
Description=Daily backup to Hetzner Storage Box
Requires=restic-backup.service
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
# Random delay of 0-30 minutes
RandomizedDelaySec=30min
[Install]
WantedBy=timers.target
EOF

13. Enable and Start the Timer

Reload systemd, enable and start the timer:

systemctl daemon-reload
systemctl enable restic-backup.timer
systemctl start restic-backup.timer

Check the timer status:

systemctl status restic-backup.timer
systemctl list-timers restic-backup.timer

14. Test the Backup

Run a manual backup to test the setup:

systemctl start restic-backup.service

Monitor the backup progress:

journalctl -fu restic-backup.service

15. Verify Backups

List all snapshots:

/usr/local/sbin/restic-helper snapshots

List snapshots with a specific tag:

/usr/local/sbin/restic-helper snapshots --tag immich

Browse the latest snapshot:

/usr/local/sbin/restic-helper ls latest

Search for specific files:

/usr/local/sbin/restic-helper find docker-compose.yml

16. Restore from Backup

Restore the latest snapshot to a target directory:

/usr/local/sbin/restic-helper restore latest --target /tmp/restore

Restore a specific snapshot:

/usr/local/sbin/restic-helper restore <snapshot-id> --target /tmp/restore

Restore specific paths only:

/usr/local/sbin/restic-helper restore latest --tag immich --target /tmp/restore --include /srv/stacks/immich

Per-Stack Configuration

Every directory under /srv/stacks/ is backed up automatically. Place a .backup.conf file in a stack directory to opt out or customise behaviour. Without a .backup.conf the stack is backed up live with no extra paths or excludes.

mode=live # back up while stack is running (default)
mode=stop # stop the stack before backup, restart it after
mode=skip # exclude this stack from backups entirely
extra_paths=/var/lib/docker/volumes/mystack_* # additional paths to include
excludes=/srv/stacks/mystack/large-cache-dir # space-separated paths to exclude

Example — opt a stack out of backups:

mode=skip

Example — stop the stack for a consistent snapshot and include its volumes:

mode=stop
extra_paths=/var/lib/docker/volumes/mystack_db_data

Maintenance

Check Repository Integrity

/usr/local/sbin/restic-helper check

View Backup Logs

restic-helper logs # recent logs
restic-helper follow # follow live

Adjust Backup Retention

Edit the retention policy in /usr/local/sbin/restic-backup:

restic forget \
 --keep-daily 7 \
 --keep-weekly 4 \
 --keep-monthly 6 \
 --keep-yearly 2 \
 --prune

restic-helper reference

Command Description
restic-helper run Trigger a backup now via systemd
restic-helper status Show timer and service status
restic-helper logs Show recent backup logs
restic-helper follow Follow backup logs live
restic-helper snapshots [--tag TAG] List snapshots
restic-helper ls latest Browse the latest snapshot
restic-helper find <file> Find a file across snapshots
restic-helper check Check repository integrity
restic-helper restore <snapshot> --target <dir> Restore a snapshot