文章目录
- [一、为什么一定要区分 public / private Bucket?](#一、为什么一定要区分 public / private Bucket?)
- 二、核心设计原则
- 三、推荐的整体架构设计
- [四、public Bucket 最佳实践](#四、public Bucket 最佳实践)
- [五、private Bucket 最佳实践](#五、private Bucket 最佳实践)
- 六、对象(Object)命名规范(非常重要)
- 七、账号与权限最佳实践
- 八、后端代码设计建议(实战)
- 九、常见错误总结
- 十、总结
MinIO 对象存储实战:Docker 安装 + Spring Boot 文件上传完整示例
一、为什么一定要区分 public / private Bucket?
很多人一开始用 MinIO,都会只有一个 bucket:
text
file-bucket
然后:
- 图片
- 附件
- 合同
- 私密文件
全都往里丢,早晚会出问题。
常见坑包括:
- 图片要能直接访问,但 bucket 是 private → AccessDenied
- 文件改成 public,结果私密文件也能被访问
- 后期想改权限,牵一发动全身
👉 根本原因:Bucket 没有做职责隔离
二、核心设计原则
public bucket:给"任何人都能看的文件"
private bucket:给"必须受控访问的文件"
这是 MinIO / S3 官方推荐模型。
三、推荐的整体架构设计
┌──────────────┐
│ 前端 / 浏览器 │
└───────┬──────┘
│
┌─────────┴─────────┐
│ │
public bucket private bucket
(匿名只读) (完全私有)
│ │
直接 URL 预签名 URL / 后端转发
四、public Bucket 最佳实践
1️⃣ 使用场景
适合 完全不敏感 的资源:
- 头像
- 商品图片
- 静态资源
- 公开下载文件
2️⃣ Bucket 命名建议
text
sky-public
命名即语义,一眼知道用途。
3️⃣ 访问策略(只读)
bash
mc anonymous set download local/sky-public
含义:
- 允许匿名访问(GET)
- 禁止匿名上传 / 删除
这是 最安全的 public 模式。
4️⃣ 上传与访问方式
上传(Java / 后端)
- 使用有权限的账号(app-user)
访问(前端 / 浏览器)
text
http://minio-host:9000/sky-public/avatar/1.png
无需任何鉴权。
五、private Bucket 最佳实践
1️⃣ 使用场景
必须 受控访问 的文件:
- 合同 / 订单附件
- 用户隐私文件
- 内部资料
- 临时下载文件
2️⃣ Bucket 命名建议
text
sky-private
3️⃣ 访问策略
保持默认 PRIVATE,不要设置匿名访问。
4️⃣ 正确的访问方式(重点)
❌ 错误方式
text
直接拼 URL 给前端
结果:
xml
AccessDenied
✅ 正确方式一:预签名 URL(最推荐)
由后端生成:
java
minioClient.getPresignedObjectUrl(
GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket("sky-private")
.object(objectKey)
.expiry(10 * 60)
.build()
);
特点:
- 有效期自动失效
- 前端无需 accessKey
- 安全、简单、解耦
✅ 正确方式二:后端转发(更严格)
- 前端请求后端
- 后端校验权限
- 后端流式下载文件
适合:
- 极高安全要求
- 需要鉴权 / 审计
六、对象(Object)命名规范(非常重要)
❌ 反例
text
uuid.png
✅ 推荐结构
text
public:
image/avatar/2026/01/uuid.png
private:
file/order/2026/01/uuid.pdf
好处:
- 避免单目录文件过多
- 方便运维与迁移
- 提升长期性能
- 语义清晰
七、账号与权限最佳实践
1️⃣ 账号划分
| 账号 | 用途 |
|---|---|
| admin | 只用于管理 |
| app-user | Java / 后端程序 |
2️⃣ app-user 推荐最小权限 policy
json
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::sky-public/*",
"arn:aws:s3:::sky-private/*"
]
}]
}
👉 永远不要让程序使用 admin 账号
八、后端代码设计建议(实战)
上传接口统一入口
java
upload(file, BucketType.PUBLIC);
upload(file, BucketType.PRIVATE);
返回值设计
- public:返回 永久 URL
- private:返回 短期签名 URL
数据库中:
- 只存 objectKey
- 不存完整 URL(方便后期迁移)
九、常见错误总结
❌ 一个 bucket 放所有文件
❌ private bucket 直接返回 URL
❌ Java 使用 admin 账号
❌ UI 改策略,环境不可控
✅ public / private 分 bucket
✅ private 用预签名 URL
✅ 权限最小化
✅ 策略用 mc / JSON 管理
十、总结
MinIO 的最佳实践不是"怎么存文件",
而是"如何控制文件被谁、在什么时候、以什么方式访问"。
public / private bucket 的划分,是所有后续设计的基础。