shuki a08cf9911c Show background jobs that finished while TUI was closed
Previously _load_registry silently dropped dead PIDs, so jobs that
completed in the background were invisible on restart. Now dead PIDs
are loaded as 'success' status so the user sees they completed. The
registry is cleaned up after loading.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 20:46:47 +02:00

gniza - Linux Backup Manager

A generic Linux backup tool with a Python Textual TUI, web GUI, and CLI interface. Define named backup targets (sets of directories), configure remote destinations (SSH, local, S3, Google Drive), and run incremental backups with rsync --link-dest deduplication.

  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  ▓▓▓▓▓▓▓▓▓▓▓▓          ▓▓▓▓▓▓▓▓▓▓▓
  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓

  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  ▓▓▓▓▓▓▓▓▓▓▓▓          ▓▓▓▓▓▓▓▓▓▓▓
  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓

  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  ▓▓▓▓▓▓▓▓▓▓▓▓          ▓▓▓▓▓▓▓▓▓▓▓
  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
              ▓▓▓▓▓▓▓▓▓▓
                ▓▓▓▓▓▓
                  ▓▓

Features

  • Target-based backups - Define named profiles with sets of directories to back up
  • Include/exclude filters - Rsync include or exclude patterns per target (comma-separated)
  • MySQL backup - Dump all or selected databases alongside directory backups
  • Multiple remote types - SSH, local (USB/NFS), S3, Google Drive
  • Incremental snapshots - rsync --link-dest for space-efficient deduplication
  • Disk space safety - Abort backup if remote disk usage exceeds configurable threshold (default 95%)
  • Textual TUI - Beautiful terminal UI powered by Textual
  • Web dashboard - Access the full TUI from any browser with HTTP Basic Auth
  • CLI interface - Scriptable commands for automation and cron
  • Atomic snapshots - .partial directory during backup, renamed on success
  • Retention policies - Automatic pruning of old snapshots
  • Pre/post hooks - Run custom commands before/after backups
  • Email notifications - SMTP or system mail on success/failure
  • Root and user mode - Works as root (system-wide) or regular user (per-user)
  • Cron scheduling - Manage cron jobs through TUI or CLI

Installation

One-liner (root)

curl -sSL https://git.linux-hosting.co.il/shukivaknin/gniza4linux/raw/branch/main/scripts/install.sh | sudo bash

One-liner (user mode)

curl -sSL https://git.linux-hosting.co.il/shukivaknin/gniza4linux/raw/branch/main/scripts/install.sh | bash

From source

git clone https://git.linux-hosting.co.il/shukivaknin/gniza4linux.git
cd gniza4linux
sudo bash scripts/install.sh    # root mode
# or
bash scripts/install.sh          # user mode

Root mode installs to /usr/local/gniza. User mode installs to ~/.local/share/gniza.

Dependencies

  • Required: bash 4+, rsync
  • Optional: ssh, curl (SMTP notifications), rclone (S3/GDrive)
  • TUI/Web: python3, textual, textual-serve (installed automatically)

Quick Start

# Launch TUI
gniza

# Or use CLI
gniza targets add --name=mysite --folders=/var/www,/etc/nginx
gniza remotes add --name=backup-server    # (edit config manually)
gniza --cli backup --target=mysite
gniza --cli backup --all

Usage

gniza [OPTIONS] [COMMAND]

Options:
  --cli             Force CLI mode (no TUI)
  --debug           Enable debug logging
  --config=FILE     Override config file path
  --help            Show help
  --version         Show version

Commands:
  backup            [--target=NAME] [--remote=NAME] [--all]
  restore           --target=NAME [--snapshot=TS] [--remote=NAME] [--dest=DIR]
  targets           list|add|delete|show [--name=NAME] [--folders=PATHS]
  remotes           list|add|delete|show|test|disk-info-short [--name=NAME]
  snapshots         list [--target=NAME] [--remote=NAME]
  retention         [--target=NAME] [--remote=NAME] [--all]
  schedule          install|show|remove
  logs              [--last] [--tail=N]

Configuration

Mode Config Logs Lock
Root /etc/gniza/ /var/log/gniza/ /var/run/gniza.lock
User ~/.config/gniza/ ~/.local/state/gniza/log/ $XDG_RUNTIME_DIR/gniza-$UID.lock

Config subdirectories: targets.d/*.conf, remotes.d/*.conf, schedules.d/*.conf

Target Config (targets.d/mysite.conf)

TARGET_NAME="mysite"
TARGET_FOLDERS="/var/www,/etc/nginx"
TARGET_EXCLUDE="*.log,*.tmp,.cache"
TARGET_INCLUDE=""
TARGET_REMOTE=""
TARGET_RETENTION=""
TARGET_PRE_HOOK=""
TARGET_POST_HOOK=""
TARGET_ENABLED="yes"

# MySQL backup (optional)
TARGET_MYSQL_ENABLED="no"
TARGET_MYSQL_MODE="all"
TARGET_MYSQL_DATABASES=""
TARGET_MYSQL_EXCLUDE=""
TARGET_MYSQL_USER=""
TARGET_MYSQL_PASSWORD=""
TARGET_MYSQL_HOST="localhost"
TARGET_MYSQL_PORT="3306"
TARGET_MYSQL_EXTRA_OPTS="--single-transaction --routines --triggers"

Include vs Exclude: Set TARGET_INCLUDE to back up only matching files (e.g. *.conf,*.sh). When include is set, everything else is excluded. If only TARGET_EXCLUDE is set, matching files are skipped. Patterns are comma-separated and support rsync glob syntax.

Remote Config (remotes.d/backup-server.conf)

REMOTE_TYPE="ssh"
REMOTE_HOST="backup.example.com"
REMOTE_PORT=22
REMOTE_USER="root"
REMOTE_AUTH_METHOD="key"
REMOTE_KEY="/root/.ssh/backup_key"
REMOTE_BASE="/backups"
BWLIMIT=0
RETENTION_COUNT=30

For local remotes (USB/NFS):

REMOTE_TYPE="local"
REMOTE_BASE="/mnt/backup-drive"

Snapshot Structure

$BASE/<hostname>/targets/<target>/snapshots/<YYYY-MM-DDTHHMMSS>/
├── meta.json
├── manifest.txt
├── var/www/
├── etc/nginx/
└── _mysql/              # MySQL dumps (if enabled)
    ├── dbname.sql.gz
    └── _grants.sql.gz

Web Dashboard

The TUI can be served in a browser via textual-serve with HTTP Basic Auth:

# Enable during install (generates admin password)
curl -sSL .../install.sh | sudo bash
# Answer "y" to "Enable web dashboard?"

# Or manually
gniza web install-service   # Install systemd service (port 2323)
gniza web start             # Start the service
gniza web stop              # Stop the service

Access at http://<server-ip>:2323. Credentials are stored in gniza.conf as WEB_USER and WEB_API_KEY.

Testing

bash tests/test_utils.sh
bash tests/test_config.sh
bash tests/test_targets.sh

License

MIT License - see LICENSE for details.

Description
No description provided
Readme MIT 1.5 MiB
Languages
Python 48.1%
Shell 45.5%
HTML 6.4%