## 主要变更
### 1. Storage 配置修改
- 修改 docker-compose.yml: STORAGE_BACKEND 从 s3 改为 file
- 注释所有 GLOBAL_S3_* 环境变量
- 启用 FILE_STORAGE_BACKEND_PATH=/var/lib/storage
- 停止使用 MinIO 容器(docker-compose.s3.yml)
### 2. 文档更新
- 新增 docs/STORAGE_FILE_BACKEND_MIGRATION.md - 迁移详细文档
- 新增 docs/STORAGE_TROUBLESHOOTING.md - 故障排查指南
- 更新 README.md - 反映新的架构
### 3. 存储架构变更
- 从 MinIO S3 对象存储 -> 本地文件系统
- 存储路径: volumes/storage/undefined/stub/{bucket}/{file}/{version}
- 不再需要额外的 MinIO 容器
## 测试结果
- ✅ 上传文件 - 正常
- ✅ 下载文件 - 正常
- ✅ 删除文件 - 正常
- ✅ 签名 URL - 正常
- ⚠️ 更新文件 - 已知bug(使用删除+上传代替)
## 注意事项
- 旧的 S3 后端数据需要清理数据库元数据
- 文件更新操作有已知bug,需使用删除+重新上传
- 备份文件保存在 *.backup-before-rustfs
## 回滚方法
如需回滚到 MinIO:
```bash
cp docker-compose.yml.backup-before-rustfs docker-compose.yml
docker compose -f docker-compose.s3.yml up -d
docker compose restart storage
```
日期: 2025-12-05
状态: ✅ 测试通过 (4/5 功能正常)
339 lines
7.4 KiB
Markdown
339 lines
7.4 KiB
Markdown
# ✅ MinIO 内网化架构 - 最终配置
|
||
|
||
## 架构变更总结
|
||
|
||
### 变更日期
|
||
2025-11-23
|
||
|
||
### 变更目标
|
||
- MinIO S3 对象存储改为仅内网访问
|
||
- 删除 MinIO 的所有 Traefik 公网路由
|
||
- 保留根路径 302 重定向到 `/group/`
|
||
- 通过 Supabase Storage API 提供公网文件上传下载功能
|
||
|
||
---
|
||
|
||
## 最终架构
|
||
|
||
### 内网访问 (Tailscale VPN Required)
|
||
|
||
| 服务 | 地址 | 用途 |
|
||
|------|------|------|
|
||
| MinIO S3 API | `http://100.64.0.2:9000` | 对象存储 API(管理员直接访问)|
|
||
| MinIO Console | `http://100.64.0.2:9001` | Web 管理界面 |
|
||
| Supabase Dashboard | `http://100.64.0.2:18000` | 数据库/后端管理 |
|
||
|
||
### 公网访问 (HTTPS)
|
||
|
||
| 服务 | 地址 | 说明 |
|
||
|------|------|------|
|
||
| **根路径** | `https://amiap.hzau.edu.cn/` | 302 重定向到 `/group/` |
|
||
| **课题组网站** | `https://amiap.hzau.edu.cn/group/` | Vue.js 前端 |
|
||
| **Supabase Storage** | `https://amiap.hzau.edu.cn/supa/storage/v1/` | 文件上传下载 API ✅ |
|
||
| **Supabase API** | `https://amiap.hzau.edu.cn/supa/` | Auth/REST/Realtime |
|
||
| **ABM 数据库** | `https://amiap.hzau.edu.cn/ABM/` | WebSocket 项目 |
|
||
|
||
---
|
||
|
||
## 存储架构
|
||
|
||
### 公网文件上传下载流程
|
||
|
||
```
|
||
用户/应用
|
||
↓ HTTPS
|
||
https://amiap.hzau.edu.cn/supa/storage/v1/
|
||
↓ Traefik (去除 /supa 前缀)
|
||
Kong Gateway (Supabase API 网关)
|
||
↓ 内部网络
|
||
Supabase Storage Service (Docker 内部)
|
||
↓ S3 协议 (http://minio:9000)
|
||
MinIO 对象存储
|
||
↓
|
||
物理存储: /vol1/1000/s3
|
||
```
|
||
|
||
**关键点**:
|
||
- 用户**不直接**访问 MinIO
|
||
- 所有公网访问通过 Supabase Storage API
|
||
- MinIO 仅在 Docker 内部网络和 Tailscale 内网可访问
|
||
- 文件最终存储在 MinIO 容器 (`/vol1/1000/s3`)
|
||
|
||
### 内网直接访问(管理员)
|
||
|
||
```
|
||
管理员 (Tailscale VPN)
|
||
↓
|
||
http://100.64.0.2:9000 (MinIO S3 API)
|
||
http://100.64.0.2:9001 (MinIO Console)
|
||
↓
|
||
MinIO 容器
|
||
↓
|
||
物理存储: /vol1/1000/s3
|
||
```
|
||
|
||
---
|
||
|
||
## 配置变更详情
|
||
|
||
### 1. docker-compose.s3.yml
|
||
|
||
**删除的配置**:
|
||
```yaml
|
||
# ❌ 已删除
|
||
labels:
|
||
- "traefik.enable=true"
|
||
- "traefik.http.routers.minio-s3.rule=..."
|
||
- "traefik.http.services.minio-s3-svc...."
|
||
# ... 所有 Traefik labels
|
||
|
||
networks:
|
||
- frontend # ❌ 不再连接到 Traefik 网络
|
||
```
|
||
|
||
**保留/更新的配置**:
|
||
```yaml
|
||
services:
|
||
minio:
|
||
ports:
|
||
- "100.64.0.2:9000:9000" # ✓ 仅 Tailscale IP
|
||
- "100.64.0.2:9001:9001" # ✓ 仅 Tailscale IP
|
||
environment:
|
||
MINIO_SERVER_URL: "http://100.64.0.2:9000" # ✓ 内网 URL
|
||
MINIO_BROWSER_REDIRECT_URL: "http://100.64.0.2:9001"
|
||
networks:
|
||
- default # ✓ 仅 Supabase 内部网络
|
||
```
|
||
|
||
### 2. docker-compose.yml
|
||
|
||
**修复的端口冲突**:
|
||
```yaml
|
||
# Studio Dashboard
|
||
studio:
|
||
ports:
|
||
- "100.64.0.2:18000:3000" # ✓ Tailscale 内网访问
|
||
|
||
# Kong API Gateway
|
||
kong:
|
||
# ✓ 不暴露端口,仅通过 Traefik 公网访问
|
||
# Kong 通过 Docker 内部网络与其他服务通信
|
||
```
|
||
|
||
### 3. Supabase Storage 配置
|
||
|
||
**Storage 通过内部网络连接 MinIO** (`docker-compose.yml`):
|
||
```yaml
|
||
storage:
|
||
environment:
|
||
STORAGE_BACKEND: s3
|
||
GLOBAL_S3_ENDPOINT: http://minio:9000 # ✓ Docker 内部网络
|
||
GLOBAL_S3_BUCKET: stub
|
||
AWS_ACCESS_KEY_ID: ${MINIO_ROOT_USER}
|
||
AWS_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD}
|
||
```
|
||
|
||
---
|
||
|
||
## 验证测试
|
||
|
||
### ✅ 测试结果
|
||
|
||
运行 `examples/test_https_storage.py`:
|
||
```bash
|
||
cd /vol1/1000/docker_server/traefik/supabase-stack
|
||
python3 examples/test_https_storage.py
|
||
```
|
||
|
||
**测试结果**: 5/5 通过 ✅
|
||
|
||
| 测试项 | 状态 | 说明 |
|
||
|--------|------|------|
|
||
| 列出 Buckets | ✅ | 发现 2 个 bucket |
|
||
| 创建/确认 Bucket | ✅ | test-https 存在 |
|
||
| 上传/更新文件 | ✅ | 79 bytes 上传成功 |
|
||
| 下载文件 | ✅ | 内容完整 |
|
||
| 生成签名 URL | ✅ | 临时链接可用 |
|
||
|
||
### 测试命令示例
|
||
|
||
```bash
|
||
# 测试根路径重定向
|
||
curl -I https://amiap.hzau.edu.cn
|
||
# 期望: HTTP/2 302 + Location: /group/
|
||
|
||
# 测试 Supabase Storage API
|
||
curl -I https://amiap.hzau.edu.cn/supa/storage/v1/bucket \
|
||
-H "apikey: YOUR_API_KEY"
|
||
# 期望: HTTP/2 200
|
||
|
||
# 测试 MinIO 内网访问(需要 Tailscale)
|
||
curl -I http://100.64.0.2:9000/minio/health/live
|
||
# 期望: HTTP/1.1 200 OK
|
||
|
||
# 测试 MinIO Console(需要 Tailscale)
|
||
curl -I http://100.64.0.2:9001
|
||
# 期望: HTTP/1.1 200 OK + Server: MinIO Console
|
||
```
|
||
|
||
---
|
||
|
||
## 安全优势
|
||
|
||
### 1. 最小权限原则
|
||
- MinIO 不再暴露到公网
|
||
- 仅授权用户(Tailscale VPN)可直接访问 MinIO
|
||
|
||
### 2. 访问控制
|
||
- 公网访问必须通过 Supabase Storage API
|
||
- 支持细粒度的权限控制(RLS)
|
||
- 自动签名 URL,临时授权
|
||
|
||
### 3. 攻击面减小
|
||
- 减少了公网暴露的端口和服务
|
||
- MinIO 管理界面仅内网可访问
|
||
- 降低了潜在的 DDoS 风险
|
||
|
||
---
|
||
|
||
## 使用指南
|
||
|
||
### 公网文件上传下载
|
||
|
||
**Python 示例**:
|
||
```python
|
||
import requests
|
||
|
||
BASE_URL = 'https://amiap.hzau.edu.cn/supa'
|
||
API_KEY = 'your_anon_key'
|
||
|
||
headers = {
|
||
'apikey': API_KEY,
|
||
'Authorization': f'Bearer {API_KEY}'
|
||
}
|
||
|
||
# 上传文件
|
||
with open('test.txt', 'rb') as f:
|
||
response = requests.post(
|
||
f'{BASE_URL}/storage/v1/object/bucket-name/file.txt',
|
||
headers={**headers, 'Content-Type': 'text/plain'},
|
||
data=f
|
||
)
|
||
|
||
# 下载文件
|
||
response = requests.get(
|
||
f'{BASE_URL}/storage/v1/object/bucket-name/file.txt',
|
||
headers=headers
|
||
)
|
||
content = response.content
|
||
```
|
||
|
||
**JavaScript 示例**:
|
||
```javascript
|
||
import { createClient } from '@supabase/supabase-js'
|
||
|
||
const supabase = createClient(
|
||
'https://amiap.hzau.edu.cn/supa',
|
||
'your_anon_key'
|
||
)
|
||
|
||
// 上传文件
|
||
const { data, error } = await supabase.storage
|
||
.from('bucket-name')
|
||
.upload('file.txt', file)
|
||
|
||
// 下载文件
|
||
const { data: fileData } = await supabase.storage
|
||
.from('bucket-name')
|
||
.download('file.txt')
|
||
```
|
||
|
||
### 内网管理(MinIO Console)
|
||
|
||
1. 连接 Tailscale VPN
|
||
2. 访问: `http://100.64.0.2:9001`
|
||
3. 登录凭证:
|
||
- **用户名**: `bsxzZAJ3fvDquup`
|
||
- **密码**: `c2dc1bca7aa4d0adc308f69b6d41eddfaa110a9572ad1b410d73ea0633523fe9`
|
||
|
||
### MinIO 命令行工具 (mc)
|
||
|
||
```bash
|
||
# 配置别名
|
||
mc alias set myminio http://100.64.0.2:9000 \
|
||
bsxzZAJ3fvDquup \
|
||
c2dc1bca7aa4d0adc308f69b6d41eddfaa110a9572ad1b410d73ea0633523fe9
|
||
|
||
# 列出 buckets
|
||
mc ls myminio
|
||
|
||
# 上传文件
|
||
mc cp local-file.txt myminio/stub/
|
||
|
||
# 下载文件
|
||
mc cp myminio/stub/file.txt ./
|
||
```
|
||
|
||
---
|
||
|
||
## 故障排查
|
||
|
||
### 问题: Supabase Storage API 返回 404
|
||
|
||
**检查**:
|
||
```bash
|
||
# 1. 确认 Kong 运行正常
|
||
docker ps | grep kong
|
||
|
||
# 2. 查看 Kong 日志
|
||
docker logs supabase-kong --tail 50
|
||
|
||
# 3. 测试 Kong 健康状态
|
||
docker inspect supabase-kong --format='{{.State.Health.Status}}'
|
||
```
|
||
|
||
### 问题: MinIO 内网无法访问
|
||
|
||
**检查**:
|
||
```bash
|
||
# 1. 确认 Tailscale 连接
|
||
tailscale status
|
||
ping 100.64.0.2
|
||
|
||
# 2. 检查 MinIO 容器
|
||
docker ps | grep minio
|
||
|
||
# 3. 查看端口绑定
|
||
docker port supabase-minio-1
|
||
```
|
||
|
||
### 问题: 文件上传失败
|
||
|
||
**检查**:
|
||
```bash
|
||
# 1. 查看 Storage 日志
|
||
docker logs supabase-storage --tail 50
|
||
|
||
# 2. 确认 Storage 到 MinIO 的连接
|
||
docker exec supabase-storage ping -c 1 minio
|
||
|
||
# 3. 检查 Storage 环境变量
|
||
docker exec supabase-storage env | grep -E "GLOBAL_S3|MINIO"
|
||
```
|
||
|
||
---
|
||
|
||
## 相关文档
|
||
|
||
- `examples/test_https_storage.py` - Storage API 功能测试
|
||
- `MINIO_LOGIN_FIX.md` - MinIO Console 登录问题修复
|
||
- `INTERNAL_ACCESS_FIXED.md` - 内网访问配置
|
||
- `DEPLOYMENT_GUIDE.md` - 完整部署指南
|
||
|
||
---
|
||
|
||
**修改日期**: 2025-11-23
|
||
**架构版本**: v3.0 (MinIO 内网化)
|
||
**状态**: ✅ 已验证,生产就绪
|
||
**测试**: 5/5 通过
|