s3://rustfs-brand/web/Templates · Web & UI

Web & UI网站与组件

The interface standard for the RustFS site, docs and Console. Import tokens/tailwind.css and any shadcn/ui project takes on the brand.
Components 16Page templates 15Stack Tailwind v4 · shadcn/uiTokens tokens/tailwind.css

Foundations for UIFoundations for UI

A 4px base, 12 columns, 1240px content; square corners, 1px rules, shadows on overlays only.

Setup

tokens/tailwind.css
globals.css · layout.tsx
/* app/globals.css */
@import "tailwindcss";
@import "./tailwind.css"; /* RustFS tokens: colours, type, radius 0, easing */

/* app/layout.tsx */
import { Archivo, Geist, Geist_Mono } from "next/font/google"

const archivo = Archivo({ subsets: ["latin"], axes: ["wdth"], variable: "--font-archivo" })
const geistSans = Geist({ subsets: ["latin"], variable: "--font-geist-sans" })
const geistMono = Geist_Mono({ subsets: ["latin"], variable: "--font-geist-mono" })

<html className={`${archivo.variable} ${geistSans.variable} ${geistMono.variable}`}>
  • Import one file. tokens/tailwind.css defines every token and sets --radius and rounded-* to 0.
  • Semantic first. Components use semantic classes such as bg-primary and border-border; scale classes only for hover and pressed.
  • Dark mode. Toggle .dark on <html>; components need no dark: variants.

Grid and breakpoints

max-w-[1240px] · px-[clamp(16px,4.2vw,64px)]
1
2
3
4
grid-cols-4 · sm:grid-cols-8 · lg:grid-cols-12
BreakpointMin widthColumnsGutterLayout
base0416pxSingle column; full-width buttons; menu nav
sm640px824pxTwo-column cards
md768px824pxFull nav; heading beside lede
lg1024px1224pxDocs sidebar; three-column cards
xl1280px1224pxContent reaches 1240px
2xl1536px1224pxContent fixed; margins grow

Spacing

4px base
14px
28px
312px
416px
624px
832px
1248px
1664px
2496px
32128px
  • Within a component 4–16px; between components 24–32px; between groups 48–64px; between sections 96–128px.
  • No values off the 4px grid, such as 13px or 18px; type sizes and line heights are exempt.

Radius, borders, elevation, focus

radius 0 · 1px · shadow-overlay · 2px ring
Radius
rounded-md · rounded-xl → 0px
Borders
border-borderdividers, cards, tables
border-strongcontrols, outline buttons
border-foregroundhover, selected, section rules
ElevationOverlays only: shadow-overlay
Focus
Link
outline 2px · offset 2px
  • Corners are always square; never use rounded-full or bring radius back through arbitrary values.
  • Cards, buttons and inputs carry no shadow; use 1px borders and surface. Overlays use shadow-overlay.
  • Focus is always focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring, on keyboard focus only, and never removed.

ComponentsComponents

Every component must cover default, hover, focus-visible, pressed and disabled states.

01Button

sm 32 · default 40 · lg 48 · icon 40
Variants
Sizes
sm · 32px
default · 40px
lg · 48px
icon · 40px
With icon
States
Default
Hover
Focus-visible
Active
Disabled
  • One primary button per view. Secondary actions use outline or secondary; destructive actions use destructive and need confirmation.
  • Labels start with a verb, within three words or six Chinese characters; icon-only buttons need an aria-label.
  • Disabled is 40% opacity; never hide a button to show it is unavailable.
components/ui/button.tsx
// components/ui/button.tsx
const buttonVariants = cva(
  [
    "relative isolate inline-flex shrink-0 items-center justify-center gap-2 overflow-hidden border border-transparent font-medium whitespace-nowrap select-none",
    "transition-[translate,background-color,border-color,color,text-decoration-color] duration-(--duration-fast) ease-standard",
    "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
    "disabled:pointer-events-none disabled:opacity-40",
  ],
  {
    variants: {
      variant: {
        default: [
          "bg-primary text-primary-foreground hover:bg-blue-600 active:bg-blue-700 hover:-translate-y-px active:translate-y-0 motion-reduce:hover:translate-y-0",
          "before:absolute before:inset-y-0 before:left-0 before:-z-10 before:w-1/3 before:-translate-x-[150%] before:-skew-x-12 before:bg-white/20",
          "hover:before:translate-x-[320%] hover:before:transition-transform hover:before:duration-(--duration-scene) hover:before:ease-emphasized motion-reduce:before:hidden",
        ],
        secondary: "bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_8%)] hover:-translate-y-px active:translate-y-0 motion-reduce:hover:translate-y-0",
        outline: "border-strong bg-background text-foreground hover:border-foreground hover:-translate-y-px active:translate-y-0 motion-reduce:hover:translate-y-0",
        ghost: "text-foreground hover:bg-surface active:bg-surface-2",
        link: "text-link underline decoration-transparent decoration-1 underline-offset-4 hover:decoration-current",
        destructive: "bg-destructive text-destructive-foreground hover:bg-[color-mix(in_oklab,var(--destructive),var(--foreground)_14%)] hover:-translate-y-px active:translate-y-0 motion-reduce:hover:translate-y-0",
      },
      size: {
        sm: "h-8 px-3 text-[13px] [&_svg]:size-3.5",
        default: "h-10 px-4 text-sm [&_svg]:size-4",
        lg: "h-12 px-5 text-[15px] [&_svg]:size-4.5",
        icon: "size-10 [&_svg]:size-4.5",
      },
    },
    compoundVariants: [{ variant: "link", class: "h-auto px-0" }],
    defaultVariants: { variant: "default", size: "default" },
  },
)

<Button>Deploy</Button>
<Button variant="outline" size="sm"><Icon name="download" />Download</Button>

02Input

40px · label · help · error

Use 3–63 lowercase letters, numbers, dots or hyphens.

https://

The S3 API listens on port 9000 by default; the Console on 9001.

Set by the cluster configuration; read-only here.

  • Labels stay visible above the field; placeholders only show a format, never replace a label.
  • Errors turn border and message danger with a square marker and say how to fix it; wire aria-invalid and aria-describedby.
  • Machine values (paths, endpoints, versions) use Geist Mono 13px; disabled fields keep their value and say why.
bucket-name-field.tsx
<div className="grid gap-2">
  <label htmlFor="bucket" className="text-sm font-medium text-foreground">Bucket name</label>
  <input id="bucket" aria-invalid={invalid} aria-describedby="bucket-help" className={cn(
    "h-10 w-full min-w-0 border border-input bg-background px-3 text-sm text-foreground placeholder:text-faint",
    "transition-colors duration-(--duration-fast) ease-standard hover:border-faint",
    "focus-visible:border-ring focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
    "aria-invalid:border-danger aria-invalid:focus-visible:outline-danger",
    "disabled:cursor-not-allowed disabled:border-border disabled:bg-surface disabled:text-faint",
  )} />
  {invalid ? (
    <p id="bucket-help" className="flex items-center gap-2 text-[13px] leading-normal text-danger">
      <i className="size-2 shrink-0 bg-danger" />Use 3–63 lowercase letters, numbers, dots or hyphens.
    </p>
  ) : (
    <p id="bucket-help" className="text-[13px] leading-normal text-muted-foreground">3–63 characters.</p>
  )}
</div>

<div className={cn(
  "flex h-10 items-stretch border border-input bg-background transition-colors duration-(--duration-fast) ease-standard hover:border-faint",
  "focus-within:border-ring focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-ring",
)}>
  <span className="grid place-items-center border-r border-border bg-surface px-3 font-mono text-xs text-muted-foreground">https://</span>
  <input className="min-w-0 flex-1 bg-transparent px-3 font-mono text-[13px] text-foreground placeholder:text-faint focus-visible:outline-none" />
</div>

03Select and segmented control

select · radix ToggleGroup
Time range

Showing the last 24 hours.

  • 2–5 visible exclusive options use a segmented control; more use a select, beyond seven a searchable combobox.
  • The selected segment is filled with the foreground colour, never blue, which reads as a primary button.
  • The chevron is a 1.5px square-capped stroke, matching the icon set.
storage-class.tsx · time-range.tsx
<div className="relative">
  <select className={cn(
    "h-10 w-full appearance-none border border-input bg-background pr-10 pl-3 text-sm text-foreground",
    "transition-colors duration-(--duration-fast) ease-standard hover:border-faint",
    "focus-visible:border-ring focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
  )}>
    <option>STANDARD</option>
    <option>REDUCED_REDUNDANCY</option>
  </select>
  <ChevronDown className="pointer-events-none absolute top-1/2 right-3 size-4 -translate-y-1/2 text-muted-foreground" />
</div>

// import { ToggleGroup } from "radix-ui"
<ToggleGroup.Root type="single" defaultValue="24h" className="inline-flex border border-strong">
  <ToggleGroup.Item value="1h" className={cn(
    "h-8 min-w-11 px-3 font-mono text-xs text-muted-foreground transition-colors duration-(--duration-fast) ease-standard not-first:border-l not-first:border-strong",
    "hover:text-foreground data-[state=on]:bg-foreground data-[state=on]:text-background",
    "focus-visible:relative focus-visible:z-10 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
  )}>1H</ToggleGroup.Item>
  {/* 24H · 7D · 30D */}
</ToggleGroup.Root>

04Checkbox and switch

16 × 16 · 36 × 20
Checkbox
Switch
  • Checkboxes for settings that are submitted; switches for settings that apply at once.
  • Both are square; checked fills Signal Blue, a partial selection shows a dash.
  • The whole label is clickable: at least 24px tall, 44px on touch screens.
checkbox.tsx · switch.tsx
<label className="inline-flex items-center gap-2.5 text-sm text-foreground has-disabled:text-faint">
  <span className="relative grid size-4 shrink-0 place-items-center">
    <input type="checkbox" className={cn(
      "peer absolute inset-0 appearance-none border border-input bg-background transition-colors duration-(--duration-instant) ease-standard",
      "hover:border-faint checked:border-primary checked:bg-primary indeterminate:border-primary indeterminate:bg-primary",
      "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring disabled:border-border disabled:bg-surface",
    )} />
    <Icon name="check" strokeWidth={2.5} className="pointer-events-none relative col-start-1 row-start-1 size-3.5 text-primary-foreground opacity-0 peer-checked:opacity-100" />
    <i className="pointer-events-none relative col-start-1 row-start-1 h-0.5 w-2 bg-primary-foreground opacity-0 peer-indeterminate:opacity-100" />
  </span>
  Enable versioning
</label>

<button role="switch" aria-checked={on} onClick={() => setOn(!on)} className={cn(
  "group inline-flex h-5 w-9 shrink-0 items-center border border-input bg-surface-2 p-0.5 transition-colors duration-(--duration-fast) ease-standard",
  "aria-checked:border-primary aria-checked:bg-primary disabled:opacity-40",
  "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
)}>
  <span className="size-3.5 bg-subtle transition-[translate,background-color] duration-(--duration-fast) ease-emphasized group-aria-checked:translate-x-4 group-aria-checked:bg-primary-foreground motion-reduce:transition-none" />
</button>

05Status chips and badges

8px square marker · 24px
Drive state
OnlineHealingDegradedOffline
Feature state
AvailablePreviewOpt-in
Shards
Data 12Parity 4
Badges
1.0.1LatestBuckets 12
  • Colour lives on the square marker. An 8px square, mono capitals and a 1px border; no dots, pills or tinted fills.
  • Online = success, Healing = brand, Degraded = warning, Offline = danger; the text label always stays.
  • Oxide marks parity and preview features only, once per view at most.
status-chip.tsx
const MARK = {
  online: "size-2 shrink-0 bg-success",
  healing: "size-2 shrink-0 bg-brand animate-[rfs-heal_2880ms_steps(1)_infinite]",
  degraded: "size-2 shrink-0 bg-warning",
  offline: "size-2 shrink-0 bg-danger",
  parity: "size-2 shrink-0 bg-parity",
}

<span className="inline-flex h-6 items-center gap-1.5 border border-border bg-background px-2 font-mono text-[11px] leading-none font-medium tracking-[0.06em] text-foreground uppercase">
  <i className={MARK.healing} />
  Healing
</span>

<span className="inline-flex h-6 items-center bg-foreground px-2 font-mono text-[11px] leading-none font-medium tracking-[0.06em] text-background uppercase">1.0.1</span>
<span className="inline-grid h-5 min-w-5 place-items-center bg-surface-2 px-1 font-mono text-[11px] leading-none text-foreground tabular-nums">12</span>

06Tabs

radix Tabs · h-11
Object list: key, size, last modified and storage class. · Sample data
  • The active tab has a 2px Signal Blue underline and foreground text.
  • Use 2–7 tabs; on narrow screens they scroll, never wrap or collapse into a menu.
  • Only an icon and a tabular count; no other decoration.
bucket-tabs.tsx
// import { Tabs } from "radix-ui"
<Tabs.Root defaultValue="objects">
  <Tabs.List className="flex overflow-x-auto border-b border-border [scrollbar-width:none]">
    <Tabs.Trigger value="objects" className={cn(
      "relative inline-flex h-11 shrink-0 items-center gap-2 px-3.5 text-sm text-muted-foreground transition-colors duration-(--duration-fast) ease-standard hover:text-foreground",
      "after:absolute after:inset-x-0 after:-bottom-px after:h-0.5 after:bg-transparent data-[state=active]:text-foreground data-[state=active]:after:bg-brand",
      "focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ring",
    )}>
      Objects <span className="inline-grid h-5 min-w-5 place-items-center bg-surface-2 px-1 font-mono text-[11px] leading-none text-foreground tabular-nums">128</span>
    </Tabs.Trigger>
    {/* Versions · Lifecycle · Replication */}
  </Tabs.List>
  <Tabs.Content value="objects" className="pt-5 text-sm leading-relaxed text-subtle focus-visible:outline-none">…</Tabs.Content>
</Tabs.Root>

07Code block and command bar

Geist Mono 13 / 1.65 · Ink
Command
curl -O https://rustfs.com/install_rustfs.sh && bash install_rustfs.sh
Block
Docker · README
# Create data and logs directories
mkdir -p data logs

# Change the owner of these directories
chown -R 10001:10001 data logs

docker run -d -p 9000:9000 -p 9001:9001 -v $(pwd)/data:/data -v $(pwd)/logs:/logs rustfs/rustfs:latest
  • Code always sits on Ink in Geist Mono 13px / 1.65, in both themes.
  • Commands come only from the README or official docs; comments state the result, output is never invented.
  • The $ prompt is never copied; long commands scroll, never wrap.
command-bar.tsx
const [copied, setCopied] = useState(false)

<div className="flex min-w-0 items-stretch border border-neutral-800 bg-neutral-950 text-neutral-100">
  <code className="flex min-w-0 flex-1 items-center gap-3 overflow-x-auto bg-transparent px-4 py-3 font-mono text-[13px] leading-5 whitespace-nowrap text-neutral-100 [scrollbar-width:thin]">
    <span className="text-blue-400 select-none">$</span>{command}
  </code>
  <button
    aria-label="Copy command"
    data-copied={copied}
    onClick={async () => {
      await navigator.clipboard.writeText(command)
      setCopied(true)
      toast.success("Copied")
      setTimeout(() => setCopied(false), 1600)
    }}
    className={cn(
      "grid w-11 shrink-0 place-items-center border-l border-neutral-800 text-neutral-400 transition-colors duration-(--duration-fast) ease-standard",
      "hover:bg-neutral-900 hover:text-white focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-blue-400 data-[copied=true]:text-green-500",
    )}
  >
    <Icon name={copied ? "check" : "copy"} className="size-4" />
  </button>
</div>

08Callouts

note · tip · warning · preview
Note

The container runs as UID 10001. Grant the mounted data and log directories to that user first.

Tip

The S3 API listens on port 9000 by default and the Console on 9001.

Warning

EC 4+2 tolerates at most two failed drives at once; beyond that, objects cannot be read until drives return.

Preview

S3 Tables (Iceberg REST) is a preview feature; its API may change in later releases.

  • Types differ only by the square marker (info / success / warning / parity); no side rails or tinted fills.
  • One point each, at most three sentences; two per screen at most.
  • Warnings state consequence and condition; no exclamation marks or all caps.
callout.tsx
<div role="note" className="grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 border border-border bg-surface px-4 py-3.5 text-sm leading-relaxed">
  <i className="mt-1 size-2.5 bg-warning" aria-hidden="true" />
  <b className="font-mono text-[11px] leading-[18px] font-medium tracking-[0.08em] text-foreground uppercase">Warning</b>
  <p className="col-start-2 text-subtle">EC 4+2 tolerates at most two failed drives.</p>
</div>

// note: bg-info · tip: bg-success · warning: bg-warning · preview: bg-parity

09Data table

40px rows · mono numerals right-aligned
Erasure set 1 · 6 drives EC 4+2Sample data
DriveNodeStateUsed TiBCapacity TiBUsed
/data/rustfs0node-01Online3.427.2847%
/data/rustfs1node-01Online3.397.2847%
/data/rustfs2node-02Healing1.077.2815%
/data/rustfs3node-02Degraded6.917.2895%
/data/rustfs4node-03Offline—7.28—
/data/rustfs5node-03Online3.407.2847%
  • Numbers right-aligned and tabular, units in the header or after the value; text left-aligned.
  • 40px rows, 36px header; 1px rules only, no zebra stripes.
  • Missing values show an em dash; on narrow screens the table scrolls, never the page.
drives-table.tsx
<div className="overflow-x-auto border border-border">
  <table className="w-full min-w-[640px] border-collapse text-[13px] leading-none">
    <thead>
      <tr>
        <th className="h-9 border-b border-border bg-surface px-3 text-left font-mono text-[11px] font-medium tracking-[0.06em] whitespace-nowrap text-muted-foreground uppercase">Drive</th>
        <th className="h-9 border-b border-border bg-surface px-3 text-left font-mono text-[11px] font-medium tracking-[0.06em] whitespace-nowrap text-muted-foreground uppercase text-right">Used</th>
      </tr>
    </thead>
    <tbody>
      <tr className="border-b border-border transition-colors duration-(--duration-instant) last:border-0 hover:bg-surface">
        <td className="h-10 px-3 whitespace-nowrap text-foreground font-mono">/data/rustfs0</td>
        <td className="h-10 px-3 whitespace-nowrap text-foreground text-right font-mono tabular-nums">3.42 TiB</td>
      </tr>
    </tbody>
  </table>
</div>

10Cards

1px border · 24px padding
  • The whole card is one link; on hover the border turns foreground and the arrow moves 2px.
  • Never emphasise a card with rails, shadows, gradients or rounded corners.
  • One icon, one title, one or two sentences; equal heights in a group.
feature-card.tsx
<a href="/docs/erasure-coding/" className={cn(
  "group flex flex-col gap-3 border border-border bg-card p-6 text-card-foreground",
  "transition-colors duration-(--duration-base) ease-standard hover:border-foreground",
  "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
)}>
  <span className="grid size-10 shrink-0 place-items-center border border-border text-brand [&_svg]:size-5"><Icon name="shard" /></span>
  <h3 className="mt-3 text-lg leading-snug font-semibold">Erasure coding</h3>
  <p className="text-sm leading-relaxed text-muted-foreground">…</p>
  <span className="mt-auto inline-flex items-center gap-1.5 pt-2 text-sm font-medium text-link">
    Learn more <Icon name="arrow-right" className="size-4 transition-transform duration-(--duration-base) ease-emphasized group-hover:translate-x-0.5 motion-reduce:transition-none" />
  </span>
</a>

12Announcement bar

40px · Ink
RustFS 1.0.1 is available
  • Above the navigation, on Ink, one site-wide at a time.
  • One statement and one link; never countdowns or slogans.
  • Dismissible, remembered per announcement ID; a new one shows again.
announcement.tsx
<div role="region" aria-label="Announcement" className="bg-stage text-stage-foreground">
  <div className="mx-auto flex min-h-10 max-w-[1240px] items-center gap-3 px-[clamp(16px,4.2vw,64px)] py-2 text-[13px] leading-snug">
    <Stripe className="hidden text-[6px] sm:inline-flex" />
    <a href="/blog/rustfs-1-0-1/" className="group inline-flex items-center gap-1.5 font-medium underline decoration-white/30 underline-offset-4 transition-colors hover:decoration-white">
      RustFS 1.0.1 is available <Icon name="arrow-right" className="size-3.5" />
    </a>
    <button aria-label="Dismiss" className="ml-auto grid size-8 shrink-0 place-items-center text-neutral-400 transition-colors hover:text-white">
      <Icon name="close" className="size-4" />
    </button>
  </div>
</div>

14Toast

sonner · bottom-center
Click to trigger · Sample data
  • Toasts confirm an action or report a background result; decisions need a dialog.
  • A one-line title; the description names the object and figures.
  • Success dismisses after 4s; errors stay until closed; three at most.
sonner
import { toast } from "sonner"

toast.success("Bucket created", { description: "s3://photos" })
toast.warning("Quota at 85%", { description: "s3://backups · 8.5 of 10 TiB" })
toast.error("Access denied", { description: "s3:PutObject on s3://logs" })
toast.promise(upload(file), {
  loading: "Uploading…",
  success: "Upload complete",
  error: "Upload failed",
})

15Empty state

outline shard matrix · one action

No buckets yet

A bucket holds objects and their versions. Create the first one, then upload through the S3 API or the Console.

  • Say what will appear here and offer one next step.
  • The graphic is a small outline shard matrix; no illustrations or emoji.
  • Centred: the one exception to left alignment.
empty-buckets.tsx
<div className="grid justify-items-center gap-5 border border-dashed border-strong px-6 py-12 text-center">
  <ShardMatrix cols={8} rows={3} k={8} m={0} mode="outline" className="h-12 w-auto" />
  <h3 className="text-lg font-semibold">No buckets yet</h3>
  <p className="max-w-[40ch] text-sm leading-relaxed text-muted-foreground">A bucket holds objects and their versions.</p>
  <Button><Icon name="plus" />Create bucket</Button>
</div>

16Progress and quota

Heal progress7 / 16 drives
HealingSample data
Bucket quota s3://backups6.8 / 10 TiB · 68%
Normal
  • Countable progress is drawn as shards: done is brand, active runs the heal motion, pending is an outline.
  • Quota bars have 40 cells: brand below 80%, warning from 80%, danger from 95%, with a matching chip.
  • Values read “used / total · percent” in tabular numerals; set role=progressbar and aria-valuenow.
heal-progress.tsx · quota.tsx
<div role="progressbar" aria-valuemin={0} aria-valuemax={16} aria-valuenow={7} className="grid grid-cols-[repeat(16,minmax(0,1fr))] gap-1">
  {drives.map((d) => <i key={d.id} className={SHARD[d.state]} />)}
</div>

const SHARD = {
  done: "aspect-square bg-brand",
  healing: "aspect-square animate-[rfs-heal_2880ms_steps(1)_infinite] bg-brand",
  todo: "aspect-square border border-strong",
}

// Quota: 40 cells; brand below 80%, warning from 80%, danger from 95%
<div className="grid h-3 grid-cols-[repeat(40,minmax(0,1fr))] gap-0.5">…</div>

Page sectionsPage sections

Each section has one label, one title and one graphic.

Hero A · line and shard matrix
1440 × 900 · rustfs.com home
RustFS 1.0.1 现已发布RustFS 1.0.1 is available更新说明 · github.com/rustfs/rustfs/releasesRelease notes · github.com/rustfs/rustfs/releases
产品Product文档Docs博客Blog社区Community
中 / ENGitHub 下载Download
开源对象存储Open-source object storage · Apache 2.0

AI 时代的基建,
从每一个字节算起。
AI infrastructure,
accounted for
byte by byte.

RustFS 是以 Rust 构建、兼容 S3 的分布式对象存储。
纠删码、位腐烂检测与自愈内建于每一次写入。
RustFS is distributed object storage built in Rust and compatible with S3. Erasure coding, bitrot detection and healing are built into every write.

开始使用Get started阅读文档Read the docs
$curl -O https://rustfs.com/install_rustfs.sh && bash install_rustfs.sh
The install command comes from the README and copies in one click.
Hero B · Signal statement
1440 × 900 · launch and campaign pages
产品Product文档Docs博客Blog社区Community
中 / ENGitHub 下载Download

兼容 S3。
Rust 构建。
开源。
S3-compatible.
Built in Rust.
Open source.

许可LicenseApache 2.0
最新版本Latest release1.0.1
正式版发布GA since2026-09-16
下载 1.0.1Download 1.0.1发布说明Release notes
On Signal the primary button is white with blue text; stripe parity is Ink.
Hero A · phone
390 × 844
RustFS 1.0.1 现已发布RustFS 1.0.1 is available
开源对象存储Open-source object storage · Apache 2.0

AI 时代的基建,
从每一个字节算起。
AI infrastructure, accounted for byte by byte.

以 Rust 构建、兼容 S3 的分布式对象存储。Distributed object storage built in Rust and compatible with S3.

开始使用Get started阅读文档Read the docs
$curl -O https://rustfs.com/install_rustfs.sh && bash install_rustfs.sh
Full-width 48px buttons; the install command stays on one line and scrolls.
Hero B · phone
390 × 844

兼容 S3。
Rust 构建。
开源。
S3-compatible.
Built in Rust.
Open source.

许可LicenseApache 2.0
最新版本Latest release1.0.1
正式版发布GA since2026-09-16
下载 1.0.1Download 1.0.1
The three statements keep three lines; facts stack vertically.
404 · phone
390 × 844
404 · NoSuchKey

此路径下没有对象。There is no object at this path.

页面可能已移动或删除。
请检查地址,或返回首页。
The page may have moved or been deleted. Check the address, or go back to the home page.

返回首页Back to home搜索文档Search the docs
Title and buttons sit in the lower half, within thumb reach.
Feature grid
1440 × 900
数据保护Data protection

数据保护内建于每一次写入Data protection built into every write

每个对象写入时即切分为数据块与校验块,并分散到纠删集中的各块盘。下列能力均为默认构建的一部分。Every object is split into data and parity shards as it is written and spread across the drives of an erasure set. Each capability below ships in the default build.

EC k+m

纠删码Erasure coding

对象切分为数据块与校验块;不超过校验块数量的盘故障时,对象仍可读取。Objects are split into data and parity shards; they stay readable while failures stay within the parity count.

Checksums

位腐烂检测Bitrot detection

读取时校验每个分片,发现静默损坏后从校验块恢复。Every shard is verified on read; silent corruption is repaired from parity.

Heal

自愈Healing

盘或节点恢复后,缺失的分片在后台重建。When a drive or node returns, missing shards are rebuilt in the background.

WORM

版本控制与对象锁定Versioning and Object Lock

保留对象的历史版本;以 WORM 方式锁定,满足留存要求。Keep every version; lock objects as WORM to meet retention rules.

Bucket · Site

复制Replication

存储桶复制与站点复制,在集群之间保持数据同步。Bucket and site replication keep data in step across clusters.

ILM

生命周期与分层Lifecycle and tiering

按规则使对象过期,或转储到其他存储层。Expire objects or transition them to another tier by rule.

Each item: one icon, one title, one sentence.
Stats band
1440 × 800 · figures carry a source and date
开源与社区Open source

在公开中构建Built in the open

RustFS 以 Apache 2.0 许可在 GitHub 上公开开发,任何人都可以阅读代码、提交问题与贡献补丁。RustFS is developed in the open on GitHub under Apache 2.0; anyone can read the code, file issues and contribute patches.

GitHub 星标GitHub stars34,869仓库 rustfs/rustfsRepository rustfs/rustfs
实例Instances2.7M+已部署的 RustFS 实例Deployed RustFS instances
Docker 拉取Docker pulls15.15M镜像 rustfs/rustfsImage rustfs/rustfs
提交Commits7,094主仓库提交数Commits to the main repository
数据来源:RustFS 官方网站。统计日期:2026-10-14。Source: official RustFS website. As of 2026-10-14.github.com/rustfs/rustfs
Official figures only; never “leading” or “fastest”.
Integrations wall
1440 × 900 · names as text, never third-party logos
生态Ecosystem

在现有技术栈中运行Runs in the stack you already have

凡支持 S3 API 的工具,均可将 RustFS 作为存储端点;部署与观测使用通用的开源工具。Any tool that speaks the S3 API can use RustFS as its storage endpoint; deployment and observability use common open-source tools.

部署DeployKubernetes
部署DeployDocker
指标MetricsPrometheus
看板DashboardsGrafana
反向代理ProxyNginx
计算ComputeSpark
分析AnalyticsClickHouse
机器学习MLTensorFlow
数据库备份DB backupPostgreSQL
流处理StreamingKafka
所列名称为其各自所有者的商标,仅用于说明兼容用途,不表示合作或认可关系。Names listed are trademarks of their respective owners, used only to describe compatibility; no partnership or endorsement is implied.
Imply no partnership; close with a trademark line.
Comparison block
1440 × 900
对比Comparison

选型前,核对这些事实Check these facts before you choose

项目CriterionRustFS对比对象Alternative
许可LicenseApache License 2.0待填:可核实的事实To fill: verifiable fact
实现语言LanguageRust待填:可核实的事实To fill: verifiable fact
接口API兼容 S3S3-compatible待填:可核实的事实To fill: verifiable fact
数据保护Data protection纠删码、位腐烂检测、自愈Erasure coding, bitrot detection, healing待填:可核实的事实To fill: verifiable fact
遥测Telemetry无None待填:可核实的事实To fill: verifiable fact
部署方式Deployment二进制、Docker、HelmBinary, Docker, Helm待填:可核实的事实To fill: verifiable fact
RustFS 一栏来源:github.com/rustfs/rustfs README。核对日期:2026-10-14。RustFS column source: github.com/rustfs/rustfs README. Checked 2026-10-14.
Sourced facts only; fill the alternative column from its official docs.
CTA band
1440 × 800
快速开始Quick start

在本地
运行 RustFS
Run RustFS on your machine

一个容器即可启动单节点实例。数据目录须对 UID 10001 可写。One container starts a single-node instance. Data directories must be writable by UID 10001.

阅读快速开始Read the quick startgithub.com/rustfs/rustfs
~/rustfs
# 创建数据与日志目录# create data and log directories
$ mkdir -p data logs
$ chown -R 10001:10001 data logs

$ docker run -d -p 9000:9000 -p 9001:9001 \
    -v $(pwd)/data:/data \
    -v $(pwd)/logs:/logs \
    rustfs/rustfs:latest

# S3 API http://localhost:9000
# Console http://localhost:9001
Commands from the README; comments state results, never invented output.
Footer
1440 × 900

AI 时代的基建,
从每一个字节算起。
AI infrastructure,
accounted for byte by byte.

订阅月报Monthly newsletter
name@example.com订阅Subscribe
产品Product功能Features下载Download控制台Console更新日志Changelog
文档Docs快速开始Quick start安装InstallationS3 兼容性S3 compatibilityHelm ChartHelm chart
社区CommunityGitHubGitHub讨论区Discussions博客Blog贡献指南Contributing
法律Legal许可证License安全Security商标Trademarks隐私Privacy
© 2026 RustFS · Apache License 2.0rustfs.comdocs.rustfs.comgithub.com/rustfs/rustfs
The wordmark spans the 1240px column and is never cropped.
Blog index
1440 × 900
产品Product文档Docs博客Blog社区Community
中 / ENGitHub 下载Download

博客Blog

全部All发布Release产品Product教程Tutorial案例Case study集成Integration
1.0
发布Release2026-09-16

RustFS 1.0.0 正式发布:生产可用、开源、兼容 S3 的对象存储Announcing RustFS 1.0.0 GA: Production-Ready, Open Source, S3-Compatible Object Storage

产品Product2026-09-10

RustFS 推出 S3 Tables:开源对象存储中的 Apache Iceberg 表RustFS Launches S3 Tables: Apache Iceberg Tables Inside an Open-Source Object Store

教程Tutorial2026-08-19

分步教程:使用 RPM/DEB 软件包安装 RustFSStep-by-Step Tutorial: How to Install RustFS with RPM/DEB Packages

案例Case study2026-08-06

借助 Nawāt 与 RustFS 管理 AI 微调存储Managing AI Fine-Tuning Storage with Nawāt and RustFS

集成Integration2026-08-04

GitLab 与 RustFS 集成:OIDC 单点登录与 S3 对象存储GitLab and RustFS Integration: OIDC SSO and S3 Object Storage

迁移指南Migration

从 MinIO 迁移到 RustFS:技术指南Migrating from MinIO to RustFS: A Technical Guide

迁移指南Migration

二进制替换:从 MinIO 迁移到 RustFS 的简便方式Binary replacement: a simple way to migrate from MinIO to RustFS

Covers use brand graphics, never stock images; no excerpts or avatars.
404 page
1440 × 900
产品Product文档Docs博客Blog社区Community
中 / ENGitHub 下载Download
404 · NoSuchKey

此路径下
没有对象。
There is no object at this path.

页面可能已移动或删除。
请检查地址,或返回首页。
The page may have moved or been deleted. Check the address, or go back to the home page.

返回首页Back to home搜索文档Search the docs
GET /docs/old-path · 404
Plain copy and two ways out.
Docs page layout
1440 × 900 · docs.rustfs.com
文档Docs搜索文档Search the docs⌘Kv1.0.1中 / ENGitHub
开始Get started概览Overview快速开始Quick start
安装InstallationLinuxLinuxDockerDockerKubernetesKubernetes
概念Concepts纠删码Erasure coding自愈Healing版本控制Versioning
管理Administration控制台Console身份与访问Identity and access生命周期Lifecycle
文档Docs / 安装Installation / Linux

在 Linux 上安装Install on Linux

使用官方安装脚本在单台 Linux 主机上安装 RustFS,然后在浏览器中打开控制台。Install RustFS on a single Linux host with the official script, then open the Console in a browser.

一键安装One-line install

$curl -O https://rustfs.com/install_rustfs.sh && bash install_rustfs.sh
说明Note S3 API 默认监听 9000 端口,控制台为 9001。生产环境须使用你自己设定的访问密钥。The S3 API listens on port 9000 by default and the Console on 9001. Production deployments must use access keys you set yourself.

访问控制台Open the Console

在浏览器中打开 http://localhost:9001,使用管理员凭据登录。Open http://localhost:9001 in a browser and sign in with the administrator credentials.

← 上一页Previous快速开始Quick start下一页Next →Docker
本页内容On this page一键安装One-line install访问控制台Open the Console下一步Next steps
Sidebar 270px · body ≤ 72 characters · contents 216px; no side rail for the current page.

EmailEmail

The layout must hold with images blocked, system fonts and dark-mode inversion.

Newsletter · monthly release
640 × 1360 · single column, system fonts
RustFS 1.0.1 现已发布,另有三篇新文章。RustFS 1.0.1 is available, plus three new articles.在浏览器中查看View in browser
月报 · 2026.10Monthly · 2026.10
版本发布Release

RustFS 1.0.1 现已发布RustFS 1.0.1 is available

1.0.1 是 1.0 系列的首个补丁版本。升级前请阅读更新说明,并按部署方式执行对应的升级步骤。1.0.1 is the first patch release in the 1.0 series. Read the release notes before upgrading and follow the steps for your deployment method.

阅读更新说明Read the release notes或访问 or visit github.com/rustfs/rustfs/releases
使用指定版本运行Run a specific versiondocker run -d -p 9000:9000 -p 9001:9001 -v $(pwd)/data:/data -v $(pwd)/logs:/logs rustfs/rustfs:1.0.1
博客From the blog
2026-09-16RustFS 1.0.0 正式发布:生产可用、开源、兼容 S3 的对象存储Announcing RustFS 1.0.0 GA: Production-Ready, Open Source, S3-Compatible Object Storage
2026-09-10RustFS 推出 S3 Tables:开源对象存储中的 Apache Iceberg 表RustFS Launches S3 Tables: Apache Iceberg Tables Inside an Open-Source Object Store
2026-08-19分步教程:使用 RPM/DEB 软件包安装 RustFSStep-by-Step Tutorial: How to Install RustFS with RPM/DEB Packages
34,869GitHub 星标GitHub stars
15.15MDocker 镜像拉取Docker pulls
数据来源:RustFS 官方网站。统计日期:2026-10-14。Source: official RustFS website. As of 2026-10-14.
你收到这封邮件,是因为订阅了 RustFS 月报。You are receiving this email because you subscribed to the RustFS newsletter.退订Unsubscribe管理订阅Preferences在浏览器中查看View in browser公司名称与通讯地址Company name and postal address
WHITE is the default; INK checks dark mode.
ItemRule
Width640px single column, 40px side padding; 100% in narrow clients
FontsSystem stack: -apple-system, Segoe UI, PingFang SC, Microsoft YaHei, Arial; no web fonts
Images offBand as cell background, wordmark with alt="RustFS"; body and buttons are live text
Tap targetsButtons 48px; links ≥ 12px apart; targets ≥ 44 × 44px
Dark modeDeclare color-scheme; wordmark on the Signal band; no dark images on transparent backgrounds
Body16px / 1.6; links underlined; figures carry a source and date
ComplianceFooter: why subscribed, unsubscribe link, postal address; send a plain-text version
email.html · bulletproof button
<!-- Bulletproof button: real text on a coloured cell, 48px tall -->
<table role="presentation" cellpadding="0" cellspacing="0" border="0">
  <tr>
    <td bgcolor="#0062FF" style="background:#0062FF;">
      <a href="https://github.com/rustfs/rustfs/releases"
         style="display:inline-block; padding:14px 24px; line-height:20px;
                font:600 16px/20px -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Arial, sans-serif;
                color:#FFFFFF; text-decoration:none;">
        Read the release notes
      </a>
    </td>
  </tr>
</table>

<!-- Dark-mode clients -->
<meta name="color-scheme" content="light dark">
<meta name="supported-color-schemes" content="light dark">

Micro-interactionsMicro-interactions

Feedback only: 80 / 150 / 240 / 420 / 720ms durations, standard or emphasized easing, no bounce.

Button sheen720ms · ease-emphasized · translate

Lifts 1px; the sheen crosses once left to right and resets on leave.

Link underline240ms · ease-emphasized · background-size

Standalone links grow the underline left to right; links in running text stay underlined.

Card hover240ms · ease-standard / emphasized

Border turns foreground, arrow moves 2px; the card never moves, scales or gains a shadow.

mkdir -p data logs
Copy feedback1600ms · toast

The icon becomes a success check for 1600ms, with a Copied toast.

Online
Heal720ms × 3 · steps

Shard drops → parity flashes → rebuild, 720ms per step, stepped, never faded.

Loading
Skeleton1200ms · stagger 40ms · steps(1)

Rows of 8px shards lit every 40ms; no shimmering gradient bars.

InteractionPropertyDurationEasingReduced motion
Button lifttranslate150ms · --duration-fastease-standardNo movement
Button sheentranslate720ms · --duration-sceneease-emphasizedHidden
Link underlinebackground-size240ms · --duration-baseease-emphasizedShown at once
Card hoverborder-color · translate240ms · --duration-baseease-standard · emphasizedColour only
Control statebackground · border80–150msease-standardKept
Healbackground · outline720ms × 3steps(1)Final state
Skeletonbackground1200ms · stagger 40mssteps(1)Static
heal · keyframes
/* 0–25% intact · 25–50% dropped out · 50–62.5% parity flash · rebuilt.
   --mx-* lets the same keyframes follow an artboard's surface. */
@keyframes rfs-heal {
  0% { background-color: var(--mx-data, var(--brand)); outline: 1px solid transparent; outline-offset: -1px; }
  25% { background-color: transparent; outline: 1px dashed var(--mx-data, var(--brand)); outline-offset: -1px; }
  50% { background-color: var(--mx-parity, var(--parity)); outline: 1px solid transparent; outline-offset: -1px; }
  62.5%, 100% { background-color: var(--mx-data, var(--brand)); outline: 1px solid transparent; outline-offset: -1px; }
}

<i className="size-2 bg-brand animate-[rfs-heal_2880ms_steps(1)_infinite]" />
skeleton · keyframes
@keyframes rfs-shard {
  0% { background-color: var(--surface-2); }
  50% { background-color: var(--strong); }
}

{cells.map((_, i) => (
  <i
    key={i}
    className="size-2 bg-surface-2 animate-[rfs-shard_1200ms_steps(1)_infinite]"
    style={{ animationDelay: `${(i % 24) * 40}ms` }}
  />
))}

Do & Don'tDo and don't

Check every interface against these five pairs before it ships.

DoButtons, inputs and cards are square.
s3://photos
CreateCancel
Don'tRounded corners and capsule shapes.
OnlineDegradedOffline
DoSquare marker, mono text, 1px border.
OnlineDegradedOffline
Don'tColoured pills and dots; weak contrast.
AI infrastructure, accounted for byte by byte.
DoFlat colour; graphics from product structure.
AI infrastructure, accounted for byte by byte.
Don'tGradient backgrounds, glows and blurred blobs.
Erasure set 1Six drives, EC 4+2, tolerates two failed drives.Updated 2026-10-14 · Sample data
DoText in foreground, subtle or muted-foreground; ≥ 4.5:1.
Erasure set 1Six drives, EC 4+2, tolerates two failed drives.Updated 2026-10-14
Don'tAd-hoc greys and tiny type.
Do1px border; foreground on hover.

Object Lock

Retain objects as WORM.

Don'tSide rails, shadows, rounded corners.