diff --git a/paperless-ngx_backup b/paperless-ngx_backup new file mode 100755 index 0000000..5189ea9 --- /dev/null +++ b/paperless-ngx_backup @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 + +import gotify +import json +import subprocess +import os +from pathlib import Path + + +def read_config(): + source_path = Path(__file__).resolve() + secrets = source_path.parent / "secrets/paperless.json" + with open(secrets, "r") as f: + config = json.load(f) + return config + + +class BackupManager: + def __init__(self): + self._config = read_config() + self._gotify = gotify.Gotify(self._config["GOTIFY_TOKEN"]) + + def export_data(self): + cmd = "docker compose exec -it webserver document_exporter ../export -d -f" + try: + result = subprocess.run(cmd, shell=True, text=True, check=True, capture_output=True) + except subprocess.CalledProcessError as e: + self._gotify.send_error( + "❗💀❗ Exporting data failed", + f"stdout:\n{e.stdout}\nstderr:\n{e.stderr}", + ) + return False + return True + + + def borg_backup(self): + backup_dirs = " ".join(self._config["BACKUP_DIRS"]) + exclude_dirs = " ".join(self._config["EXCLUDE_DIRS"]) + repo_subdir = self._config["REPO_SUBDIR"] + time_format = self._config["TIME_FORMAT"] + backup_user = self._config["BACKUP_USER"] + hostname = os.uname().nodename + borg_env = os.environ.copy() + borg_env["BORG_RSH"] = "ssh -i /home/lennartalff/.ssh/borg.ed25519" + borg_env["BORG_PASSPHRASE"] = self._config["BORG_PASSPHRASE"] + repo = f"ssh://{backup_user}@{backup_user}.your-storagebox.de:23/./backups/{hostname}/{repo_subdir}::{{{time_format}}}" + cmd = f"borg create -v --stats {repo} {backup_dirs} --exclude {exclude_dirs}" + try: + result = subprocess.run( + cmd, + shell=True, + check=True, + text=True, + capture_output=True, + env=borg_env, + ) + except subprocess.CalledProcessError as e: + self._gotify.send_error( + title="❗💀❗ Backup failed!", + text=f"stdout: \n{e.stdout}\nsterr: \n{e.stderr}", + ) + return False + text = "\n".join([result.stdout, result.stderr]) + self._gotify.send_info("✅ Backup completed", f"Result:\n{text}\n") + return True + + +def main(): + config = read_config() + os.chdir(config["BACKUP_DOCKER_DIR"]) + backup_manager = BackupManager() + if not backup_manager.export_data(): + exit(1) + if not backup_manager.borg_backup(): + exit(1) + exit(0) + + +if __name__ == "__main__": + main() + diff --git a/paperless.json.sample b/paperless.json.sample new file mode 100644 index 0000000..81be49b --- /dev/null +++ b/paperless.json.sample @@ -0,0 +1,13 @@ +// vim: ft=jsonc +// put this file into the secrets subdir +{ + "BORG_RSH": "ssh -i /home/lennartalff/.ssh/borg.ed25519", + "BORG_PASSPHRASE": "the passphrase", + "GOTIFY_TOKEN": "gotify token", + "BACKUP_DOCKER_DIR": "path to the docker compose file", + "BACKUP_DIRS": ["list of directories to backup"], + "REPO_SUBDIR": "paperless-ngx", + "BACKUP_USER": "u433234", + "EXCLUDE_DIRS": ["list of directories to exclude"], + "TIME_FORMAT": "utcnow:%Y-%m-%d_%H:%M:%S" +}