powerful but friendly backup program that runs in your tray, powered by restic devins.page/restray
go restic system-tray
2

Configure Feed

Select the types of activity you want to include in your feed.

11 1 50

Clone this repository

https://tangled.org/devins.page/restray https://tangled.org/did:plc:gawtj6bv455n7clria4k22y6
git@knot.devins.page:devins.page/restray git@knot.devins.page:did:plc:gawtj6bv455n7clria4k22y6

For self-hosted knots, clone URLs may differ based on your setup.



README.md

Restray#

A simple Go application that runs in the background/system tray, that can schedule and manage restic backups and profiles easily. It can also use multiple profiles with different schedules and settings at once. It's also pretty configurable, see config below.

Restray is intended for desktops. Runs on MacOS, Windows, and Linux. If you're on GNOME, you will need to install this extension to interact with and use the app since GNOME doesn't natively support the system tray.

I needed a replacement for Time Machine, since it's painfully slow, only exclusive to Macs, and only supports SMB now. I quite like it's simplicity and ease-of-use though. Looking for other solutions, restic appeared to be a great fit, and I already use it for my server. However, I didn't find any option for scheduling restic backups that I actually liked. I did see resticprofile which looks cool, and may be a better solution for some, please do check it out! But I'd still prefer a simple GUI personally. So... here's Restray which should hopefully solve that :)

This is new and somewhat work-in-progress/beta software. You might possibly encounter a bug or two that I haven't fixed yet, and if so, please make an issue. I don't really intend on adding many new features, but I will fix bugs and refine the codebase more over time.

MacOS Linux Windows
Preview of Restray on MacOS Preview of Restray on Linux Preview of Restray on Windows

Features#

  • Initialize a repository if one doesn't already exist
  • Run backups on a schedule with cron expressions, or just manually
    • Can detect battery power too and temporarily disable schedule
  • Multiple backup profiles with different schedules and different settings
  • Optional automatic pruning and checks after backups
  • Optional automatic retry and removal of stale locks
  • Optional restic binary download and updates
    • First tries to find restic in user's PATH, but if not found, user can manually click "download"/"update" restic and it'll manage it for them
    • This can also be automated daily by enabling "manage_restic" in config
  • Open a shell with your profile's environment and restic binary loaded, for restoring or other CLI operations without friction
  • Mount repository snapshots on macOS/Linux
    • Requires FUSE-T or macFUSE on macOS. Requires FUSE on Linux
    • I'd recommend something like restic-browser to browse on Windows, or just open the Shell and use the CLI
  • Full Disk Access detection and prompt on macOS
  • Config file hot-reloading

Installation#

Check this repository's tags for build artifacts. I currently build+package for MacOS/Windows and build for Linux.

On MacOS you will need to disable Gatekeeper/remove quarantine from the .app as I cannot pay Apple $100 a year to get my app signed. Sorry.

Compiling#

If you're on Nix(OS)/nix-darwin, just run nix build. Or add this repo to your flake and install the package :)

If you aren't using Nix, install the dependencies from flake.nix's devshell and use just build or just package to build/package for your current platform. You can also cross-compile to other platforms, for example just build linux amd64 or just package windows.

Configuration#

[general]#

Key Type Default Description
manage_restic bool false If restic is not found in PATH, automatically downloads and updates a self-managed restic binary daily from GitHub
notifications string "none" "all" (success + errors), "errors" (errors only), or "none" (silent)
schedule_display string "description" "description" (human-readable, e.g. "every 6 hours"), "cron" (raw expression, e.g. "0 * * * *"), or "none"
terminal string "" Terminal emulator used in "Shell" and "View Log". If unset, MacOS will use Terminal.app. Linux will use default. Not used on Windows. e.g. "Ghostty"

[[profile]]#

You can create multiple of these sections for separate backup targets. Each profile has its own schedule, repository, environment, etc.

Key Type Default Description
name string "default" Name for the profile
env_file string <config_dir>/<name>.env Path to the environment file with RESTIC_REPOSITORY, RESTIC_PASSWORD, etc.
retry_lock string "2m" How long to retry acquiring a repository lock (e.g. "5m", "30s"). Will automatically attempt to clear stale locks after this timeout. Set to "0" to disable
pre_hook string "" Shell command to run before any repository operation. Inherits the profile's environment and restic binary. Operation is aborted if the hook exits non-zero. For scheduled runs, runs before the sequence
post_hook string "" Shell command to run after any repository operation. Inherits the profile's environment and restic binary. For scheduled runs, runs after the sequence

Hooks receive the following environment variables:

Variable Description
RESTRAY_PROFILE Name of the active profile
RESTRAY_OPERATIONS Comma-separated list of operations that ran (e.g. backup, backup,forget,check, unlock)
RESTRAY_SCHEDULED true if triggered by schedule, false if manual
RESTRAY_STATUS success or failure (post-hook only)
RESTRAY_ERROR Error message when RESTRAY_STATUS=failure (post-hook only)

[profile.schedule]#

Key Type Default Description
cron string "" Set to an empty string to disable the schedule entirely. Cron expression for profile schedule (for help, see crontab.guru)
on_battery bool false Whether to run schedule while on battery power
backup bool true Run backup on schedule
prune bool false Run prune on schedule
check bool false Run check on schedule

[profile.backup]#

Key Type Default Description
paths string[] [] Paths to back up, e.g. ["/Users/user/Documents", "/home/user/Projects"]
args string[] ["--exclude-caches", "--exclude", "*.tmp"] Extra arguments passed to restic backup
args_scheduled string[] ["--tag", "scheduled"] Extra arguments appended (not replaced) when running from schedule

[profile.prune]#

Key Type Default Description
args string[] ["--keep-last", "4", "--keep-hourly", "24", "--keep-daily", "7", "--keep-weekly", "4", "--keep-monthly", "12"] Extra arguments passed to restic forget --prune

[profile.check]#

Key Type Default Description
args string[] [] Extra arguments passed to restic check (e.g. ["--read-data"])

[profile.mount]#

Key Type Default Description
args string[] [] Extra arguments passed to restic mount (e.g. ["--allow-other"])

Credits#