Files
labweb/supabase-stack/docs/STORAGE_FILE_BACKEND_MIGRATION.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

6.0 KiB
Raw Permalink Blame History

Storage 后端迁移:从 MinIO (S3) 到文件系统

日期: 2025-12-05
状态: 完成(部分功能限制)

迁移概述

将 Supabase Storage 从 MinIO (S3 兼容对象存储) 迁移到文件系统后端。

变更内容

1. docker-compose.yml 修改

修改前 (S3 后端):

storage:
  environment:
    STORAGE_BACKEND: s3
    GLOBAL_S3_BUCKET: ${GLOBAL_S3_BUCKET}
    GLOBAL_S3_ENDPOINT: ${GLOBAL_S3_ENDPOINT}
    GLOBAL_S3_PROTOCOL: ${GLOBAL_S3_PROTOCOL}
    GLOBAL_S3_FORCE_PATH_STYLE: ${GLOBAL_S3_FORCE_PATH_STYLE}

修改后 (文件后端):

storage:
  environment:
    STORAGE_BACKEND: file
    FILE_STORAGE_BACKEND_PATH: /var/lib/storage
    # GLOBAL_S3_BUCKET: ${GLOBAL_S3_BUCKET}  # 已注释
    # GLOBAL_S3_ENDPOINT: ${GLOBAL_S3_ENDPOINT}  # 已注释
    # GLOBAL_S3_PROTOCOL: ${GLOBAL_S3_PROTOCOL}  # 已注释
    # GLOBAL_S3_FORCE_PATH_STYLE: ${GLOBAL_S3_FORCE_PATH_STYLE}  # 已注释

2. MinIO 服务停用

# 停止 MinIO 容器
docker compose -f docker-compose.s3.yml down

# MinIO 不再启动docker-compose.s3.yml 不再使用)

3. 文件存储目录

存储路径:

volumes/storage/undefined/stub/{bucket-name}/{file-name}/{version-id}

示例:

volumes/storage/undefined/stub/test-file-backend/hello.txt/59a6c5e4-fe40-4414-8f42-619cd0792619

注意: 路径中的 undefined 是文件后端的固定目录结构,不是错误。

测试结果

正常功能 (4/5)

功能 状态 说明
列出 Buckets 完全正常
上传文件 完全正常
下载文件 公共和认证访问都正常
删除文件 完全正常
更新文件 500 错误

已知问题

1. 文件更新失败

错误:

PUT /storage/v1/object/{bucket}/{file}
Status: 500 Internal Server Error

原因: Supabase Storage 文件后端的已知 bug更新文件时尝试删除旧版本时路径解析错误。

临时方案: 先删除再上传

# 删除旧文件
requests.delete(f'{BASE_URL}/storage/v1/object/{bucket}/{file}', headers=headers)

# 上传新文件
requests.post(f'{BASE_URL}/storage/v1/object/{bucket}/{file}', headers=headers, data=new_data)

2. S3 后端数据不兼容

  • 之前 MinIO (S3) 后端创建的 buckets 中的文件无法访问
  • 文件元数据存储格式不同
  • 需要重新上传旧文件到新 bucket

使用示例

Python

import requests

BASE_URL = 'https://amiap.hzau.edu.cn/supa'
API_KEY = 'your_service_role_key'

headers = {
    'apikey': API_KEY,
    'Authorization': f'Bearer {API_KEY}'
}

# 创建 bucket
response = requests.post(
    f'{BASE_URL}/storage/v1/bucket',
    headers=headers,
    json={'name': 'my-bucket', 'public': True}
)

# 上传文件
with open('file.txt', 'rb') as f:
    response = requests.post(
        f'{BASE_URL}/storage/v1/object/my-bucket/file.txt',
        headers={**headers, 'Content-Type': 'text/plain'},
        data=f
    )

# 下载文件(公共 bucket
response = requests.get(
    f'{BASE_URL}/storage/v1/object/public/my-bucket/file.txt'
)
content = response.content

# 删除文件
response = requests.delete(
    f'{BASE_URL}/storage/v1/object/my-bucket/file.txt',
    headers=headers
)

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('my-bucket')
  .upload('file.txt', file)

// 下载文件
const { data: fileData } = await supabase.storage
  .from('my-bucket')
  .download('file.txt')

// 删除文件
await supabase.storage
  .from('my-bucket')
  .remove(['file.txt'])

架构对比

MinIO (S3) 后端

用户 → Supabase Storage API
     → MinIO 容器 (S3协议)
     → /vol1/1000/s3 (对象存储)

优势:

  • 完整的 S3 API 支持
  • 可以用 MinIO Console 管理
  • 文件更新功能正常
  • 可扩展性好

劣势:

  • 需要额外的 MinIO 容器
  • 占用更多资源

文件系统后端

用户 → Supabase Storage API
     → 本地文件系统
     → volumes/storage/undefined/stub/...

优势:

  • 简单,无需额外容器
  • 直接访问文件系统
  • 资源占用少

劣势:

  • 文件更新功能有bug
  • 无管理界面
  • 扩展性差
  • 与 S3 后端数据不兼容

回滚到 MinIO

如需回滚到 MinIO (S3) 后端:

cd /vol1/1000/docker_server/traefik/supabase-stack

# 1. 恢复配置
cp docker-compose.yml.backup-before-rustfs docker-compose.yml

# 2. 重启 Storage
docker compose stop storage
docker compose rm -f storage
docker compose up -d storage

# 3. 启动 MinIO
docker compose -f docker-compose.s3.yml up -d

# 4. 测试
python3 examples/test_https_storage.py

备份文件

迁移过程中创建的备份:

  • docker-compose.yml.backup-before-rustfs - S3 后端配置
  • docker-compose.s3.yml.backup-before-rustfs - MinIO 配置

物理存储位置

文件后端

  • 路径: volumes/storage/undefined/stub/{bucket}/{file}/{version}
  • 格式: 本地文件系统
  • 管理: 直接文件访问

MinIO (旧)

建议

生产环境

不推荐使用文件后端,原因:

  1. 文件更新功能有已知bug
  2. 功能不完整
  3. 无管理界面
  4. 官方主要支持 S3 后端

推荐继续使用 MinIO (S3) 后端。

开发/测试环境

可以使用文件后端,注意:

  1. 避免文件更新操作(使用删除+上传)
  2. 定期备份 volumes/storage 目录
  3. 监控存储空间

相关文档

  • README.md - 主文档
  • docs/FINAL_ARCHITECTURE_MINIO_INTERNAL.md - MinIO 架构说明
  • examples/test_https_storage.py - Storage API 测试

迁移日期: 2025-12-05
执行人: 系统管理员
状态: 完成(功能受限)
建议: 生产环境使用 MinIO