Skip to content

About

GTK3 rsync backup manager with incremental snapshots for Linux

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Backup Manager

Warning: This project is no longer actively maintained. I am migrating away from Linux Mint, and this app was built specifically for that environment. No further updates or bug fixes are planned. Feel free to fork and continue development.

Backup Manager is a GTK3 desktop app for Linux that does rsync-based incremental backups with hard-link snapshots, scheduled via systemd user timers. It has a graphical interface with a Catppuccin Mocha dark theme, system tray integration, and a headless mode for automated backups.

Each backup creates a timestamped snapshot directory. Unchanged files are hard-linked to the previous snapshot using rsync's --link-dest, so multiple snapshots consume only the disk space of files that actually changed between runs. Old snapshots are automatically pruned based on a configurable retention limit.

Backup Manager Screenshot Screenshot placeholder -- no screenshot available yet.


Features

  • Incremental hard-link snapshots -- rsync --link-dest deduplicates unchanged files across snapshots, minimizing disk usage
  • Scheduled backups -- daily, weekly, or monthly schedules powered by systemd user timers
  • Headless mode -- run jobs from the command line or systemd without launching the GUI (--run-job)
  • Snapshot browser -- browse the file tree of any snapshot and selectively restore individual files or directories
  • Restore to original or custom location -- restore files back to their original paths or to a separate directory
  • Real-time progress -- live progress percentage, transfer speed, and ETA during backup and restore operations
  • Backup history -- SQLite database tracks every run with status, file counts, transfer sizes, duration, and full rsync logs
  • System tray -- AyatanaAppIndicator3 tray icon with status display, quick "Backup Now" per-job menu, and minimize-to-tray
  • Desktop notifications -- libnotify alerts on backup completion or failure
  • Catppuccin Mocha theme -- dark theme with scoped CSS classes (.bm-*) that avoid conflicts with the system theme
  • Job validation -- checks for missing names, invalid paths, and configuration errors before saving
  • Global exclude patterns -- define patterns (e.g., .cache/, node_modules/, *.tmp) applied to all jobs
  • Per-job excludes -- additional exclude patterns specific to individual backup jobs
  • Configurable retention -- set the maximum number of snapshots to keep per job (oldest pruned automatically)
  • Cancel running backups -- stop an in-progress backup cleanly, with partial snapshot cleanup

Pages

Page Description
Dashboard Overview cards (overall status, last backup, next scheduled, total runs) and a job status table with color-coded indicators
Jobs Split-pane job list and editor. Create, edit, delete, and run jobs. Configure sources, destination, schedule, excludes, and retention
Restore Select a job, browse its timestamped snapshots, navigate the file tree with checkboxes, and restore selected files
History Sortable, filterable table of all backup runs. Filter by job and status. Double-click a run to view its full rsync log
Settings Global preferences: default destination, max snapshots, notifications toggle, start-minimized toggle, log level, and global exclude patterns

Dependencies

Runtime

Dependency Purpose
Python 3.10+ Runtime
GTK 3 (gir1.2-gtk-3.0) GUI toolkit
PyGObject (python3-gi) Python GObject introspection bindings
AyatanaAppIndicator3 (gir1.2-ayatanaappindicator3-0.1) System tray indicator
rsync Backup engine
systemd (user session) Scheduled timers
PyYAML (python3-yaml) Configuration file parsing
libnotify (gir1.2-notify-0.7) Desktop notifications (optional, graceful degradation)

Install dependencies on Debian/Ubuntu/Mint

sudo apt install python3 python3-gi gir1.2-gtk-3.0 \
    gir1.2-ayatanaappindicator3-0.1 gir1.2-notify-0.7 \
    rsync python3-yaml

Installation

Clone the repository and run the install script:

git clone https://github.com/your-username/backup-manager.git
cd backup-manager
chmod +x install.sh
./install.sh

The install script performs the following:

  1. Copies the application to /opt/backup-manager/
  2. Creates a launcher script at /usr/local/bin/backup-manager
  3. Installs a .desktop file to /usr/share/applications/ for the application menu
  4. Creates an autostart entry at ~/.config/autostart/ that launches minimized to the tray on login

Uninstall

sudo rm -rf /opt/backup-manager
sudo rm /usr/local/bin/backup-manager
sudo rm /usr/share/applications/backup-manager.desktop
rm ~/.config/autostart/backup-manager.desktop

Usage

GUI

Launch from the application menu or terminal:

backup-manager

Start minimized to the system tray:

backup-manager --minimized

Enable debug logging:

backup-manager --debug

Headless mode

Run a specific backup job without the GUI (intended for systemd timer invocation):

backup-manager --run-job <JOB_ID>

The job ID is the 8-character identifier assigned when a job is created. Job files are stored as YAML in ~/.config/backup-manager/jobs/. Headless mode sends a desktop notification on completion or failure and exits with a non-zero status code on error.

System tray

When a tray indicator is available, closing the window minimizes the app to the tray instead of quitting. The tray menu provides:

  • Status line -- shows "Idle" or "Backing up: ..."
  • Backup Now -- submenu listing all configured jobs for one-click execution
  • Open Backup Manager -- bring the window back
  • Quit -- fully exit the application

Configuration

Global settings

Stored in YAML format at:

~/.config/backup-manager/config.yaml
Setting Default Description
default_destination /mnt/backup Default backup destination for new jobs
max_snapshots 30 Default maximum snapshots to retain
notifications true Enable desktop notifications
start_minimized true Start minimized to tray on autostart
log_level info Logging verbosity: debug, info, warning, error
global_excludes (see below) Patterns excluded from all jobs

Default global excludes:

global_excludes:
  - .cache/
  - .thumbnails/
  - "*.tmp"
  - __pycache__/
  - node_modules/
  - .venv/
  - .git/objects/

Job files

Each backup job is stored as an individual YAML file in:

~/.config/backup-manager/jobs/<JOB_ID>.yaml

Example job file:

id: a1b2c3d4
name: Daily Documents
enabled: true
sources:
  - /home/user/Documents
  - /home/user/Projects
destination: /mnt/backup/documents
schedule:
  frequency: daily
  time: "22:00"
  day_of_week: null
excludes:
  - "*.log"
  - build/
max_snapshots: 30

History database

Backup run history is stored in an SQLite database at:

~/.local/share/backup-manager/backup-manager.db

The backup_runs table records: job ID, start/end timestamps, status (running, success, failed, cancelled), file counts (added, modified, deleted), byte totals, snapshot path, error message, and the full rsync log output.

Systemd timers

When a job has a schedule other than "manual", a systemd user timer and service unit are created at:

~/.config/systemd/user/backup-manager-<JOB_ID>.timer
~/.config/systemd/user/backup-manager-<JOB_ID>.service

The service unit invokes backup-manager --run-job <JOB_ID>. Timers use Persistent=true so missed runs are executed on next boot.

You can inspect timers manually:

systemctl --user list-timers 'backup-manager-*'
systemctl --user status backup-manager-<JOB_ID>.timer

Architecture

backup_manager/
|-- __init__.py
|-- __main__.py              # Entry point, argparse, headless & GUI launch
|-- install.sh               # Installation script
|
|-- backend/
|   |-- config.py            # ConfigManager -- YAML settings & job file I/O
|   |-- database.py          # Database -- SQLite history (WAL mode)
|   |-- rsync_engine.py      # RsyncEngine -- backup & restore via rsync subprocess
|   |-- scheduler.py         # systemd user timer create/remove/query
|
|-- core/
|   |-- job_model.py         # BackupJob dataclass, BackupResult dataclass, validation
|   |-- job_executor.py      # JobExecutor -- threaded job runner with GObject signals
|
|-- ui/
    |-- app.py               # BackupManagerApp -- Gtk.Application wrapper
    |-- main_window.py       # MainWindow -- sidebar navigation, page stack, tray setup
    |-- theme.py             # Catppuccin Mocha CSS theme (scoped .bm-* classes)
    |-- tray.py              # TrayIndicator -- AyatanaAppIndicator3 system tray
    |
    |-- pages/
        |-- dashboard.py     # DashboardPage -- status cards, job overview table
        |-- jobs.py          # JobsPage -- job list + editor form
        |-- restore.py       # RestorePage -- snapshot browser, file tree, restore action
        |-- history.py       # HistoryPage -- filterable run history table, log viewer
        |-- settings.py      # SettingsPage -- global preferences editor

Key design patterns

  • Threaded execution -- JobExecutor runs rsync in a background thread and emits GObject signals (started, progress, finished) marshalled to the GTK main loop via GLib.idle_add
  • Incremental snapshots -- RsyncEngine uses rsync -aAXH --delete --link-dest=<prev> to create space-efficient hard-link snapshots. Each snapshot is a full directory tree, but only changed files consume additional disk space
  • Progress parsing -- rsync output is parsed in real time using --info=progress2 (percentage, speed, ETA) and --itemize-changes (file-level add/modify/delete counts)
  • Cancellation -- a cancel flag checked on each line of rsync output allows clean termination with partial snapshot cleanup
  • Page lifecycle -- each page implements start_updates() and stop_updates() methods called on navigation, allowing pages to start/stop polling timers
  • Scoped CSS -- all theme selectors are prefixed with .bm- to prevent interference with system GTK themes
  • Graceful degradation -- libnotify and AyatanaAppIndicator3 are imported in try/except blocks so the app runs without tray or notification support

License

MIT License

Copyright (c) 2026

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

About

GTK3 rsync backup manager with incremental snapshots for Linux

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages