Desktop app + command line · snapshot backup

One backup tool — a desktop app and a command line.

A small, fast backup client in Rust with a native GTK desktop app and a scriptable CLI — same engine, same config. Hard-linked snapshots over SSH make every run look like a complete tree, but only what changed takes new space. Restore anything, from any of them.

GTK desktop app moraine CLI rsync --link-dest rclone backend

Moraine 0.2.2 · desktop app + CLI · or build from source with cargo build --release

Moraine — Quick Backup
Moraine desktop app, Quick Backup tab: a target selected, the rclone backend, and a snapshot backup running in the live log.

How it works

Full trees. A fraction of the disk.

Every run creates a new <timestamp>/ folder. Files that haven't changed since last time become hard links — the same data on disk, but visible in every snapshot. A latest symlink always points to the newest one.

older newer → hard links — unchanged files share disk 06-19 ↑ pruned 06-22 06-24 06-25 06-26 latest →
/volume1/backups/nas/ — five snapshots, one latest symlink 2026-06-19T… · 06-22 · 06-24 · 06-25 · 06-26
01 — run

rsync mirrors the source

The client runs rsync -aAX --delete over SSH into a new <timestamp>/ folder. Permissions, ACLs and xattrs come along.

02 — linking

Unchanged files are hard-linked

--link-dest=../latest lets files that haven't changed point at the previous snapshot. New disk is only used for what actually differs.

03 — pruning

latest is repointed, old is pruned

latest moves to the new snapshot. Auto-prune keeps the N most recent plus daily/weekly/monthly according to your policy.

Features

Everything a home server needs — nothing more.

A shared engine powers both the CLI and the desktop app. Same config, same snapshots, same log.

Hard-linked snapshots

Every backup is a complete, browsable tree. Unchanged files share disk via hard links — so history costs almost nothing.

rsync --link-dest

GFS retention & auto-prune

Keep the N most recent plus the newest per day, week and month. Pruning runs automatically after every successful backup.

keep_last · daily · weekly · monthly

Selective restore

Browse a snapshot's file tree and pick exactly what you want back — or the whole tree. Nothing in the destination folder is ever deleted.

browse · pick · restore

Scheduling

Create multiple schedules — hourly, daily or weekly — and install them straight into your crontab with one click.

→ crontab

Run history

Every backup, restore and prune is written to history.jsonl and shown in a History tab — with time, target and outcome.

history.jsonl

Verification

Test the SSH key, the connection, that all sources exist and that the destination is writable — before you trust a backup.

moraine verify

Dry-run everywhere

See exactly what would be transferred or deleted before anything happens. Applies to backup, restore and prune.

--dry-run

Two backends

rsync over SSH for your NAS, or rclone for cloud and object storage. Same snapshot model, same flow.

ssh · rclone

A polished desktop UI

The desktop app (built with GTK 4) has a clean dark design system — cards, a teal accent and soft shadows — with native file pickers and dialogs.

GTK 4

The desktop app

Four tabs. The whole workflow.

The same engine as the CLI, with a graphical interface for editing targets, scheduling, restoring and tracking runs. Click around below.

Moraine
Moraine
Snapshot backups over SSH · v0.2.2
Quick BackupScheduleRestoreHistorySettingsHelp
# snapshot 2026-06-26T08-30-12
sending incremental file list ...
✓ 24,910 files · 312.4M sent · snapshot done

Quick Backup

Edit a target and run it right away — with a live-streamed rsync log at the bottom.

  • Host, user, port, SSH key and destination in one form
  • Sources and exclude patterns as editable lists
  • Retention per target + Prune now
  • Test connection, Dry run and Run backup
Moraine
Moraine
Snapshot backups over SSH · v0.2.2
Quick BackupScheduleRestoreHistorySettingsHelp
Installed 2 schedule(s) to crontab

Schedule

Build up multiple schedules and write them to your crontab — the app shows the cron expression as you set it up.

  • Hourly, daily or weekly per target
  • Live preview of the cron expression
  • Enable/disable without deleting the schedule
  • Install to crontab activates everything at once
Moraine
Moraine
Snapshot backups over SSH · v0.2.2
Quick BackupScheduleRestoreHistorySettingsHelp
2 item(s) selected in documents/

Restore

List snapshots, browse the tree and pick exactly what you want back. Files are copied — nothing is deleted.

  • Snapshots newest first, the latest marked newest
  • Browse folder by folder with breadcrumbs
  • Tick individual files, or leave empty for the whole snapshot
  • A suggested restore folder so live data is never overwritten
Moraine
Moraine
Snapshot backups over SSH · v0.2.2
Quick BackupScheduleRestoreHistorySettingsHelp
Run history
Refresh
backupnassnapshot 2026-06-26T08-30-1208:30:14
prunenasdeleted 1, kept 1308:30:15
restorenas2026-06-25T02-00 → ~/restoreYesterday 21:12
backupoffsitessh: connection timed outYesterday 03:00
backupnassnapshot 2026-06-25T02-00-032 days ago
5 log entries

History

Every run becomes a row in the log — so you can see after the fact what happened, and when.

  • Backup, restore and prune with color-coded badges
  • Time, target and a short detail (snapshot id, count, or error)
  • A clear ✓ / ✗ for the outcome
  • Saved as history.jsonl next to your config

The command line

Five commands, all scriptable.

Prefer the terminal? The moraine binary does exactly the same job — perfect for cron and remote servers.

moraine init

Writes a commented example config to start from.

moraine verify --target nas

Tests the SSH key, the connection, that the sources exist and that the destination is writable.

moraine run --dry-run

Runs backup for all targets (or a chosen one). Auto-prune after a successful run.

moraine list --target nas

Lists all snapshots on the target, newest first.

moraine prune --dry-run

Shows which snapshots the retention policy would prune — before anything is deleted.

moraine --version

Version string with embedded git hash and build date from build.rs.

Download

Download Moraine 0.2.2

The desktop app + CLI on Linux; the CLI on macOS and Windows (the desktop app lands there next). Same engine and config everywhere.

Debian / Ubuntu in Debian

Now in official Debian. apt install moraine works on unstable / testing (migrating up from sid; the buildds cover arm64/armhf too), and reaches Ubuntu/Mint as they sync. For stable — or auto-updating everywhere today — add the thern.io APT repo:

curl -fsSL https://cdn.thern.io/keys/thern-cdn-keyring.gpg | sudo tee /usr/share/keyrings/thern-cdn-keyring.gpg >/dev/null echo "deb [signed-by=/usr/share/keyrings/thern-cdn-keyring.gpg] https://cdn.thern.io/deb stable main" | sudo tee /etc/apt/sources.list.d/thern-cdn.list sudo apt update && sudo apt install moraine
official Debian · thern.io APT repo · GTK app · rsync · ssh

Arch Linux app + CLI

The thern.io pacman repopacman -S moraine. Or the package / PKGBUILD.

curl -fsSL https://cdn.thern.io/keys/thern-cdn-pacman.conf | sudo tee -a /etc/pacman.conf sudo pacman -Sy moraine
pacman repo · GTK app · rsync · ssh · rclone

Fedora / RPM app + CLI

The thern.io DNF repodnf install moraine, GPG-signed (Fedora/RHEL/openSUSE).

sudo curl -fsSL -o /etc/yum.repos.d/thern-cdn.repo https://cdn.thern.io/keys/thern-cdn.repo sudo dnf install moraine
DNF repo · GTK app · rsync · ssh · rclone

Alpine Linux app + CLI

Build the package from the APKBUILD with abuild, then install it with apk. Both the desktop app and the CLI, on musl.

GTK app · rsync · ssh · rclone · musl

Flatpak App + CLI

The desktop app on any distro, sandboxed, with rsync, ssh and rclone bundled inside it — nothing to match against your system. Served from our own repo on the thern.io CDN, signed with the same GPG key as the APT and DNF repos.

flatpak remote-add --if-not-exists moraine https://cdn.thern.io/moraine.flatpakrepo
flatpak install moraine io.thern.moraine
x86-64 & arm64 · GTK app · signed repo · sandboxed

AppImage any distro

One file, no install, no package manager — download it, make it executable, run it. GTK is bundled, so the desktop app works the same on any distribution. It needs glibc 2.39 or newer (Ubuntu 24.04+, Debian 13+, Fedora 40+, Arch and the rolling distros). On something older, take the Flatpak or the .deb instead. A native aarch64 build (for arm64 desktops) arrives with the next release.

chmod +x moraine-x86_64.AppImage && ./moraine-x86_64.AppImage
GTK app · portable · x86-64 today · arm64 soon

Raspberry Pi CLI

A perfect always-on backup box. These builds are statically linked, so one file runs on any Raspberry Pi OS — no dependencies to match, nothing to compile. Pick arm64 for a Pi 3/4/5 on a 64-bit system, armv7 for a 32-bit one.

uname -m  # aarch64 → arm64 · armv7l → armv7
CLI · rsync · ssh · rclone · static

macOS CLI

The command-line client — best via Homebrew, which also pulls a modern rsync (macOS ships an old one). Or the Apple-Silicon tarball. A universal .pkg installer (Apple Silicon + Intel, into /usr/local) arrives with the next release. The GTK desktop app is coming to macOS.

brew install TheJonaz/moraine/moraine
arm64 · Homebrew · .pkg installer soon · rclone

Windows App + CLI

The x64 desktop app — a one-click installer with the full GTK app, native window controls and the Moraine icon. Or the command-line client (installer that adds moraine to your PATH, winget / Scoop, or the plain zip). Scheduling via Task Scheduler; for rsync/SSH use WSL, or the rclone backend (SFTP/FTP/SMB/cloud).

winget install TheJonaz.Moraine
scoop install moraine
Desktop app · Task Scheduler · winget · Scoop · rclone

Source code

Build it yourself with cargo build --release. Pure Rust, MIT license — it's all open on GitHub.

Rust · MIT

Coming soon packaging ready · awaiting store review

Built and in the repo — these light up here once they're live in their stores.

macOS installer .pkg · universal AppImage arm64 · GTK FreeBSD port · CLI OpenBSD ports · CLI NetBSD pkgsrc · CLI Snap app + CLI Nix / NixOS app + CLI Chocolatey Windows CLI

Packages are served from the thern.io CDN (GPG-signed APT/DNF/pacman/Flatpak repos) · every build is also on GitHub Releases, verified in CI. Gentoo ships from its own overlay; the macOS .pkg, FreeBSD, OpenBSD and NetBSD recipes live in packaging/.

Get started

One TOML file. One block per target.

Run moraine init, fill in host, sources and retention — and run a --dry-run before your first real backup.

moraine.toml
# One or more [[target]] blocks.
[[target]]
name   = "nas"
host   = "192.168.1.50"
user   = "backup"
port   = 22
key    = "~/.ssh/backup_ed25519"
dest   = "/volume1/backups"
sources = [
  "/home/jonaz/dokument",
  "/home/jonaz/bilder",
]
exclude = [ "*.tmp", "node_modules" ]

# Keep 5 most recent + GFS
[target.retention]
keep_last    = 5
keep_daily   = 7
keep_weekly  = 4
keep_monthly = 6

Ready to protect your home server?

Snapshots that cost almost no disk, file-level restore and a log of everything that happened.

↓ Download Moraine

Why Windows warns about this download

Moraine’s Windows installer isn’t code-signed yet, so Microsoft Defender SmartScreen — and Edge — flag it the way they flag any new app from an independent developer. The warning is about the missing signature, not about anything found in the file. A code-signing certificate (via the SignPath Foundation programme for open source) is on the way.

It’s safe to install: Moraine is open source (MIT). Every build is compiled in public GitHub Actions CI straight from the source, and the identical file is also on GitHub Releases — so you can verify it byte-for-byte.