5.3 KiB
backup.py is a CLI utility written in Python designed to backup small-scale UNIX environments
such as VPS, personal servers and workstations. It relies on tar, gpg and Python builtin
modules to copy, compress and encrypt your files.
Overview
backup.py supports two major options: --backup, to create a new backup and --extract
to extract an existing backup archive.
In order to create a backup file, you first need to create a "sources file" to specify the absolute paths to backup. For instance:
# directories end with a slash...
photos=/home/marco/Pictures/
documents=/home/marco/Documents/
# while individual files do not
wireguard=/etc/wireguard/wg0.conf
Then, you can start the backup with the following command:
$ sudo ./backup.py -V --checksum --backup sources.ini /home/marco "very_bad_pw"
Copying photos (1/3)
Computing checksums...DONE
└──Computing checksums... [██████████████████████████████] 100.0% (2/2) - (processing 'wallpaper2.jpg')
Copying documents (2/3)
Computing checksums...DONE
└──Computing checksums... [██████████████████████████████] 100.0% (7844/7844) - (processing '__init__.cpython-313.pyc')
Copying wireguard (3/3)
Computing checksums...DONE
└──Computing checksums... [██████████████████████████████] 100.0% (1/1) - (processing 'wg0.conf')
Compressing backup...DONE
└──Compressing backup... [██████████████████████████████] 100.0% (9062/9061) - (processing 'wg0.conf')
Encrypting backup...DONE
File name: '/home/marco/backup-wood-20260122.tar.gz.enc'
Checksums file: '/home/marco/backup-wood-20260122.sha256'
File size: 5533767184 bytes (5.15 GiB)
Elapsed time: 2 minutes, 10 seconds
Both the --checksum and the --verbose (-V) flags are optional. The former generates a checksum
file containing the hashes of each single file, the latter enables the verbose mode, which renders
the user interface as shown before.
To extract an existing backup, you can instead proceed as follows:
$ ./backup.py -V -c --extract backup-wood-20260122.tar.gz.enc "very_bad_pw" backup-wood-20260122.sha256
Decrypting backup...DONE
Extracting backup...DONE
└──Extracting backup... [██████████████████████████████] 100.0% (9062/9062) - (processing 'wg0.conf')
Verifying backup...DONE
└──Verifying backup... [██████████████████████████████] 100.0% (7847/7847) - (processing '__init__.cpython-313.pyc')
Backup extracted to: '/home/marco/Projects/backup.py/backup.py.tmp'
Elapsed time: 1 minute, 3 seconds
This will create a new directory named backup.py.tmp on your local path. Just like before,
the -V and the -c options are optional.
Usage
As stated before, python.py is built from scratch in modern Python (3.10+) without using
any external dependency except for tar and gpg.
The sources file follows an INI-like syntax structured using associative records between labels and absolute paths. In order words:
<label>=<path>
where:
<label>is a descriptive name of a backup entry;<path>is the absolute path to a directory or a file.
For example:
# File 'server_backup.ini'
# List directories and files to backup
#
nginx=/etc/nginx/
ssh=/etc/ssh/
www=/var/www/html/
# no slash here ----v
host_file=/etc/hosts
As you can see, individual files are specified by omitting the trailing slash at the end
of the absolute path. Comments, on the other hand, are inserted using the # token. Blank
lines are ignored.
Internally, backup.py orchestrates several UNIX utilities to create backups. In particular,
it follows the procedure listed below:
- Copy phase: uses Python
shutil.copytree()to copy files while preserving metadata and symlinks (without following them) and by ignoring special files; - Compression: creates a gzip-compressed tar archive using GNU tar;
- Encryption: encrypts the archive with GPG using AES-256 symmetric encryption;
- Checksum (optional): computes SHA256 hashes for each file in the backup archive.
The backup process creates temporary files in backup.py.tmp and backup.py.tar.gz, which are
automatically cleaned up on completion or interruption (i.e., C-c).
Old version
This implementation of backup.py is a porting of an old backup script originally written in Bash
that I developed back in 2018. While this new version should be compatible with old backup archives,
it may start to diverge at a certain point in the future. If you're experience incompatibilities and want
to revert to the original version, you can do so by visiting the
latest stable commit.
License
This software is released under GPLv3. You can obtain a copy of this license by visiting this page.
