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

439 lines
8.7 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.
# 🚀 课题组网站部署指南
## 📋 最终架构
### 公网 HTTPS 访问
```
https://amiap.hzau.edu.cn/
├── / → MinIO S3 API对象存储
│ └── /stub/ → 默认 bucket
├── /group/ → 🎨 Vue 课题组网站(主站)
│ ├── /group/ - 首页
│ ├── /group/members - 成员介绍
│ ├── /group/research - 研究方向
│ └── /group/... - 其他页面
├── /supa/ → Supabase 后端 API
│ ├── /supa/auth/v1 - 用户认证
│ ├── /supa/rest/v1 - 数据库 REST
│ └── /supa/storage/v1 - 文件存储
└── /ABM/ → ABM 数据库系统
```
### 内网访问Tailscale VPN: 100.64.0.2
```
http://100.64.0.2:18000 → Supabase Dashboard后端管理
http://100.64.0.2:9001 → MinIO ConsoleS3 管理)
```
---
## 🎨 Vue 课题组网站开发
### 1. 项目配置
#### vite.config.js
```javascript
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
base: '/group/', // ⚠️ 必须配置子路径
plugins: [vue()],
server: {
port: 5173
}
})
```
#### router/index.js
```javascript
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory('/group/'), // ⚠️ 必须配置子路径
routes: [
{
path: '/',
name: 'Home',
component: () => import('@/views/Home.vue')
},
{
path: '/members',
name: 'Members',
component: () => import('@/views/Members.vue')
},
{
path: '/research',
name: 'Research',
component: () => import('@/views/Research.vue')
},
{
path: '/publications',
name: 'Publications',
component: () => import('@/views/Publications.vue')
}
]
})
export default router
```
### 2. Supabase 集成
#### src/lib/supabase.js
```javascript
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = 'https://amiap.hzau.edu.cn/supa'
const supabaseKey = import.meta.env.VITE_SUPABASE_ANON_KEY
export const supabase = createClient(supabaseUrl, supabaseKey)
```
#### .env
```bash
VITE_SUPABASE_ANON_KEY=your-anon-key-here
```
#### 使用示例
```vue
<script setup>
import { ref, onMounted } from 'vue'
import { supabase } from '@/lib/supabase'
const members = ref([])
onMounted(async () => {
// 查询团队成员
const { data, error } = await supabase
.from('members')
.select('*')
.order('join_date', { ascending: false })
if (\!error) {
members.value = data
}
})
// 上传文件到 Supabase Storage
async function uploadPhoto(file) {
const { data, error } = await supabase.storage
.from('photos')
.upload(`members/${file.name}`, file)
if (\!error) {
console.log('上传成功:', data.path)
}
}
</script>
```
### 3. 跳转链接配置
```vue
<template>
<div class="admin-panel">
<h3>管理入口内网访问</h3>
<\!-- Supabase 后端管理 -->
<a
href="http://100.64.0.2:18000"
target="_blank"
class="admin-link"
>
<icon>🗄</icon>
<span>Supabase Dashboard</span>
<badge>需要 VPN</badge>
</a>
<\!-- MinIO 存储管理 -->
<a
href="http://100.64.0.2:9001"
target="_blank"
class="admin-link"
>
<icon>💾</icon>
<span>MinIO Console</span>
<badge>需要 VPN</badge>
</a>
<\!-- ABM 数据库 -->
<router-link to="/external/ABM" class="admin-link">
<icon>📊</icon>
<span>ABM 数据库</span>
</router-link>
</div>
</template>
<script setup>
// 外部链接处理
function openExternal(url) {
window.open(url, '_blank')
}
</script>
```
---
## 📦 MinIO S3 存储使用
### 直接上传到 S3大文件
```javascript
// 使用 AWS SDK
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'
const s3Client = new S3Client({
endpoint: 'https://amiap.hzau.edu.cn', // 根路径
region: 'stub',
credentials: {
accessKeyId: import.meta.env.VITE_S3_ACCESS_KEY,
secretAccessKey: import.meta.env.VITE_S3_SECRET_KEY
},
forcePathStyle: true // ⚠️ 必须启用路径风格
})
async function uploadLargeFile(file) {
await s3Client.send(new PutObjectCommand({
Bucket: 'stub',
Key: `publications/${file.name}`,
Body: file,
ContentType: file.type
}))
// 文件 URL: https://amiap.hzau.edu.cn/stub/publications/file.pdf
return `https://amiap.hzau.edu.cn/stub/publications/${file.name}`
}
```
### 使用 Supabase Storage小文件
```javascript
// 推荐用于 < 50MB 的文件
const { data, error } = await supabase.storage
.from('documents')
.upload('research/paper.pdf', file)
// 获取公开 URL
const { data: { publicUrl } } = supabase.storage
.from('documents')
.getPublicUrl('research/paper.pdf')
```
---
## 🚀 部署流程
### 1. 开发环境
```bash
# 创建 Vue 项目
npm create vite@latest group-website -- --template vue
cd group-website
# 安装依赖
npm install @supabase/supabase-js
npm install @aws-sdk/client-s3 # 如果需要直接访问 S3
# 配置 vite.config.js 和 router见上面
# 本地开发
npm run dev
# 访问: http://localhost:5173/group/
```
### 2. 生产部署
```bash
# 构建
npm run build
# 部署到服务器
scp -r dist/* user@server:/vol1/1000/docker_server/traefik/web/group-site/dist/
# 或直接在服务器上
cd /vol1/1000/docker_server/traefik/web/group-site
rm -rf dist/*
# 复制构建产物到 dist/
# 重启服务
docker compose restart
```
### 3. 验证部署
```bash
# 访问网站
curl https://amiap.hzau.edu.cn/group/
# 查看日志
docker logs group-site
# 查看状态
docker ps | grep group-site
```
---
## 📊 数据库设计示例
### Supabase 表结构
```sql
-- 团队成员表
CREATE TABLE members (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(100) NOT NULL,
title VARCHAR(100),
email VARCHAR(100),
photo_url TEXT,
bio TEXT,
research_interests TEXT[],
join_date DATE,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW()
);
-- 研究成果表
CREATE TABLE publications (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
title TEXT NOT NULL,
authors TEXT[],
journal VARCHAR(200),
year INTEGER,
doi VARCHAR(100),
pdf_url TEXT,
abstract TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
-- 研究项目表
CREATE TABLE projects (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(200) NOT NULL,
description TEXT,
status VARCHAR(50),
start_date DATE,
end_date DATE,
funding_source VARCHAR(200),
created_at TIMESTAMP DEFAULT NOW()
);
```
---
## 🎨 页面布局建议
### 首页 (/)
- 课题组介绍
- 最新动态
- 研究领域概览
- 快速链接
### 成员介绍 (/members)
- 导师信息
- 博士生/硕士生
- 校友网络
### 研究方向 (/research)
- 主要研究领域
- 正在进行的项目
- 技术路线
### 论文成果 (/publications)
- 按年份/类别分类
- 搜索和筛选
- 下载链接
### 管理入口(仅内网)
- Supabase Dashboard 链接
- MinIO Console 链接
- ABM 系统链接
---
## 🔧 常用命令
### 开发调试
```bash
npm run dev # 启动开发服务器
npm run build # 构建生产版本
npm run preview # 预览生产构建
```
### 服务器管理
```bash
# 查看所有服务
docker ps | grep -E '(minio|group|supabase)'
# 重启服务
cd /vol1/1000/docker_server/traefik/web/group-site
docker compose restart
# 查看日志
docker logs -f group-site
# 更新代码
cd /vol1/1000/docker_server/traefik/web/group-site
git pull # 如果使用 git
docker compose restart
```
---
## 📞 故障排查
### Vue 网站 404
- 检查 `base: '/group/'` 配置
- 检查 Nginx try_files 配置
- 清除浏览器缓存
### 静态资源加载失败
- 确认 vite.config.js 中 base 设置
- 检查文件权限:`chmod -R 755 dist/`
### Supabase API 调用失败
- 检查 CORS 配置
- 验证 API Key
- 查看浏览器控制台错误
### S3 上传失败
- 确认 forcePathStyle: true
- 检查 credentials
- 验证 bucket 存在
---
## 🎉 最终检查清单
部署前确认:
- [ ] vite.config.js 配置 `base: '/group/'`
- [ ] router 配置 `createWebHistory('/group/')`
- [ ] Supabase client 配置正确
- [ ] 环境变量已设置
- [ ] 测试所有路由
- [ ] 测试文件上传
- [ ] 测试 Supabase 查询
- [ ] 内网链接可访问
- [ ] 响应式设计检查
- [ ] 浏览器兼容性测试
---
**架构设计**: ✅
**配置完成**: ✅
**开发就绪**: ✅
**开始开发你的课题组网站吧!** 🚀
有任何问题,参考:
- FINAL_ARCHITECTURE_v2.md - 架构说明
- web/group-site/README.md - 部署配置