Sync & Backup — a native ZimaOS module: encrypted backups with restore, one-way sync to USB, cloud drives, another Zima or a server

A while ago someone here wrote: “If a developer could create a sync and backup app as ergonomic and easy to use as [Lintux Firewall, Cron], that would be great.” — so here it is. Third module in the same family as ZFW and Cron: a native ZimaOS module (systemd-sysext, no Docker), a tile on the dashboard, ZimaOS session login, four languages, light and dark.

ZimaOS’ own Backup tile backs up phones to the Zima. This module covers the folders on the Zima itself — the AppData of your apps, your documents, photos, media. Both coexist.

Two kinds of job

  • Backup — encrypted, versioned snapshots with restic (bundled). Keep last / daily / weekly / monthly, browse any point in time, restore single files or whole folders, check the repository. The first run sends everything, every later run only what changed.
  • Sync — a plain one-way mirror with rsync or rclone. Readable anywhere without any tool. “Mirror deletions” is a switch, off by default, and a preview shows what a run would copy and delete before it runs.

Where it can go

  • a USB disk or any local folder — the target step lists what is mounted (system disk, pools, USB disks by label, free space); one click sets the folder. An unplugged disk is refused instead of silently filling the system disk.
  • the cloud drives ZimaOS Files is signed in to (Google Drive, OneDrive, …) — the module talks to the drive directly through ZimaOS’ own rclone configuration, not through the mounted folder. Measured against Google Drive: the mounted folder needed >10 minutes just to create restic’s repository skeleton; the direct path does it in 14–46 s.
  • another ZimaOS or Linux box over SSH — the module has its own key; paste the public key into authorized_keys on the other box. Find on the network lists other ZimaOS boxes on the LAN (they announce themselves via mDNS) and your Tailscale peers, one click fills in the host.
  • SFTP, Windows/SMB share, S3-compatible storage.

The rest

  • three-step wizard: what · where · when
  • schedule: manual, every N hours, or a cron expression with a live check that shows the next runs
  • job cards with live progress, phase, transfer rate; a Log window with the tool’s own output; run history
  • notifications: Telegram, or a webhook in generic JSON / n8n / Discord / Slack / Home Assistant / Uptime Kuma format
  • exFAT/FAT USB disks work without the usual ownership errors
  • secrets stay in /DATA/AppData/zbackup/keys/ (mode 600) and never appear in an API response

Install (ZimaOS 1.7.x; verified on amd64 — the arm64 image is built by CI but I have no arm64 box, reports welcome)

Two ways, both need SSH (Settings → General → Developer mode → View → SSH Access):

1. One installer for the Lintux modules — you pick whether the firewall comes along. Each script installs what is missing and updates what is old, nothing else; run it again later to update.

Cron + Sync & Backup, without the firewall:

curl -fsSL https://raw.githubusercontent.com/chicohaager/lintux-modkit/main/install-without-firewall.sh -o /tmp/lintux-install.sh
sudo bash /tmp/lintux-install.sh

ZFW Firewall + Cron + Sync & Backup:

curl -fsSL https://raw.githubusercontent.com/chicohaager/lintux-modkit/main/install-with-firewall.sh -o /tmp/lintux-install.sh
sudo bash /tmp/lintux-install.sh

2. Just this module, by hand: download zbackup-amd64.raw (or -arm64) from the release, copy it to the box as zbackup.raw — zpkg matches the file name against the extension name — and run:

sudo zpkg install /tmp/zbackup.raw

Either way the Sync & Backup tile appears on the dashboard; the UI follows your ZimaOS language (EN/DE/FR/ZH). Step-by-step with the expected output: see the installation thread (link below).

Repo: GitHub - chicohaager/zima-backup: Sync & Backup module for ZimaOS: restic backups with versions and restore, rsync/rclone one-way sync to disks, SSH, SMB, S3 and cloud drives · GitHub
Release v0.1.1: Release v0.1.1 — Sync & Backup · chicohaager/zima-backup · GitHub
Step-by-step HowTo (first backup, restore, sync, cloud, SSH): zima-backup/HOWTO.md at main · chicohaager/zima-backup · GitHub

Verified on ZimaOS 1.7.1 (ZimaCube Pro): 27 end-to-end checks against /DATA, a mergerfs pool, ext4 and exFAT USB disks, across a reboot; SSH/SFTP/SMB targets against a Linux box; Google Drive as a direct target. Known limits are in the changelog — the honest one: Google Drive charges one round trip per file, so the first backup of a big folder is an overnight job (later runs are seconds).

Not affiliated with IceWhale. Feedback and issues welcome — and please write down your passphrase, without it nobody can restore, not even me. :slightly_smiling_face:

Title: [HowTo] Install Sync & Backup on ZimaOS — a native module, no Docker, five minutes


This is the installation walkthrough for Sync & Backup, the folder backup & sync module for ZimaOS (announcement thread: link to the announcement post). Every step below was run on a ZimaCube Pro with ZimaOS 1.7.1 right before posting; the exact messages you should see are quoted.

What you need

  • ZimaOS 1.7.x on an amd64 box (ZimaBoard, ZimaBlade, ZimaCube). An arm64 image is built as well, but I have no arm64 hardware to run it on — if you try it, please report.
  • Five minutes and a terminal: either an SSH client on your computer, or ZimaOS’ own web terminal (both live in the same settings panel, see step 1).

The module is a systemd-sysext image (zbackup.raw) that ZimaOS’ zpkg tool installs — the same mechanism ZimaOS uses for its own modules. No container, no port to map.

Two ways to install: A — one script for the whole Lintux stack (ZFW Firewall, Cron, Sync & Backup; also does updates), or B — by hand, one module, four commands. Both need SSH or the web terminal (step 1).


Step 1 — Turn on SSH (once)

SSH is off on a fresh ZimaOS. In the ZimaOS web UI:

Settings → General → Developer mode → View → SSH Access (toggle on).

The panel says “Log in to SSH using the ZimaOS system account” — that is the user you log into the ZimaOS web UI with, same password. (The same panel has Web-based terminal, if you prefer not to use an SSH client.)

Step 2 — Connect

From your computer:

ssh <your-zimaos-user>@<zima-ip>

Way A — the stack installer (install and update)

Sync & Backup is one of three Lintux modules (ZFW Firewall, Cron, Sync & Backup). Two ready-made installers, pick one — each installs what is missing and updates what is old, and touches nothing else:

Cron + Sync & Backup, no firewall:

curl -fsSL https://raw.githubusercontent.com/chicohaager/lintux-modkit/main/install-without-firewall.sh -o /tmp/lintux-install.sh
sudo bash /tmp/lintux-install.sh

ZFW Firewall + Cron + Sync & Backup:

curl -fsSL https://raw.githubusercontent.com/chicohaager/lintux-modkit/main/install-with-firewall.sh -o /tmp/lintux-install.sh
sudo bash /tmp/lintux-install.sh

For each module the script asks the running daemon for its version, asks GitHub for the latest release, downloads the asset for this CPU (amd64/arm64), verifies the checksum and installs. What the no-firewall one prints on a box that has Cron but not Sync & Backup yet (lines as measured):

[lintux] ZimaOS 1.7.1 · amd64 · install/update · stack: cron zbackup
[lintux] cron: installed 0.3.0 · latest 0.3.0
[lintux] cron: up to date
[lintux] zbackup: not installed · latest 0.1.1
[lintux] zbackup: downloading zbackup-amd64.raw (v0.1.1)
[lintux] zbackup: checksum OK
[lintux] zbackup: zpkg install
[lintux]   starting install module...
[lintux]   install success
[lintux] zbackup: 0.1.1 is running

Useful switches:

  • --check — only report installed vs. latest, change nothing
  • --force — reinstall even when up to date

Run the same script again any time to update; jobs, history and keys under /DATA/AppData/<module> are kept. A Sync & Backup with a job running is left alone until you run it again. Then continue with Step 5.

Way B — by hand

Step 3 — Download the module onto the box and verify it

cd /tmp
curl -fsSL -o zbackup-amd64.raw https://github.com/chicohaager/zima-backup/releases/download/v0.1.1/zbackup-amd64.raw
curl -fsSL -o zbackup-amd64.raw.sha256 https://github.com/chicohaager/zima-backup/releases/download/v0.1.1/zbackup-amd64.raw.sha256
sha256sum -c zbackup-amd64.raw.sha256

Expected: zbackup-amd64.raw: OK (the file is 14 MB; it contains the daemon, the UI and restic 0.19.1).

arm64 box: use zbackup-arm64.raw and zbackup-arm64.raw.sha256 instead.

Step 4 — Rename and install

zpkg matches the file name against the module’s name inside the image, so the file must be called zbackup.raw:

mv zbackup-amd64.raw zbackup.raw
sudo zpkg install /tmp/zbackup.raw

Expected:

starting install module...
install success

If you skip the rename you get Failed to install module: module not pass validate — that is the file name, nothing else.

Step 5 — Open it

Go back to the ZimaOS dashboard (reload the page). A new tile Sync & Backup is there; click it. The UI follows your ZimaOS language (English, German, French, Chinese) and has a light and a dark theme.

Optional check from the terminal:

curl -s http://127.0.0.1/v2/zbackup/api/health

→ {"jobs_running":0,"jobs_total":0,"status":"healthy","uptime_seconds":…,"version":"0.1.1"}

Step 6 — Your first job

Click New job — three steps: what (backup or sync, the folders), where (a USB disk, a cloud drive you signed in to in Files, another Zima over SSH, SFTP, SMB, S3), when (schedule and how many versions to keep). The full walkthrough with screenshots — first backup, restoring a file, sync, Google Drive, another Zima — is here:

Two things worth knowing before the first backup:

  • Write the passphrase down. It encrypts the backup; without it nothing can be restored — not by the module, not by anyone.
  • Pick the USB disk from the drive cards, not by typing /media/sda. The module refuses an unplugged disk instead of quietly filling your system disk.

Upgrading later

Way A: run the same installer again — it updates only what is old. Way B:

sudo zpkg remove zbackup
sudo zpkg install /tmp/zbackup.raw

Your jobs, history and keys are in /DATA/AppData/zbackup/ and survive remove/install and reboots (checked: three jobs before, three after).

Uninstalling

sudo zpkg remove zbackup removes the module and its tile. /DATA/AppData/zbackup/ stays — delete it yourself for a clean slate. The backups on your disks are plain restic repositories; with restic and your passphrase you can read them on any computer, module or not.

Where to report problems

Issues · chicohaager/zima-backup · GitHub — please include the Log of the failing job (button on the job card) and your ZimaOS version.

Hello I have just installed the two new updates for Cron and Sync & Backup for testing.

Cron
The interface is clean with multilingual. It’s great.
However, importing the task file only works with tasks created in ****** Tasks easily created in min/h/d are refused.
Cron is very difficult for beginners. There are no more operational examples on the new version.

Sync & Backup
The interface appears clean and multilingual. it’s great.
Step 1 is impeccable, ergonomic and easy.
Step 2 is too complicated to attach equipment locally. And attaching a second ZimaOS locally with an SSH key is too complicated and time-consuming. It’s the same as Syncin. You should be able to view the destination folder as in step 1.
I can’t get it to work on a simple task and don’t want to rack my brains to find the error.

For step 3 The intervals with the Cron configuration are not intuitive.

It would be interesting to take inspiration from the ZimaOS Backup application for ergonomics. And add security modes only for those who want them.

Thanks again for your work. I guess it must be complicated to design a complex application accessible to beginners. But that’s the goal of the ZimaOS system:).

I discovered two bugs last night - just fixing them
Step 2 – you’re right about that; I’ll adjust it

Hello, would it be possible to change the icon to Sync, it is the same as that of Cron. Thank you for your work.

0.2 is out, and it is mostly the answer to the feedback in this thread — the sentence that stuck was “the goal of ZimaOS is a complex application that beginners can use.” So here is what changed.

Your first backup in nine clicks — nothing to type. New backup → Choose folder… → pick it → Choose this folder → click a drive → Start → tick “I have written the passphrase down” → Create backup. Name, target folder, schedule (daily at 03:00), what to keep (7 days, 4 weeks, 6 months) and the passphrase are filled in for you, and the first run starts right away. Everything else moved under Advanced.

Targets are cards, in three groups: drives in this box (with free space), network shares, cloud drives. One click sets the target; the folder on it is chosen for you (Backups/<folder>, one repository per job — two backup jobs can no longer collide in one folder, which was the cause of a “wrong password” reported here).

Network shares come from ZimaOS Files. No SMB form, no SSH key for the everyday case: Connect a network share… asks for the server (found on the LAN by name), guest or user + password, and hands it to Files’ own endpoint. Files mounts every share of that server; from then on they are cards here and folders in Files, and they come back after a reboot on their own (measured: Files reconnects about 20 s after boot). SMB with its own credentials, SSH, SFTP and S3 are still there — under Advanced → Direct target for experts.

A passphrase you can keep. A backup without a passphrase of your own gets seven random words (EFF short wordlist, drawn with the browser’s cryptographic random numbers, about 72 bits), shown once, with Copy and Print / save as PDF, and a checkbox before the backup starts.

Schedules in words. Daily at 03:00, every Sunday at 03:00, monthly on day 1, every hour at minute 15, every 20 minutes — the next three runs are shown while you choose, and the list says next in 19 hours. Cron expressions are still there for experts (the same change went into Cron 0.3.2, and Cron now shows the Sync & Backup jobs in a read-only card, so one page holds everything that runs on a timer).

Errors in words. The unable to open config file: unexpected HTTP response (500) reported here now reads repository at the target unreadable with the line rclone printed (one Samba answered 500 for a config directory); a wrong SMB password reads user or password refused, a missing share share not found on the server, a disconnected share or unplugged disk the network share \server\share is not connected — connect it in Files or with ‘Connect a network share…’. A folder that is empty at run time ends yellow (nothing to back up), not green.

Also

  • folder chips show file count and size before you back up; a run against an empty folder is refused once
  • cloud sync shows files per second — Google Drive charges about one round trip per file, whatever its size (measured); a backup packs files and does not suffer from it
  • restore: the folder picker opened behind the dialog (fixed), and files whose names contain [ ] * ? were silently skipped by restic’s include patterns (fixed, with a test)
  • Spanish as the fifth language (drafted by a non-native speaker — corrections welcome)
  • built with Go 1.26.8; govulncheck finds no known issues (0.1.1 carried 43 in the standard library); the CasaOS-Common dependency tree is gone

Will it survive the next ZimaOS update? Yes, by the same mechanism ZimaOS uses for its own Files and ZVM: the module is a systemd-sysext image. A ZimaOS update replaces the read-only system image; the extension images live in /var/lib/extensions, which sits on the data partition, and systemd merges them into /usr again at every boot (the boot journal on my box: Using extensions ‘cron.raw’, ‘icewhale_files.raw’, … ‘zbackup.raw’, ‘zfw.raw’ … Merged extensions into ‘/usr’). Your jobs, passphrases and history are in /DATA/AppData/zbackup/, nowhere near the system image. Measured, not assumed: on my ZimaCube the extensions installed in June and July are still merged after the 1.7.1 image from August. What an OS update can change is an internal ZimaOS API the module talks to — then the fix is a new module version from the release page, installed over the old one; the jobs stay.

Install / upgrade (ZimaOS 1.7.x; verified on amd64, arm64 built by CI): the installer updates what is old and leaves the rest alone —

curl -fsSL https://raw.githubusercontent.com/chicohaager/lintux-modkit/main/install-without-firewall.sh -o /tmp/lintux-install.sh
sudo bash /tmp/lintux-install.sh

(install-with-firewall.sh for ZFW + Cron + Sync & Backup.) By hand: download zbackup-amd64.raw (or -arm64), copy it to the box as zbackup.raw, sudo zpkg remove zbackup && sudo zpkg install /tmp/zbackup.raw — jobs, secrets and history are kept; 0.1 jobs keep working and show their schedule in words where the words fit.

Release v0.2.0: Release v0.2.0 · chicohaager/zima-backup · GitHub
Cron v0.3.2: Release v0.3.2 · chicohaager/cron · GitHub
HowTo (first backup, restore, sync, network share, cloud, SSH): zima-backup/HOWTO.md at main · chicohaager/zima-backup · GitHub
Changelog: zima-backup/CHANGELOG.md at main · chicohaager/zima-backup · GitHub

Verified on ZimaOS 1.7.1 (ZimaCube Pro)


New Icon :wink:

Great, I’ll test it shortly and come back. Thanks for the new icon.

Zima Backup 0.3 – what’s new

System backup is the big addition in 0.3. It’s a third backup type next to Backup and Sync, and it takes one click. It saves everything that makes your box your box:

  • network, users, hostname and SSH keys (/etc)
  • ZimaOS state: apps, users, app store, file service
  • installed modules and /DATA/AppData
  • all of /DATA too, if you want it

Every snapshot comes with a manifest that records the ZimaOS version, apps, modules and partition layout. It contains no secrets. The state databases are copied in a consistent state. On a well-used box the first run took 85.8 GiB in about 5 minutes, and the next run took 8 MiB in 10 seconds.

System restore is a guided dialog. It shows you what’s inside the snapshot and warns you if the snapshot comes from a different ZimaOS version. After the restore it brings your containers back and asks for a reboot. To get a fresh install back, install the same ZimaOS version, add the module and restore. I tested this in a VM installed from the official ISO: apps, tiles and app data were all back.

Fixes in 0.3.1

  • Job results now show in your UI language with local number formats.
  • Sizes in the restore dialog display correctly.
  • Logins keep working after the ZimaOS user service restarts.