Back

Blog details

Automating Backups to AIOZ Storage with GitHub Actions

AIOZ Network
5 min readAugust 25, 2026
aioz-storage
Server room aisle with rows of dark server racks

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:

  • A scheduled GitHub Actions workflow installs rclone, restores your rclone config from a GitHub secret, and runs rclone sync on a cron schedule, no new tooling beyond what a manual rclone backup already uses.
  • AIOZ Storage credentials belong in GitHub's encrypted repository secrets, never committed to the repo, referenced in the workflow as environment variables at runtime.
  • This is a backup job, not a migration, it should run repeatedly and safely, which means checking the sync actually completed and did what you expected, not just that the workflow returned green.

Why GitHub Actions for This

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.

Storing AIOZ Storage Credentials as GitHub Secrets

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.

The Workflow File

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.log

The 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.

Why rclone sync, Not rclone copy or bisync

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.

What to Actually Verify

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.

Frequently Asked Questions

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.

References

We only send updates when meaningful changes ship, and you can unsubscribe anytime

Related Content

blog thumbnail

How to Build an MCP Server for AIOZ Storage, Step by Step

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.

aioz-storage
6 min readSeptember 19, 2026
blog thumbnail

What Is an MCP Server? How AI Agents Access Storage

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.

aioz-storage
6 min readSeptember 16, 2026
blog thumbnail

S3 Access Logs vs CloudTrail: Which Should You Use?

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

aioz-storage
5 min readSeptember 15, 2026
blog thumbnail

Eventual vs Strong Consistency: How S3 Made the Switch

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.

aioz-storage
6 min readSeptember 14, 2026
blog thumbnail

Bucket Policy vs IAM Policy: What Is the Real Difference?

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.

aioz-storage
6 min readSeptember 13, 2026
blog thumbnail

SSE-S3 vs SSE-KMS vs SSE-C: S3 Encryption Types Explained

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.

aioz-storage
6 min readSeptember 12, 2026