restic-linux-backup is a conservative system backup runner for Linux. It
backs up local filesystems directly to any repository supported by
restic, including rclone remotes, S3-compatible storage,
SFTP, REST servers, and local disks.
The project grew from a production Ubuntu server deployment with independent local and encrypted off-site backups. It focuses on predictable recovery, application-consistent dump hooks, bounded remote integrity checks, and safe systemd automation.
Status: early release (
0.1.x). Review the configuration and perform restore tests before relying on it as your only backup path.
- Restic encryption, compression, deduplication, and versioned snapshots
- Multiple source filesystems, including separate
/bootand/boot/efi - Configurable 7-daily/4-weekly/12-monthly retention by default
forget --prunescoped by host and tag- Executable pre/post hooks for consistent database dumps
- Docker PostgreSQL and MariaDB hook examples
- Gzip verification for every dump produced by hooks
- First-snapshot repository check and verified small-file restore
- Monthly rotating repository data checks (1/20 per run by default)
- Local locking and optional waiting for other systemd backup units
- Optional Docker container continuity monitoring
- ntfy success and high-priority failure notifications
- Authentication-expiry hints for rclone/cloud failures
- Persistent, rotated logs and systemd journal integration
- Installer, safe uninstaller, tarball target, and Debian package builder
- It does not replace restic, rclone, or a database-native dump tool.
- It does not stop all containers or freeze a host for a long upload.
- It does not initialize, delete, or migrate repositories automatically.
- It does not store backup passwords or cloud credentials.
- It does not enable timers before an administrator completes preflight.
- Linux with Bash 4.4+ and systemd
- restic 0.16 or newer (0.18+ recommended)
- jq, curl, gzip, GNU coreutils/findutils, and util-linux (
flock) - rclone only for repositories or transport checks that use it
- Docker CLI only when Docker hooks/monitoring are enabled
Ubuntu/Debian example:
sudo apt install restic rclone jq curl gzip util-linuxgit clone https://github.com/rocket6317/linux-time-machine-backup-tool.git
cd linux-time-machine-backup-tool
sudo ./install.shThe installer backs up replaced managed files, preserves existing configuration, reloads systemd, and leaves both timers disabled.
Alternatively, build and install the Debian package:
make deb
sudo apt install ./restic-linux-backup_0.1.0_all.debEdit these root-only files:
/etc/restic-linux-backup/config
/etc/restic-linux-backup/paths
/etc/restic-linux-backup/excludes
/etc/restic-linux-backup/hooks.d/
Keep repository passwords and cloud credentials in their native protected files. The main configuration should point to them:
RESTIC_REPOSITORY="rclone:offsite:server-backup"
RESTIC_PASSWORD_FILE="/root/.config/restic/password"
RCLONE_CONFIG="/root/.config/rclone/rclone.conf"
TRANSPORT_CHECK_TARGET="offsite:server-backup"Initialize a new repository explicitly only when it truly does not exist:
sudo env \
RCLONE_CONFIG=/root/.config/rclone/rclone.conf \
RESTIC_REPOSITORY=rclone:offsite:server-backup \
RESTIC_PASSWORD_FILE=/root/.config/restic/password \
restic initNever run restic init against an existing repository merely because access
fails; diagnose credentials and transport first.
Place one absolute path per line in paths. Restic runs with
--one-file-system, so list separate filesystems explicitly:
/
/boot
/boot/efi
The configured state directory must be beneath one source path so hook-created
dumps enter the snapshot. /var/lib/restic-linux-backup is covered when / is
a source.
Example hooks install with a .example suffix and are not executable. Copy,
review, configure, and enable only the hooks you need:
sudo cp /etc/restic-linux-backup/hooks.d/10-postgresql-docker.example \
/etc/restic-linux-backup/hooks.d/10-postgresql-docker
sudo chmod 700 /etc/restic-linux-backup/hooks.d/10-postgresql-dockerSet POSTGRES_CONTAINER or MARIADB_CONTAINER in a small root-owned wrapper,
or customize the copied hook. Exclude the corresponding live database storage
from excludes; restore from the logical dump instead. Hooks run as root, so
they must be root-owned and not group/world writable.
Custom pre-backup hooks receive:
RLB_HOOK_PHASE=pre-backup
RLB_DUMP_DIR=/var/lib/restic-linux-backup/dumps.RANDOM
Write gzip-compressed dumps beneath RLB_DUMP_DIR. The runner verifies every
.gz file with gzip -t. Hooks are invoked again with
RLB_HOOK_PHASE=post-backup; hooks that do not need that phase should exit 0.
Post-backup hooks also receive RLB_SNAPSHOT_ID.
sudo /usr/sbin/restic-linux-backup preflight
sudo /usr/sbin/restic-linux-backup validate
sudo systemctl start restic-linux-backup.service
sudo journalctl -fu restic-linux-backup.serviceAfter the manual backup and restore verification succeed:
sudo systemctl enable --now \
restic-linux-backup.timer \
restic-linux-backup-check.timer
systemctl list-timers 'restic-linux-backup*'Defaults are a daily backup around 05:15 and a bounded integrity check on the first Sunday of each month around 08:00. Edit timer drop-ins to change the schedule; do not edit packaged units in place.
List snapshots:
sudo env \
RESTIC_REPOSITORY=rclone:offsite:server-backup \
RESTIC_PASSWORD_FILE=/root/.config/restic/password \
RCLONE_CONFIG=/root/.config/rclone/rclone.conf \
restic snapshotsRestore into a staging directory and inspect before copying to production:
sudo mkdir -p /srv/restic-restore
sudo env \
RESTIC_REPOSITORY=rclone:offsite:server-backup \
RESTIC_PASSWORD_FILE=/root/.config/restic/password \
RCLONE_CONFIG=/root/.config/rclone/rclone.conf \
restic restore latest --target /srv/restic-restore \
--include /etc --include /home --verifyFor bare-metal recovery, restore host configuration selectively. Do not blindly overwrite a new machine's fstab, networking, bootloader configuration, machine identity, or hardware-specific settings.
sudo systemctl status restic-linux-backup.timer
sudo journalctl -u restic-linux-backup.service --since today
sudo tail -f /var/log/restic-linux-backup/backup.log
sudo /usr/sbin/restic-linux-backup checkIf a cloud remote reports authentication, trust, session, 401, or 403 errors, renew that transport's credentials, validate it directly, then rerun preflight. Do not print credentials into logs or issue reports.
- Configuration, hooks, state, and logs are root-only.
- Hooks execute as root and are rejected if writable by group/others.
- Passwords are read using
RESTIC_PASSWORD_FILE. - Cloud credentials remain in rclone or the backend's standard credential file.
- Repository cleanup is limited to configured retention for the selected host and tag.
- Uninstall preserves credentials, configuration, logs, state, and repository data.
Review SECURITY.md before reporting a vulnerability.
make check
make test
make debSee CONTRIBUTING.md. Contributions for additional dump hooks, notification providers, distributions, and test coverage are welcome. The complete setting reference is in docs/configuration.md, and the execution/security flow is described in docs/architecture.md.
MIT. See LICENSE.