Mastodon

rclone with Storm Buckets

rclone treats a Storm Bucket the way it treats any S3 endpoint, because that is
what it is. There is no Storm plugin, no vendor backend, and nothing to install
beyond rclone itself. If you already use rclone against Backblaze, Wasabi, or
AWS, you already know how to use it here.

This page covers three ways to configure it, when each one is the right choice,
and the single setting that causes almost every failure people report.

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

The three values

Whichever method you pick, rclone needs the same things:

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 is what selects the node. The region is a literal string and is the
same everywhere. Get the endpoint and region from the Connection panel on your
bucket page, and the key from
Managing Access Keys.

Use a read-write key scoped to the bucket rather than an admin key. rclone only
needs to read and write objects, and a key that can also delete buckets is a key
you have to be careful with.

Way one: the config file

The default, and the right choice for anything you run more than once.

rclone config walks you through it interactively, 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 sits on disk in plain text, so treat the file accordingly:
chmod 600 ~/.config/rclone/rclone.conf. rclone can encrypt it with
rclone config if you would rather type a password each time.

Way two: environment variables

Every config value has an environment variable equivalent, named
RCLONE_CONFIG_<REMOTE>_<SETTING> in capitals. Set them and the remote exists
without any config file at all:

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 remote is named by the middle part, so RCLONE_CONFIG_STORM_* gives you
storm:.

This is the one to use in a container, a CI job, or a systemd unit, where you
want the credential to arrive from the environment or a secrets manager and
never touch the filesystem. It also means the same image runs against different
buckets without rebuilding anything.

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 worth knowing anyway. It is the fastest way to test a key you were
just handed, and it is useful in a script that talks to several buckets with
different credentials in one run.

The credential appears in your shell history and in ps output while the
command runs, so it is a poor fit for anything scheduled. Prefer way two there.

The setting that bites: path style

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

rclone defaults force_path_style to true, so you may never hit this. What flips
it is the provider value. Answer AWS at rclone's provider prompt, which is a
natural thing to 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

Read that hostname. rclone has glued the bucket name onto the front of the
endpoint and asked DNS for a name 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. The natural way to test a new remote passes, and then every command that
touches an actual bucket fails. If lsd works and ls does not, this is why.

Set force_path_style = true explicitly. It is already the default for
provider = Other, and writing it anyway means the config stays correct if the
provider value ever changes.

Everyday commands

Nothing here is Storm specific.

# 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 what makes it useful and what makes --dry-run
worth typing first.

For a large transfer, --progress gives you a live display and
--transfers 8 raises the parallelism. Storm's storage is flat per TB and
egress throttles rather than billing, so a big transfer will not produce a
surprise line on your invoice.

Checking a transfer arrived

rclone exiting 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. On a
backup that matters, this is the difference between having a copy and believing
you have one.

Next steps