Raff Object Storage exposes an S3-compatible API, so rclone can use its S3 backend to copy, sync, verify, restore, and automate file transfers against https://s3.raffusercloud.com. This tutorial keeps Raff's current compatibility limits in mind: standard object operations, multipart uploads, SigV4, bucket ACLs/policies, and common S3 tooling are supported, while object versioning, lifecycle rules, Object Lock, cross-region replication, and static website hosting are not currently supported.
Raff Technologies uses us-east as the product-region label, but S3-compatible clients use us-east-1 as the signing region. Those are not interchangeable UI labels. For rclone, use provider = Other, endpoint https://s3.raffusercloud.com, signing region us-east-1, and virtual-hosted-style requests with force_path_style = false.
This tutorial also separates file mirroring from backup history. rclone sync makes the destination match the source and can delete destination objects. Because Raff Object Storage does not currently provide object versioning, a destructive sync is not a complete backup strategy. Use copy to immutable/timestamped backup artifacts when you need historical recovery points.
The saved test note remains Ubuntu 24.04 LTS on Raff 1 vCPU / 2 GB RAM VM. This revision re-verifies rclone installation, S3 configuration, integrity checking, multipart behavior, sync safety, restore testing, optional client-side encryption, and systemd automation against current rclone documentation and Raff's current Object Storage behavior without claiming a new end-to-end machine test.
Prerequisites:
- Ubuntu 24.04 with SSH and sudo access
- A Raff Object Storage bucket
- A bucket-scoped read-write access key where possible
- The bucket name, access key ID, and secret key stored securely
- Enough local space for any restore test you plan to run
Step 1 — Check the Ubuntu package and current rclone release
Inspect the Ubuntu package candidate first:
sudo apt update apt-cache policy rclone
Ubuntu 24.04 currently carries the 1.60.1 branch with Ubuntu security/maintenance patches, while the current upstream stable rclone release is newer. For an S3 workflow where current backend fixes and current commands matter, this tutorial uses rclone's official stable installer rather than the older distro feature level.
Check whether rclone is already installed:
command -v rclone || true rclone version 2>/dev/null || true
If your organization standardizes on Ubuntu packages, the distro package can still perform basic S3 copy/sync operations. Just do not assume an Ubuntu package version exposes every command documented by current rclone.
Verify: You should know whether the machine already has rclone, which version it runs, and whether you intend to stay on Ubuntu's older package or use current upstream stable.
Step 2 — Install the current stable rclone release
Download the official installer to a local file instead of piping an unseen script directly into a privileged shell:
curl -fsSLo /tmp/rclone-install.sh https://rclone.org/install.sh
Review the script before running it:
less /tmp/rclone-install.sh
Install the current stable release:
sudo bash /tmp/rclone-install.sh rm -f /tmp/rclone-install.sh
Verify the installed version:
rclone version
The stable release page should match the major/minor version reported by the binary.
Verify: rclone version should run successfully and report the current stable branch you intentionally installed.
Step 3 — Create a protected rclone configuration file
Because the tutorial later uses systemd, keep one explicit root-owned config path:
sudo install -d -m 700 /etc/rclone sudo touch /etc/rclone/raff-rclone.conf sudo chmod 600 /etc/rclone/raff-rclone.conf
Start rclone's interactive configurator:
sudo rclone config --config /etc/rclone/raff-rclone.conf
Create a new remote named raffs3 with these values:
Storage type: s3 Provider: Other Use environment credentials: false Access key ID: YOUR_RAFF_ACCESS_KEY Secret access key: YOUR_RAFF_SECRET_KEY Region: us-east-1 Endpoint: https://s3.raffusercloud.com Location constraint: leave empty ACL: private Advanced config: yes force_path_style: false
Raff supports virtual-hosted-style S3 URLs, so force_path_style = false is intentional. Use bucket names without periods for the cleanest HTTPS virtual-host compatibility.
Do not print the full config with rclone config show; that command can expose sensitive values.
Verify only the remote name:
sudo rclone listremotes --config /etc/rclone/raff-rclone.conf
Expected output includes:
raffs3:
If your installed rclone supports it, inspect a redacted view:
sudo rclone config redacted raffs3 \ --config /etc/rclone/raff-rclone.conf
Double-check even redacted output before pasting it into support tickets.
Verify: /etc/rclone/raff-rclone.conf should be mode 600, raffs3: should exist, the endpoint should be Raff's HTTPS endpoint, region should be us-east-1, and force_path_style should be false.
Step 4 — Test the existing bucket and scoped permissions
Set the bucket name for this shell session:
BUCKET="YOUR_BUCKET_NAME"
List that bucket directly:
sudo rclone lsf "raffs3:${BUCKET}" \ --config /etc/rclone/raff-rclone.conf \ --max-depth 1
An empty bucket can produce no object lines while still returning successfully.
Do not treat a failed global bucket listing as an authentication failure if your key is intentionally bucket-scoped. Test the intended bucket path instead.
Create a harmless prefix directory marker only if you need a write test:
sudo rclone mkdir "raffs3:${BUCKET}/rclone-tutorial" \ --config /etc/rclone/raff-rclone.conf
Verify: The bucket-specific command should complete without signature errors. Permission-denied responses should only occur for operations the scoped key is intentionally not allowed to perform.
Step 5 — Upload and download one file before using sync
Create a small local test file:
mkdir -p ~/raff-rclone-demo printf 'Raff Object Storage rclone verification\n' \ > ~/raff-rclone-demo/verify.txt
Upload it with copyto so the destination key is explicit:
sudo rclone copyto \ ~/raff-rclone-demo/verify.txt \ "raffs3:${BUCKET}/rclone-tutorial/verify.txt" \ --config /etc/rclone/raff-rclone.conf \ --progress
List the object:
sudo rclone lsl "raffs3:${BUCKET}/rclone-tutorial/verify.txt" \ --config /etc/rclone/raff-rclone.conf
Download it to a different local file:
sudo rclone copyto \ "raffs3:${BUCKET}/rclone-tutorial/verify.txt" \ ~/raff-rclone-demo/verify-restored.txt \ --config /etc/rclone/raff-rclone.conf
Compare the files:
cmp ~/raff-rclone-demo/verify.txt \ ~/raff-rclone-demo/verify-restored.txt \ && echo 'Upload/download verification passed'
Verify: The uploaded object should be listed, the restored file should download successfully, and cmp should report Upload/download verification passed.
Step 6 — Use rclone check for integrity verification
Rclone's S3 backend validates uploads with HTTP/S3 checksums and object metadata where available. For an additional comparison between local source and remote destination, use rclone check:
sudo rclone check \ ~/raff-rclone-demo \ "raffs3:${BUCKET}/rclone-tutorial" \ --config /etc/rclone/raff-rclone.conf \ --one-way
The --one-way flag requires each local source object to match a remote object but ignores extra objects already present remotely.
S3 ETags are not always plain MD5 hashes, especially for multipart uploads or objects written by other tools. If you need a full content verification independent of remote hash metadata, use:
sudo rclone check \ ~/raff-rclone-demo \ "raffs3:${BUCKET}/rclone-tutorial" \ --config /etc/rclone/raff-rclone.conf \ --one-way \ --download
--download reads object data and can consume network/egress, so use it deliberately on large datasets.
Verify: A normal rclone check should report no differences for files uploaded by this workflow; a targeted --download check should also complete without mismatch for the test data.
Step 7 — Understand multipart uploads before tuning performance
Rclone automatically uses multipart upload above its S3 upload cutoff. Multipart is required for large S3 objects and is already supported by Raff Object Storage.
Do not blindly increase concurrency. Multipart memory consumption grows approximately with:
transfers × s3-upload-concurrency × s3-chunk-size
Inspect current S3 defaults supported by your installed rclone:
rclone help backend s3 | \ grep -E 'upload-cutoff|chunk-size|upload-concurrency' -A2
For most backup/file-transfer jobs, start with rclone defaults. Increase --s3-upload-concurrency or --s3-chunk-size only after measuring a large-file workload and checking memory headroom.
Do not set --s3-disable-checksum or --s3-no-head just to make uploads appear faster; those options reduce integrity verification.
Verify: The workflow should use default multipart/checksum behavior unless you have measured evidence and enough RAM to justify tuning it.
Step 8 — Use copy for non-destructive uploads
Create a small directory tree:
mkdir -p ~/raff-rclone-demo/assets ~/raff-rclone-demo/logs printf 'asset\n' > ~/raff-rclone-demo/assets/app.txt printf 'log line\n' > ~/raff-rclone-demo/logs/app.log
Use copy when destination-only objects must not be deleted:
sudo rclone copy \ ~/raff-rclone-demo \ "raffs3:${BUCKET}/copy-demo" \ --config /etc/rclone/raff-rclone.conf \ --progress
List the result:
sudo rclone lsf "raffs3:${BUCKET}/copy-demo" \ --config /etc/rclone/raff-rclone.conf \ --recursive
copy uploads new/changed source files but does not remove extra destination objects. That makes it the safer default for one-way upload workflows.
Verify: All source files should appear under copy-demo, and an unrelated destination-only object would remain untouched.
Step 9 — Preview sync and cap destructive deletes
rclone sync makes the destination match the source, including deleting destination objects that are absent from the source. Rclone's own documentation recommends testing destructive syncs with --dry-run or interactive mode first.
Create a dedicated mirror source:
mkdir -p ~/raff-rclone-mirror printf 'one\n' > ~/raff-rclone-mirror/one.txt printf 'two\n' > ~/raff-rclone-mirror/two.txt
Preview the first sync:
sudo rclone sync \ ~/raff-rclone-mirror \ "raffs3:${BUCKET}/mirror-demo" \ --config /etc/rclone/raff-rclone.conf \ --dry-run \ --combined -
If the preview is correct, run the first real sync:
sudo rclone sync \ ~/raff-rclone-mirror \ "raffs3:${BUCKET}/mirror-demo" \ --config /etc/rclone/raff-rclone.conf
Now remove one local file and preview again with a delete guard:
rm ~/raff-rclone-mirror/two.txt sudo rclone sync \ ~/raff-rclone-mirror \ "raffs3:${BUCKET}/mirror-demo" \ --config /etc/rclone/raff-rclone.conf \ --dry-run \ --max-delete 10 \ --combined -
Only run the real destructive sync when the deletion list is expected.
Because Raff Object Storage does not currently support object versioning, a deleted or overwritten destination key does not automatically leave a recoverable prior version. A mirror is therefore not the same thing as a historical backup.
Verify: The dry run should explicitly show the planned delete, and no real delete should occur until you intentionally remove --dry-run after reviewing the output.
Step 10 — Use immutable or timestamped backup objects for recovery history
If your application already creates timestamped backup archives, upload them with copy rather than mirroring a mutable directory.
Example local backup files:
sudo install -d -m 700 /var/backups/app STAMP="$(date -u +%Y%m%dT%H%M%SZ)" echo 'example backup payload' | \ sudo tee "/var/backups/app/app-${STAMP}.tar" >/dev/null sudo chmod 600 "/var/backups/app/app-${STAMP}.tar"
Upload without deleting older remote backups:
sudo rclone copy \ /var/backups/app \ "raffs3:${BUCKET}/backups/app" \ --config /etc/rclone/raff-rclone.conf \ --include 'app-*.tar'
List the backup prefix:
sudo rclone lsl "raffs3:${BUCKET}/backups/app" \ --config /etc/rclone/raff-rclone.conf
Retention must be an explicit operational decision. Raff Object Storage does not currently support S3 lifecycle expiration, so do not imply that old objects will age out automatically. For retention policies and safe cleanup planning, see S3 Lifecycle Policy: Retention, Versioning, and Cleanup; it also explains the distinction between native S3 lifecycle features and application-managed retention.
Verify: The new timestamped backup object should exist remotely without deleting earlier backup objects, and your retention process should be documented separately.
Step 11 — Restore into a clean directory and verify content
Create a disposable restore directory:
rm -rf ~/raff-rclone-restore-test mkdir -p ~/raff-rclone-restore-test
Restore the non-destructive copy demo:
sudo rclone copy \ "raffs3:${BUCKET}/copy-demo" \ ~/raff-rclone-restore-test \ --config /etc/rclone/raff-rclone.conf
Compare source and restore:
sudo rclone check \ ~/raff-rclone-demo \ ~/raff-rclone-restore-test \ --one-way
For recovery-critical data, inspect representative files and application-level validity, not just object counts.
Verify: The restored directory should contain the expected files and rclone check should report no mismatches for the files you intended to recover.
Step 12 — Optionally add client-side encryption with an rclone crypt remote
Raff Object Storage already uses HTTPS in transit. If you also want rclone-managed client-side encryption before upload, wrap a dedicated S3 prefix with an rclone crypt remote.
Create a dedicated underlying path such as:
raffs3:YOUR_BUCKET_NAME/encrypted-backups
Start the interactive configurator:
sudo rclone config --config /etc/rclone/raff-rclone.conf
Create a new remote named raffcrypt:
Storage type: crypt Remote to encrypt: raffs3:YOUR_BUCKET_NAME/encrypted-backups Filename encryption: standard Directory name encryption: true Password: generate or enter a strong unique password Password2/salt: generate or enter a different strong value
Store the encryption password(s) outside the VM in a password manager or recovery record. Rclone notes that crypt passwords stored in the config are only lightly obscured unless the config itself is encrypted. Losing the crypt credentials can make the encrypted objects unrecoverable.
Upload through the crypt remote:
sudo rclone copy \ /var/backups/app \ raffcrypt: \ --config /etc/rclone/raff-rclone.conf
Verify encrypted data with cryptcheck, not normal checksum comparison against the wrapped S3 objects:
sudo rclone cryptcheck \ /var/backups/app \ raffcrypt: \ --config /etc/rclone/raff-rclone.conf
Do not mix plaintext writes directly into the same underlying encrypted-backups prefix.
Verify: raffcrypt: should list readable plaintext names through rclone, the raw raffs3:.../encrypted-backups path should contain encrypted objects, and the crypt credentials should be stored in a separate recovery location.
Step 13 — Automate a non-destructive upload with systemd
For automation, prefer copy of already-created backup artifacts over sync unless you truly want mirror semantics.
Create the script:
sudo tee /usr/local/sbin/rclone-raff-backup-upload.sh >/dev/null <<'EOF' #!/usr/bin/env bash set -euo pipefail CONFIG=/etc/rclone/raff-rclone.conf SOURCE=/var/backups/app DEST=raffs3:YOUR_BUCKET_NAME/backups/app /usr/bin/rclone copy "$SOURCE" "$DEST" \ --config "$CONFIG" \ --include 'app-*.tar' \ --log-level INFO \ --stats 30s /usr/bin/rclone lsf "$DEST" \ --config "$CONFIG" \ --max-depth 1 EOF sudo chown root:root /usr/local/sbin/rclone-raff-backup-upload.sh sudo chmod 750 /usr/local/sbin/rclone-raff-backup-upload.sh
Replace YOUR_BUCKET_NAME before running it.
Test manually:
sudo /usr/local/sbin/rclone-raff-backup-upload.sh
Create a oneshot service:
sudo tee /etc/systemd/system/rclone-raff-backup-upload.service >/dev/null <<'EOF' [Unit] Description=Upload backup artifacts to Raff Object Storage with rclone Wants=network-online.target After=network-online.target [Service] Type=oneshot ExecStart=/usr/local/sbin/rclone-raff-backup-upload.sh EOF
Create a daily timer:
sudo tee /etc/systemd/system/rclone-raff-backup-upload.timer >/dev/null <<'EOF' [Unit] Description=Run Raff Object Storage backup upload daily [Timer] OnCalendar=*-*-* 03:15:00 Persistent=true RandomizedDelaySec=15m Unit=rclone-raff-backup-upload.service [Install] WantedBy=timers.target EOF
Enable it:
sudo systemctl daemon-reload sudo systemctl enable --now rclone-raff-backup-upload.timer
Verify: The script should succeed manually, systemctl list-timers rclone-raff-backup-upload.timer should show a next run, and the service should use copy, not an unreviewed destructive sync.
Step 14 — Run the final end-to-end verification and clean up only test data
Verify the remote, sample object, backup path, and timer:
rclone version sudo rclone listremotes \ --config /etc/rclone/raff-rclone.conf sudo rclone lsl "raffs3:${BUCKET}/rclone-tutorial" \ --config /etc/rclone/raff-rclone.conf sudo rclone lsl "raffs3:${BUCKET}/backups/app" \ --config /etc/rclone/raff-rclone.conf systemctl list-timers rclone-raff-backup-upload.timer
Confirm the design:
- endpoint is
https://s3.raffusercloud.com; - signing region is
us-east-1; provider = Other;force_path_style = false;- the config file is root-only;
copyis used for non-destructive backup upload;syncis only used when mirror/delete semantics are intentional;- destructive syncs are previewed first;
- recovery is tested into a clean directory;
rclone checkor a targeted--downloadcheck is used when integrity assurance matters;- optional crypt credentials are stored independently;
- no workflow depends on object versioning or lifecycle rules.
Remove only tutorial test prefixes if you are certain they contain no production data:
sudo rclone purge "raffs3:${BUCKET}/rclone-tutorial" \ --config /etc/rclone/raff-rclone.conf \ --dry-run
Review the output, then remove --dry-run only if the destination is correct. Do not purge backups/app unless those backup objects are disposable.
Verify: The production bucket should retain all intended data, only explicitly reviewed tutorial objects should be removed, and at least one verified recovery path should remain documented.
Troubleshooting
SignatureDoesNotMatch or authentication errors
Confirm the endpoint and signing region in the redacted config:
sudo rclone config redacted raffs3 \ --config /etc/rclone/raff-rclone.conf
Expected values include:
provider = Other region = us-east-1 endpoint = https://s3.raffusercloud.com force_path_style = false
Do not paste unredacted credentials into support channels.
Bucket access works in one tool but not rclone
Check whether the bucket name contains periods and whether rclone is using virtual-hosted requests. For Raff, prefer DNS-safe bucket names without periods and keep force_path_style = false.
rclone sync wants to delete unexpected files
Stop. Keep --dry-run enabled and inspect --combined - output. Confirm source/destination direction, filters, and prefix spelling. Use copy instead if destination-only objects must survive.
rclone check cannot use a useful remote hash
Multipart objects and objects written by other clients may not expose an MD5-compatible ETag. Use a targeted rclone check --download when you need content verification independent of remote hash metadata.
Large uploads consume too much RAM
Reduce transfers, S3 upload concurrency, or chunk size. Multipart memory use scales with transfers × upload concurrency × chunk size. Return to defaults before tuning further.
An interrupted upload leaves multipart data behind
Inspect unfinished multipart uploads before deleting anything:
sudo rclone backend list-multipart-uploads \ "raffs3:${BUCKET}" \ --config /etc/rclone/raff-rclone.conf
Rclone also supports cleanup of old unfinished multipart uploads. Preview cleanup with --dry-run or interactive mode before removing pending uploads.
Encrypted backups cannot be opened
Use the raffcrypt: remote and confirm you have the original crypt password and salt. Do not point a newly configured crypt remote with different credentials at existing encrypted objects and expect them to decrypt.
Conclusion
You configured current rclone for Raff S3-compatible Object Storage, kept credentials in a protected config, used the correct endpoint and signing region, verified upload/download integrity, separated copy from destructive sync, tested restores, accounted for multipart behavior, optionally added client-side crypt encryption, and automated non-destructive backup uploads with systemd.
The most important operational rule is that object synchronization and backup history are different. Raff Object Storage does not currently provide object versioning or lifecycle expiration, so use immutable/timestamped backup objects and explicit retention when previous recovery points matter.
Continue with How to Use Raff S3-Compatible Object Storage with AWS CLI, Automate Backups with Cron and Rsync on Ubuntu 24.04, and Back Up PostgreSQL to Raff Object Storage with Restic.
