十分钟在自己机器上跑通一个 S3 兼容对象存储(RustFS + Docker)

本地联调代码要一个对象存储、给客户做 POC 要演示、边缘小站想垫一层存储底座,都不值得专门为它采购和运维一套分布式集群。一条 docker run 就能在笔记本或一台小服务器上把 RustFS 跑起来,S3 接口直接可用,代码里把 endpoint 指过来就能测。这篇把从拉镜像到用 aws-cli 建桶的完整路径走一遍,并把几个最容易卡住的点讲清楚。

端口和镜像先到位

Docker Engine 要 20.10 以上,主机上 9000(S3 API)和 9001(控制台)两个端口可用,或者你自己改端口也行。先把镜像拉下来,建个命名卷让容器重建后数据不丢:

bash 复制代码
docker pull rustfs/rustfs:latest
docker volume create rustfs-data

一条命令起服务

把占位符换成你自己的密钥再跑,重点是把 access key 和 secret key 都设上,别留空也别用 rustfsadmin 这种众所周知的值:

bash 复制代码
docker run -d \
  --name rustfs \
  --restart unless-stopped \
  -p 9000:9000 \
  -p 9001:9001 \
  -v rustfs-data:/data \
  -e RUSTFS_ACCESS_KEY="<your-access-key>" \
  -e RUSTFS_SECRET_KEY="<your-secret-key>" \
  -e RUSTFS_ADDRESS=":9000" \
  -e RUSTFS_CONSOLE_ADDRESS=":9001" \
  -e RUSTFS_CONSOLE_ENABLE=true \
  -e RUSTFS_OBS_LOGGER_LEVEL=error \
  -e RUSTFS_OBS_LOG_DIRECTORY="/var/log/rustfs/" \
  rustfs/rustfs:latest \
  /data

RUSTFS_CONSOLE_ENABLE=true 才会开 9001 控制台;RUSTFS_ADDRESS 和 RUSTFS_CONSOLE_ADDRESS 分别管 S3 和控制台的监听地址。同一个配置也能用命令行参数传,--access-key、--address 这类,而且命令行参数优先级高于环境变量。

一个权限坑:容器里的用户不是 root

RustFS 容器以非 root 用户 rustfs(UID 10001)运行。如果你用主机目录挂载(-v /path/on/host:/data)而不是命名卷,目录所有者必须改成 10001,否则会权限拒绝:

bash 复制代码
chown -R 10001:10001 /path/to/host_directory

用命名卷就省掉这步,所以本地起服务优先命名卷。

起来先探活,再开控制台

别急着登控制台,先用健康检查端点确认服务在:

bash 复制代码
docker ps --filter name=rustfs
curl --fail http://localhost:9000/health

curl --fail 返回 0 说明 S3 接口已经起来了,控制台在 http://localhost:9001,用上面设的密钥登录。

顺手验一下 S3 通路

探活通过后用 aws-cli 建个桶、传个文件,确认整条链路通:

bash 复制代码
export AWS_ACCESS_KEY_ID="<your-access-key>"
export AWS_SECRET_ACCESS_KEY="<your-secret-key>"
export AWS_DEFAULT_REGION=us-east-1
aws --endpoint-url http://localhost:9000 s3 mb s3://demo
aws --endpoint-url http://localhost:9000 s3 cp ./local-file.txt s3://demo/

能传能取,本地的对象存储就真的能当 S3 用了。习惯用 MinIO Client 的也可以:mc alias set rustfs http://localhost:9000 <key> <secret> 之后 mc mb rustfs/demo。停服就 docker stop rustfs,重启就 docker start rustfs,命名卷里的数据还在。

日志和常见报错

容器日志用 docker logs --follow rustfs 实时跟。RustFS 自己把运行日志写到 RUSTFS_OBS_LOG_DIRECTORY(上面设的是 /var/log/rustfs/),这个容器内路径记得挂出来或挂命名卷,否则容器一删日志也没了。想看更细的日志,把 RUSTFS_OBS_LOGGER_LEVEL 从 error 临时调到 info,能看到更细的启动和请求日志,定位完记得调回去。

起不来和必须处理的情况基本就这几类:端口被占用(bind: address already in use),换 -p 映射或停掉占端口的进程;权限拒绝,是主机目录没 chown 10001(见上);凭证还留着默认值,容器能起,但官方要求接入网络前就换成唯一密钥,处置办法是停掉容器、带 -e 凭证参数重建,数据卷不受影响。

命名卷还是绑定挂载

命名卷(rustfs-data)由 Docker 管理,权限和生命周期都省心,本地联调首选。要直接摸到宿主机上的文件(比如把对象导出来看),才用绑定挂载 -v /path:/data,代价就是自己管 10001 那个 UID 的归属。两种方式的 S3 行为完全一致,按你需不需要直接看盘上文件来选。

想顺带看监控?用 Compose 一把拉起可观测栈

官方仓库里的 docker-compose.yml 除了 RustFS 本身,还带了 grafana、prometheus、otel-collector、jaeger、loki、tempo 等可观测服务(另有 tempo-init 初始化容器和 nginx 反代)。想一起跑:

bash 复制代码
git clone https://github.com/rustfs/rustfs.git
cd rustfs
docker compose --profile observability up -d

只想要对象存储、不要监控栈,就只起 rustfs 服务:

bash 复制代码
docker compose -f docker-compose.yml up -d rustfs

注意仓库自带的 compose 里没有权限初始化这一步:官方文档给的 compose 示例里用了一个 init 容器 rustfs_perms(基于 alpine),在 RustFS 启动前把挂载卷的所有权改成 10001,靠 depends_on 卡顺序,避免权限问题。自己编排时可以照官方示例把这个服务加进去。单服务场景用一条 docker run 最轻量;只有当要把对象存储和监控等多个服务一起编排时,compose 才显出价值。

数据怎么备份和迁移

命名卷的数据在 Docker 的 volumes 目录里,整卷打包就能备份:

bash 复制代码
docker run --rm -v rustfs-data:/from -v "$PWD":/to alpine \
  tar czf /to/rustfs-data.tgz -C /from .

换机器时把这份 tar 在目标主机解回同名卷,再用同样的 docker run 起服务,数据就跟着过来了。

这是卷级别的冷备,和对象存储自己的版本化、复制是两套不同层级的保障,别互相替代。冷备频率按数据变更节奏定,变化快的桶每天一备,变化慢的每周也够,关键是恢复时这份 tar 能和当时的对象清单对上。

另外分清删容器和删卷:docker rm rustfs 只删容器、不动命名卷 rustfs-data,数据还在;要彻底清数据才用 docker volume rm rustfs-data。

几个边界先说清

单节点 Docker 不是生产形态。官方明确建议生产前走预安装检查清单,上多节点架构、开 TLS、配日志轮转和定期备份。TLS 的接法是挂证书目录再指过去:

bash 复制代码
-v /path/to/certs:/certs \
-e RUSTFS_TLS_PATH=/certs \

这里有个官方的硬约定:证书文件必须命名为 rustfs_cert.pem 和 rustfs_key.pem 放进该目录,按别的名字放进去 TLS 起不来。配好后 9000(S3 API)和 9001(控制台)两个监听器都会走 HTTPS。另外容器以 rustfs 用户跑,这两个文件的属主也要改成 10001:10001,不然 RustFS 读不了证书,TLS 同样配失败。

升镜像版本就是重新拉再重建容器,命名卷 rustfs-data 不动,数据不受影响。镜像 tag 的取舍就一条:rustfs/rustfs:latest 会跟到最新,POC 用着方便;要稳就钉一个具体标签,避免某次 docker pull 把不想要的变更悄悄带进来,升级前先在测试环境跑一遍再上。截至发稿(2026 年 10 月),稳定线最新是 1.0.4(2026-10-25),钉版本可以用 rustfs/rustfs:1.0.4。

端口方面,-p 9000:9000 默认就绑在 0.0.0.0 上,局域网联调直接能访问;但别把 9000 裸露到公网,公网前面至少加一层 TLS 和强密钥。

下一步

服务起好、/health 通了、aws-cli 也能建桶传文件,本地验证就算闭环。单节点部署的定位就是开发、POC、边缘小站这三件事,它把跑通 S3 接口的门槛压到最低,但不提供盘级容错,一块盘坏了数据就丢。给边缘小站用时,把 data 挂到本地 SSD、把 9000/9001 映射出去,整机重启靠 --restart unless-stopped 自动拉起,基本免运维,够小站用很久。真要上生产、要冗余,顺着本篇末尾的链接去多节点或 K8s,形态虽然变,S3 接口和密钥这套东西不变,代码几乎不用改。完整安装说明在 RustFS Docker 文档 ,镜像和 compose 文件在 rustfs/rustfs 。

相关推荐
元岳数字人小元1 小时前
告别云端依赖,数字人本地部署筑牢项目安全底座
人工智能·安全·架构·开源·人机交互·交互
小杨互联网1 小时前
Kenney / Blender CC0 小资源离线镜像汇总
开源·blender·游戏素材·kenney·cc0·离线包
知已难寻1 小时前
00 · OpenStack 总纲——从云计算到 OpenStack 全景
运维·服务器·云原生·云计算·负载均衡·openstack·perl
2601_949480062 小时前
开源鸿蒙平台 KMP 三方库「kasechange」适配全流程
华为·开源·harmonyos
2301_780789662 小时前
SSL 卸载 + WAF + 抗 D:高防 CDN 一站式解决 HTTPS 性能与安全
网络·云原生·ddos
切糕师学AI2 小时前
K8s 滚动更新与 Spring Boot 优雅停机实战:如何做到真正的平滑发布?
spring boot·云原生·容器·kubernetes·k8s
resh_people2 小时前
开源鸿蒙平台 CMP 三方库「table」适配全流程
华为·开源·harmonyos
喜欢吃豆2 小时前
我开源了 Agent UI Lab 用交互实验理解 AG-UI A2UI 与 MCP Apps
ui·开源·大模型·交互
hhhjhl2 小时前
开源鸿蒙平台 CMP 三方库「compose-macos-26-ui」适配全流程
macos·开源·harmonyos