From 3f9ac9f4e5610a946dd7b2e9aab4209c73b682b5 Mon Sep 17 00:00:00 2001 From: KakiFilem Team Date: Tue, 3 Feb 2026 14:22:23 +0800 Subject: [PATCH] release: v1.0.6 optional local backup retention Add optional KEEP_LOCAL_BACKUP environment variable to control local backup retention. Default behavior remains unchanged: backup files are deleted locally after successful upload, keeping deployments safe on Railway and other PaaS platforms with ephemeral storage. When KEEP_LOCAL_BACKUP=true is set, backups are preserved locally, which is useful for CLI usage, local machines, VPS, or NAS workflows. Documentation and CLI output were updated for clarity. No breaking changes. --- README.md | 23 +++++++++++++++++++---- main.py | 7 ++++++- pyproject.toml | 4 ++-- requirements.txt | 10 +++++----- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 2f1acd1..a48cbf1 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ Designed specifically as a **Railway deployment template**, with built-in suppor - 🐳 **Docker Ready** — portable, lightweight container - 🚀 **Railway Template First** — no fork required for normal usage - 🪣 **S3-Compatible Storage** — works with R2, AWS S3, Wasabi, B2, MinIO +- 💾 **Optional Local Retention** — keep backups locally for CLI, VPS, or NAS usage --- @@ -32,7 +33,9 @@ Designed specifically as a **Railway deployment template**, with built-in suppor 1. Click the **Deploy on Railway** button below 2. Railway will create a new project using the latest version of this repository 3. Add the required environment variables in the Railway dashboard -4. (Optional) Configure a cron job for your desired backup schedule +4. (Optional) Configure a cron job for your desired backup schedule + +> Railway uses ephemeral storage. Local backup files are deleted by default after upload. [![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/deploy/postgres-to-r2-backup?referralCode=nIQTyp&utm_medium=integration&utm_source=template&utm_campaign=generic) @@ -48,6 +51,7 @@ USE_PUBLIC_URL=false # Set true to use DATABASE_PUBLIC_URL DUMP_FORMAT=dump # sql | plain | dump | custom | tar FILENAME_PREFIX=backup # Backup filename prefix MAX_BACKUPS=7 # Number of backups to retain +KEEP_LOCAL_BACKUP=false # Keep backup file locally after upload (not recommended on PaaS) R2_ENDPOINT= # S3 endpoint URL R2_BUCKET_NAME= # Bucket name @@ -166,13 +170,13 @@ If you downloaded a prebuilt Docker image archive (`.tar` or `.tar.gz`), you can ```bash # Extract the archive (if compressed) -tar -xzf postgres-to-r2-backup_v1.0.4.tar.gz +tar -xzf postgres-to-r2-backup_v1.0.6.tar.gz # Load the image into Docker -docker load -i postgres-to-r2-backup_v1.0.4.tar +docker load -i postgres-to-r2-backup_v1.0.6.tar # Run the container -docker run --env-file .env postgres-to-r2-backup:v1.0.4 +docker run --env-file .env postgres-to-r2-backup:v1.0.6 ``` > Prebuilt images are architecture-specific (amd64 / arm64). @@ -225,6 +229,17 @@ When running via the CLI, environment variables are resolved in the following or This allows different folders to maintain separate backup configurations. +### Local Backup Behavior (CLI) + +By default, pg-r2-backup deletes the local backup file after a successful upload. + +To keep a local copy (recommended for local machines, VPS, or NAS): + + KEEP_LOCAL_BACKUP=true + +> Not recommended on PaaS platforms (Railway, Fly.io, Render, Heroku, etc.) +> due to ephemeral filesystems. + ### Scheduling Backups (CLI) The CLI does not run a background scheduler. Use your operating system or platform scheduler instead. diff --git a/main.py b/main.py index 6be2640..39a3818 100644 --- a/main.py +++ b/main.py @@ -22,6 +22,7 @@ R2_SECRET_KEY = os.environ.get("R2_SECRET_KEY") R2_BUCKET_NAME = os.environ.get("R2_BUCKET_NAME") R2_ENDPOINT = os.environ.get("R2_ENDPOINT") MAX_BACKUPS = int(os.environ.get("MAX_BACKUPS", 7)) +KEEP_LOCAL_BACKUP = os.environ.get("KEEP_LOCAL_BACKUP", "false").lower() == "true" BACKUP_PREFIX = os.environ.get("BACKUP_PREFIX", "") FILENAME_PREFIX = os.environ.get("FILENAME_PREFIX", "backup") DUMP_FORMAT = os.environ.get("DUMP_FORMAT", "dump") @@ -173,7 +174,11 @@ def run_backup(): log(f"[ERROR] R2 operation failed: {e}") finally: if os.path.exists(compressed_file): - os.remove(compressed_file) + if KEEP_LOCAL_BACKUP: + log("[INFO] Keeping local backup (KEEP_LOCAL_BACKUP=true)") + else: + os.remove(compressed_file) + log("[INFO] Local backup deleted") if __name__ == "__main__": log("[INFO] Starting backup scheduler...") diff --git a/pyproject.toml b/pyproject.toml index ef2a32e..a2d26ea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "pg-r2-backup" -version = "1.0.5" +version = "1.0.6" description = "PostgreSQL backup tool for Cloudflare R2 (S3 Compatible)" readme = "README.md" requires-python = ">=3.9" @@ -13,7 +13,7 @@ authors = [ { name = "Aman" } ] -license = { text = "MIT" } +license = "MIT" dependencies = [ "boto3", diff --git a/requirements.txt b/requirements.txt index 2c508a2..3637611 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ -boto3==1.42.40 -psycopg2-binary==2.9.10 -python-dotenv==1.2.1 -py7zr==1.1.0 -schedule==1.2.2 \ No newline at end of file +boto3==1.42.40 +psycopg2-binary==2.9.10 +python-dotenv==1.2.1 +py7zr==1.1.0 +schedule==1.2.2