Mastodon

rclone with Storm Buckets

A Storm Bucket is a standard S3 endpoint. No Storm plugin, no vendor backend,
nothing to install beyond rclone. If you use rclone against Backblaze, Wasabi or
AWS, you already know how to use it here.

Every command below was run against a real bucket on the alpha endpoint.

The three values

Whichever method you pick, rclone needs the same values:

Setting Value
type s3
provider Other
endpoint your bucket's endpoint, for example https://alpha.buckets.stormdevelopments.ca
region storm, always, wherever your bucket lives
access_key_id / secret_access_key from a key you create
force_path_style true

The endpoint selects the node. The region is a literal string, the same
everywhere. Both are on the Connection panel of your bucket page; the key comes
from Managing Access Keys.

Use a read-write key scoped to the bucket, not an admin key. rclone only reads
and writes objects.

Way one: the config file

For anything you run more than once. rclone config walks you through it, or
write ~/.config/rclone/rclone.conf yourself:

[storm]
type = s3
provider = Other
endpoint = https://alpha.buckets.stormdevelopments.ca
region = storm
access_key_id = YOUR_KEY_ID
secret_access_key = YOUR_SECRET
force_path_style = true

Then:

rclone lsd storm:
rclone ls storm:your-bucket

The secret is on disk in plain text. chmod 600 ~/.config/rclone/rclone.conf.
rclone can encrypt the file if you would rather type a password each time.

Way two: environment variables

Every setting has an environment variable equivalent,
RCLONE_CONFIG_<REMOTE>_<SETTING> in capitals. Set them and the remote exists
with no config file:

export RCLONE_CONFIG_STORM_TYPE=s3
export RCLONE_CONFIG_STORM_PROVIDER=Other
export RCLONE_CONFIG_STORM_ENDPOINT=https://alpha.buckets.stormdevelopments.ca
export RCLONE_CONFIG_STORM_REGION=storm
export RCLONE_CONFIG_STORM_ACCESS_KEY_ID=YOUR_KEY_ID
export RCLONE_CONFIG_STORM_SECRET_ACCESS_KEY=YOUR_SECRET
export RCLONE_CONFIG_STORM_FORCE_PATH_STYLE=true

rclone lsd storm:

The middle part names the remote, so RCLONE_CONFIG_STORM_* gives you storm:.

Use this in a container, a CI job or a systemd unit: the credential comes from
the environment or a secrets manager and never touches the filesystem, and the
same image runs against different buckets without a rebuild.

Way three: a connection string

Everything inline, no config file and no environment:

rclone lsd ":s3,provider=Other,endpoint='https://alpha.buckets.stormdevelopments.ca',region=storm,access_key_id=YOUR_KEY_ID,secret_access_key=YOUR_SECRET,force_path_style=true:your-bucket"

Unwieldy, and the fastest way to test a key you were just handed. Also useful
in a script hitting several buckets with different credentials in one run.

The credential lands in shell history and in ps output while the command runs,
so do not schedule it. Use way two.

Path style

Storm Buckets serves path style URLs, endpoint/bucket, not virtual hosted
style, bucket.endpoint. This causes nearly every "rclone cannot see my bucket"
report.

rclone defaults force_path_style to true, so you may never hit this. The
provider value is what flips it. Answer AWS at rclone's provider prompt, a
natural pick when you are configuring an S3-compatible endpoint, and rclone
switches to virtual hosted style:

NOTICE: Failed to ls: operation error S3: ListObjectsV2,
request send failed, Get "https://your-bucket.alpha.buckets.stormdevelopments.ca/...":
dial tcp: lookup your-bucket.alpha.buckets.stormdevelopments.ca: no such host

rclone put the bucket name in front of the endpoint and asked DNS for a host
that does not exist.

The confusing part: listing buckets still works. rclone lsd storm: talks
to the endpoint itself, not to a bucket, so it succeeds even when path style is
wrong. If lsd works and ls does not, this is why.

Set force_path_style = true explicitly. It is already the default for
provider = Other, but writing it keeps the config correct if the provider
value changes.

Everyday commands

# Upload a directory, skipping files already there and unchanged
rclone copy ./site storm:your-bucket/site

# Make the destination match the source, INCLUDING deletions
rclone sync ./site storm:your-bucket/site

# See what sync would delete, before it does it
rclone sync ./site storm:your-bucket/site --dry-run

# One file to an exact object name
rclone copyto ./backup.dump storm:your-bucket/db/backup-2026-08-21.dump

# What is in there, with sizes
rclone ls storm:your-bucket

# Total size and object count
rclone size storm:your-bucket

# Delete objects older than 30 days
rclone delete storm:your-bucket/db --min-age 30d

copy adds and updates. sync also deletes anything at the destination that is
not at the source, which is why --dry-run comes first.

On a large transfer, --progress gives a live display and --transfers 8
raises parallelism. Storage is flat per TB and egress throttles rather than
billing, so a big transfer will not show up as a surprise on your invoice.

Checking a transfer arrived

Exit code zero means rclone believes it uploaded. Ask the bucket:

rclone check ./site storm:your-bucket/site

check compares sizes and hashes on both sides and reports differences.

Next steps