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 and Windows; the CLI on macOS (the desktop app lands there next). Same engine and config everywhere.

Debian / Ubuntu in Debian

Now in official Debian. apt install moraine works on testing and unstable — it has migrated into testing on every architecture Debian builds (amd64, arm64, armhf, i386, ppc64el, riscv64, s390x, loong64) — 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

On the AURparu -S moraine (or yay) builds it from source like any other AUR package, and picks up new releases with your regular upgrade.

paru -S moraine

For a prebuilt binary instead — no compile step — add the thern.io pacman repo once:

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

Fedora / RPM app + CLI

The thern.io DNF repodnf install moraine, GPG-signed, for Fedora and RHEL. On Fedora there is also a Copr, rebuilt from this repository on every release:

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

openSUSE app + CLI

Built for Tumbleweed on the openSUSE Build Service. Add the repo once and zypper keeps Moraine updated with the rest of the system.

sudo zypper ar https://download.opensuse.org/repositories/home:/TheJonaz/openSUSE_Tumbleweed/home:TheJonaz.repo sudo zypper in moraine
Build Service · Tumbleweed · GTK app · rsync · ssh · rclone

Gentoo app + CLI

From our own overlay — add it once and emerge builds Moraine from source like everything else on the system. USE="-gui" gives you the CLI without pulling in GTK.

sudo eselect repository add moraine git https://github.com/TheJonaz/moraine-overlay.git sudo emaint sync -r moraine sudo emerge -av app-backup/moraine
overlay · USE=gui · 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

Snap CLI

The command-line client on any distro with snapd, with rsync, ssh and rclone bundled. Strictly confined: your home folder, external drives and every remote backend work straight away. Backing up top-level dotfiles (~/.ssh, ~/.config, ~/.gnupg) needs a permission that's still awaiting store approval — until then use the .deb, Flatpak or AppImage if those matter to you.

sudo snap install moraine
sudo snap connect moraine:ssh-keys
CLI · strict confinement · rsync · ssh · rclone

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 Nix / NixOS app + CLI Chocolatey Windows CLI Docker container · 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 our own overlay and openSUSE from the openSUSE Build Service; 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

FAQ

Frequently asked questions

Answers to what people ask before trusting a backup tool with their files.

Is Moraine free?

Yes. Moraine is free and open source under the MIT licence — no paid tier, no account required and no feature held back for one. The complete source is on GitHub.

How do hard-linked snapshots save disk space?

Every run creates a new timestamped folder that looks like a complete copy of your files. Files that have not changed since the previous run are stored as hard links to it (rsync's --link-dest), so they take up no additional space. Only what actually changed costs anything.

Can I restore a single file instead of everything?

Yes. In the desktop app's Restore tab you browse any snapshot's file tree and tick individual files or folders. From the command line a snapshot is an ordinary directory, so plain rsync or cp works. A restore never deletes anything at the destination — it only adds and overwrites.

Which operating systems does Moraine run on?

The desktop app and the command-line client both run on Linux and Windows. macOS has the CLI today, with the desktop app in progress. There are also native Raspberry Pi builds for arm64 and armv7.

Do I need a NAS, or does it work with cloud storage?

Either. The SSH/rsync backend backs up to anything you can SSH into — a NAS, a VPS or another PC. The rclone backend covers cloud and object storage, including S3, Backblaze B2, Google Drive, WebDAV, SMB and FTP.

How is Moraine different from Borg or restic?

Moraine stores plain directory trees rather than a repository format. You can open a snapshot in any file manager, copy files out with ordinary tools, and read it on a machine that has never had Moraine installed. Borg and restic deduplicate and encrypt into their own repository, which is more space-efficient and encrypted at rest, but readable only through their own tooling.

What happens if a backup is interrupted?

Nothing half-finished ever becomes a snapshot. Each run is assembled in a hidden work area and made visible only once every file has transferred, so listing, verifying, restoring and pruning all ignore incomplete runs. An aborted backup cannot become “the latest snapshot”, and cannot trick retention into deleting a good one.

Is my backup encrypted?

In transit, yes — the SSH backend runs over SSH. At rest it depends on the destination: the rclone and FTP backends can encrypt with rclone's crypt, using a password and optional salt per target. The SSH backend writes ordinary files, so encrypt the destination volume if that matters to you.

How do I run backups automatically?

The app's Schedule tab writes crontab entries on Linux and macOS, and Task Scheduler jobs on Windows. From the command line, point cron or a systemd timer at moraine run. A successful run prunes the target afterwards, so a single scheduled line both backs up and cleans up.

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.