Files
labweb/supabase-stack/docs/FINAL_ARCHITECTURE_MINIO_INTERNAL.md
zly 1f7a2ed1e4 feat: 迁移 Storage 后端从 MinIO 到文件系统
## 主要变更

### 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 功能正常)
2025-12-05 19:44:11 +08:00

339 lines
7.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ✅ 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 通过