Disks, not paths.

Put and get files on named disks — local, memory, or S3 and the services that speak it, like Cloudflare R2 and MinIO.

What you get

  • A default disk through the Storage facade, named disks through Storage::disk.
  • Disks declared once at boot; the call site does not know which backend it has.
  • A memory disk for tests.

In the docs

src/app/http/controllers/avatar_controller.rs
use rainier_framework::facades::Storage;

// The default disk: local, memory or S3 — and anything that speaks S3.
Storage::instance().put("avatars/7.png", bytes).await?;
let avatar = Storage::instance().get("avatars/7.png").await?;

// A named one, declared once at boot.
Storage::disk("archive").unwrap().put("2026/report.pdf", bytes).await?;

Up close

Select an image to see it full size.

A path that tries to climb out of the disk is refused rather than resolved.
A disk that cannot sign a URL says so: temporary_url on the local disk is an error, never a public link passed off as an expiring one.
All features

Type to search 2.0.0 docs.