SLD-Filebackups-py

Usage of the sld-filebackups-py

Description

A lightweight, zero-dependency Python backup utility that archives files and folders defined in a JSON list, with automatic rotation of old backups. Designed to run as a daily cron job on Linux servers.

Features

Project Structure

📁 backups_script/
├── 🐍 script.py           # Entry point and CLI argument parser
├── 🐍 functions.py        # Core logic: backup, rotation, checks
├── 🐍 constants.py        # Shared state: paths, loaded config, timestamps
├── 🐍 logger.py           # Logging setup (console + optional file handler)
├── 🐍 init.py             # Environment selector (local / prod)
├── 🧰 config.json         # Runtime configuration
├── 🧰 dir_backups.json    # Declarative list of paths to back up
└── ⭐ LICENSE             # GNU GPL v3

Module Responsibilities

FileRole
init.pyDefines ROOT_DIR_APP and ROOT_DIR_BACKUPS based on the selected environment. Imported first by everything else.
constants.pyBuilds all derived paths (backup folder, config paths), loads config.json and dir_backups.json into memory, captures today's date and current time.
logger.pyReads config.json directly and configures the root Python logger with a StreamHandler (always on) and an optional FileHandler.
functions.pyContains all business logic: default_backup_dir(), check_existing_folders(), backups_now(), autorotate_backups(), show_enabled().
script.pyBootstraps logging, then parses CLI arguments and calls the appropriate function(s). With no flags, runs a full backup + rotation.

How It Works

  1. script.py calls setup_logger(), which reads config.json and sets up logging.
  2. default_backup_dir() ensures the root backup folder and the host-named subfolder exist.
  3. check_existing_folders() reads dir_backups.json, filters for enabled entries (flag == 1), verifies each path exists, and classifies it as "folder" or "file". Empty or unreadable directories are excluded.
  4. backups_now() iterates the verified paths:
    • For folders: creates a #NAME_YYYY-MM-DD.tar.gz archive using Python's tarfile module.
    • For files: creates a #NAME_YYYY-MM-DD.gz compressed copy using gzip + shutil.copyfileobj.
    • If the target archive already exists today, the entry is skipped.
  5. autorotate_backups() scans each immediate subfolder of the host backup directory, sorts .gz files by modification time (newest first), and deletes any beyond the keep_backups threshold.

Installation

No packages to install. The script uses Python's standard library only.

  git clone https://gitea.sld-server.org/sld-admin/sld-filebackups-py.git
  cd sld-filebackups-py

Then set your environment and paths in init.py and dir_backups.json.

Configuration

config.json:

  {
    "keep_backups": 7,
    "logs": false,
    "logs_path": "/home/backups/logs"
  }
KeyTypeDefaultDescription
keep_backupsInteger 7How many recent backup archives to retain per subfolder. Older ones are deleted by the rotation step.
logsbooleanfalseIf true, a backup.log file is written to logs_path in addition to console output.
Kelogs_pathystring~/backups/logsDirectory where backup.log will be created. Created automatically if it does not exist.
Note:Even when logs is +false, all output is still printed to stdout/stderr, which means cron will capture it via mail or redirection as usual.

dir_backups.json:

This is the declarative list of everything to back up. Each entry is a JSON array of exactly three values:

[
    [ "/absolute/path/to/folder",  1, "BackupName"   ],
    [ "/absolute/path/to/file",    1, "ConfigBackup" ],
    [ "/path/that/is/disabled",    0, "OldEntry"     ]
]
PositionFieldDescription
0IntegerAbsolute path to the file or folder to back up.
1boolean1 = include in backup runs. 0 = skip entirely (the entry is parsed but never processed).
2stringA short identifier used as the subfolder name inside the backup destination, and as the prefix of the archive filename. Must be unique across entries.

Tips:

Environment (init.py)

  env = "local"   # Switch between: "local", "local2", "prod"
EnvironmentROOT_DIR_APPROOT_DIR_BACKUPS
local/home/sld-admin/Scrivania/backups_script/###ROOT_DIR_APP###/backups/Daily_File_Backups/
local2/home/simo-positive/Desktop/backups_script/###ROOT_DIR_APP###/backups/Daily_File_Backups/
prod/opt/sld-backups//home/backups/backups_root/Daily_File_Backups/

If an unknown value is set, the script exits immediately with an error.

Usage

# Full backup + auto-rotation (default, no flags needed)
python3 script.py

# Show which paths are enabled and which are disabled
python3 script.py --show

# Check whether declared paths exist on disk and print a status report
python3 script.py --check

# Run backup with verbose debug output
python3 script.py --debug

# Run only the rotation step (no new backups created)
python3 script.py --rotate

# Preview what rotation would delete, without actually deleting anything
python3 script.py --rotate --dry

CLI Reference

FlagLong formDescription
-s--showPrint enabled and disabled paths from dir_backups.json.
-d--debugRun backup with debug="on", which enables verbose path-checking output.
-c--checkRun check_existing_folders() and print a detailed status for each declared path.
-r--rotateRun autorotate_backups() only. Can be combined with --dry.
--dryDry-run mode for --rotate: logs candidates for deletion but deletes nothing.

Backup Storage Layout

Backups are written under:

📁 ROOT_DIR_BACKUPS/
└── 📁 HOSTNAME/
    ├── 📁 Documents/
    │   ├── Documents_2026-03-10.tar.gz
    │   ├── Documents_2026-03-11.tar.gz
    │   └── Documents_2026-03-12.tar.gz
    └── 📁 ConfigBackup/
        ├── ConfigBackup_2026-03-10.gz
        └── ConfigBackup_2026-03-11.gz

Backup Rotation

The rotation step (autorotate_backups) runs automatically after every backup, or can be triggered manually with --rotate.

Logic:

  1. Scans each immediate subfolder of ###ROOT_DIR_BACKUPS/###hostname>/.
  2. Finds all *.gz files (this covers both .gz and .tar.gz).
  3. Sorts them by modification time, newest first.
  4. Keeps the first keep_backups (default: 7) and deletes the rest.

Dry-run(--rotate --dry) logs exactly which files would be deleted, with no filesystem changes. Useful for verifying the retention setting before applying it.

Logging

All functions use Python's standard logging module via a named logger (__name__). The root logger is configured by logger.py at startup.

Running as a Cron Job

To run a full backup every day at 2:00 AM:

crontab -e
0 2 * * * /usr/bin/python3 /opt/sld-backups/script.py >> /home/backups/logs/cron.log 2>&1

Since the script always writes to stdout, cron output redirection captures the full run log even if file logging is disabled in config.json.

Requirements

License

GNU General Public License v3.0 — see LICENSE for full terms.


Details

Name: SLD-Filebackups-py

Categories: Python, Backups, Linux, Server, Scripts

Size: 124KB

Created: 14/03/2026

Updated: 14/03/2025

Autor: Simone Cusano - sld-server.org

Author Website: https://sld-server.org

Gitea Repository: Gitea Link