Mirror your bucket.
Keep the history.
Back up any S3-compatible bucket into Git with a full change history.
Works with any S3-compatible storage
Common use cases
This template is useful anytime an app stores its sync data in an S3-compatible bucket and you want a separate Git-based backup history.
Obsidian sync bucket backup
Your Obsidian plugin syncs vault data to S3-compatible storage. This template mirrors that bucket into Git so older versions stay recoverable.
Joplin sync bucket backup
Your Joplin sync target lives in S3-compatible storage. This template keeps a versioned backup trail outside the live sync system.
Setup in 3 steps
ENABLE_NIGHTLY_SYNC=true.
Sync and backup are not the same thing
Sync keeps the latest version of your data available across devices. Backup gives you older states you can inspect or recover when something changes unexpectedly.
If a file is deleted, overwritten, or corrupted, sync can spread that state quickly. This template adds a separate Git history so you have a backup trail outside the live sync path.
Sync
Keeps files consistent across devices. It reflects the current state of your bucket, not a backup timeline.
Backup (this template)
Saves changes into Git over time. You get point-in-time recovery, a deletion trail, and version history.
How it works
GitHub Actions checks your bucket, downloads only what changed, and commits those changes to your backup repository. After setup, it can run nightly on its own.
ENABLE_NIGHTLY_SYNC to true so scheduled runs are allowed.
What you need
Create a repo from this template, then add the required secrets and repository variables in GitHub. You should not need to edit any code.
Secrets
-
S3_ACCESS_KEY_IDYour storage access key -
S3_SECRET_ACCESS_KEYYour storage secret key
Repository Variables
-
S3_BUCKET_NAMEBucket to mirror -
S3_ENDPOINT_URLCustom endpoint (R2, MinIO, Ceph) -
S3_REGIONRegion; defaults to us-east-1 -
ENABLE_NIGHTLY_SYNCSet totrueafter your first successful manual run
Where to add them
Settings.
Secrets and variables → Actions → Secrets, then create S3_ACCESS_KEY_ID and S3_SECRET_ACCESS_KEY.
Actions area, open Variables and add S3_BUCKET_NAME, S3_ENDPOINT_URL, and S3_REGION. Add ENABLE_NIGHTLY_SYNC=true after your first successful manual run.
GitHub constraints
This backup runs on GitHub Actions and stores history in a Git repository, so a few GitHub limits matter.
Private vs public repository
For personal backups, use a private repository unless you want your synced files and their full history to be public. GitHub-hosted Actions are free on standard runners for public repositories, while private repositories use your plan's included minutes and storage and may incur charges if you go over quota.
Repository size
GitHub currently recommends keeping a repository under 10 GB on disk. This setup is best for notes, documents, and other moderate-sized backups, not for very large media archives.
Large files
GitHub enforces a 100 MB maximum for a single Git object and a 2 GB push size limit. If your bucket contains large binaries, this repository can become a poor fit quickly.
Current GitHub limits and billing details: Actions billing · Repository limits
Ready to set up your backup?
Create a repo from the template, add your bucket settings, and run the first backup from GitHub Actions.
Use this template