
Automating backups to AIOZ Storage with GitHub Actions turns a one-time migration into a recurring job, running on a schedule instead of something someone has to remember to do manually. This is a different task from a one-time migration guide, it's the same rclone remote configuration this series has already covered, wired into a GitHub Actions workflow that runs on a cron schedule instead of a single manual command. This article covers the exact workflow YAML, how to store AIOZ Storage credentials safely as GitHub secrets, and what to verify before trusting it as your actual backup mechanism.
TL;DR:
rclone sync on a cron schedule, no new tooling beyond what a manual rclone backup already uses.A cron schedule is the whole point here, backups that depend on someone remembering to run a command eventually stop happening reliably. GitHub Actions already runs on a cron trigger natively, and since AIOZ Storage's rclone remote configuration is already established elsewhere in this series, wiring it into a scheduled workflow doesn't require new tooling, just a place to run the same rclone command on a timer instead of by hand.
The access key and secret key from your AIOZ Storage access grant never belong in your repository, in the workflow file, or anywhere version-controlled. GitHub's repository secrets exist for exactly this: encrypted values, set once in your repo's settings, referenced in a workflow without ever appearing in the workflow file itself or in any log output. Add two secrets to your repository, AIOZ_ACCESS_KEY and AIOZ_SECRET_KEY, holding the values from the access grant you generated for this backup job specifically, scoped narrowly to just the bucket this workflow needs, not a broader credential reused from something else.
name: Backup to AIOZ Storage
on:
schedule:
- cron: '0 3 * * *' # daily at 03:00 UTC
workflow_dispatch: {} # allow manual runs too
jobs:
backup:
runs-on: ubuntu-latest
steps:
- name: Install rclone
run: curl https://rclone.org/install.sh | sudo bash
- name: Configure rclone remote
run: |
mkdir -p ~/.config/rclone
cat > ~/.config/rclone/rclone.conf << EOF
[aioz-storage]
type = s3
provider = Other
access_key_id = ${{ secrets.AIOZ_ACCESS_KEY }}
secret_access_key = ${{ secrets.AIOZ_SECRET_KEY }}
endpoint = https://s3.aiozstorage.network
EOF
- name: Run backup
run: rclone sync /path/to/backup-source aioz-storage:my-backup-bucket --log-file=rclone.log -v
- name: Upload log as artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: rclone-backup-log
path: rclone.logThe cron: '0 3 *' line schedules a daily run at 3 AM UTC, standard cron syntax GitHub Actions supports directly. workflow_dispatch: {} adds the ability to trigger the same job manually from the GitHub UI, useful for testing the workflow without waiting for the schedule. The rclone config gets written fresh on every run rather than committed anywhere, built entirely from the two secrets and AIOZ Storage's known endpoint, the same remote structure covered in the migration guides, just generated at runtime instead of stored in a config file on a laptop.
rclone sync makes the destination match the source exactly, including deleting anything on the destination that no longer exists on the source, which is the correct behavior for a one-directional backup job: the backup should reflect the current state of what you're protecting, not accumulate files that were deleted from the source months ago. That's meaningfully different from rclone copy, which never deletes anything on the destination, and from rclone bisync, which synchronizes changes in both directions, a genuinely different tool for a genuinely different job, covered in a companion article specifically because bisync's two-way behavior needs more care than a one-way backup does.
Before this workflow ever runs on a real schedule against real data, rclone's own documentation on sync is direct about the risk: it recommends testing first "with the --dry-run or the --interactive/i flag" before trusting it, since sync is a destructive operation, it deletes anything on the destination that doesn't exist on the source. Run the workflow once manually with --dry-run added to the sync command, confirm the file list it reports matches what you'd actually expect to be added or removed, and only then remove the flag for the real scheduled runs.
A green checkmark on the workflow run means the rclone sync command exited successfully, it doesn't on its own confirm the backup actually contains what you expect. The -v flag and the uploaded log artifact in the workflow above exist specifically so you can check what actually happened on a given run, how many files transferred, whether anything errored partway through. Worth periodically checking that log, and periodically restoring from the backup bucket to confirm the files that come back are actually usable, the same "verified recoverability" discipline that matters for any backup strategy, a scheduled job running successfully for months is not proof the data it produced would actually restore correctly if you needed it.
How do you schedule a recurring backup to AIOZ Storage?
With a GitHub Actions workflow using a schedule trigger with cron syntax, running rclone sync against an AIOZ Storage remote on each scheduled run. No AIOZ-specific tooling is required beyond the rclone remote configuration already used for manual migrations.
Where should AIOZ Storage credentials go in a GitHub Actions workflow?
In GitHub's encrypted repository secrets, referenced in the workflow as ${{ secrets.NAME }}, never committed to the repository or written directly into the workflow file.
Why use rclone sync instead of rclone copy for a backup job?rclone sync makes the destination match the source exactly, including removing files deleted from the source, which is the correct behavior for a backup meant to reflect current state. rclone copy never deletes anything on the destination, which can let a backup accumulate stale files indefinitely.
Does a successful workflow run guarantee the backup is usable?
No. A green checkmark confirms the rclone sync command exited without error, not that the resulting backup would actually restore correctly. Periodically checking the transfer log and test-restoring from the backup bucket is the only way to confirm that directly.
Can this workflow be triggered manually, not just on a schedule?
Yes, with workflow_dispatch: {} added to the workflow's triggers, which adds a manual "Run workflow" button in GitHub's UI alongside the scheduled cron trigger.
What's the difference between this and the rclone migration guides in this series?
The migration guides cover a one-time move from another S3-compatible provider to AIOZ Storage. This workflow automates a recurring backup job, the same rclone remote configuration, run repeatedly on a schedule rather than once by hand.

AIOZ Storage has no official MCP server yet. Here is a working MCP server for AIOZ Storage, built with the official Python SDK and boto3, tools included.

What is an MCP server: a standard letting AI agents like Claude use tools and data through one protocol. How MinIO and Azure apply it to object storage.

S3 access logs vs CloudTrail: AWS recommends CloudTrail, but each one catches real events the other misses. Speed, cost, and coverage, compared directly.

Eventual vs strong consistency: whether a read right after a write sees the new data immediately. S3 ran on the first model for 14 years, then changed it.

Bucket policy vs IAM policy: one attaches to the resource, one attaches to the identity. What each can do that the other can't, and how S3 evaluates both.

SSE-S3 vs SSE-KMS vs SSE-C: who manages the encryption key, and what that decision actually costs you. Includes the real 2026 default change to SSE-C.