19 KiB
Traefik 反向代理 + 多服务部署平台
基于 Traefik 的统一网关架构,支持多个 Web 应用和后端服务的集中管理和部署。
域名: amiap.hzau.edu.cn
核心架构: Traefik + Supabase + MinIO (内网) + Vue.js + WebSocket 服务
📊 系统架构总览
整体架构图
┌─────────────────────────────────────────────────────────┐
│ Internet (HTTPS) │
│ https://amiap.hzau.edu.cn │
└────────────────────┬────────────────────────────────────┘
│
┌──────────▼──────────┐
│ Traefik Gateway │ ← Let's Encrypt 自动证书
│ (反向代理+路由) │
└──────────┬──────────┘
│
┌────────────┼────────────┐
│ │ │
┌────▼───┐ ┌────▼────┐ ┌───▼────┐
│Supabase│ │Web Apps │ │Derper │
│ Stack │ │ (多项目)│ │ │
└────┬───┘ └─────────┘ └────────┘
│
┌────▼────┐
│ MinIO │ ← 内网存储
│ (内网) │
└─────────┘
核心设计原则
✅ MinIO 内网化: 对象存储不暴露公网,仅通过 Tailscale VPN 访问
✅ 统一网关: 所有公网服务通过 Traefik 统一入口
✅ 安全隔离: 管理界面仅内网可访问
✅ 自动证书: Let's Encrypt 自动申请和续期 HTTPS 证书
🌐 URL 路由规划
公网访问 (HTTPS)
| 服务 | URL | 说明 | 状态 |
|---|---|---|---|
| 主站 | https://amiap.hzau.edu.cn/ |
自动跳转到 /group/ (302) | ✅ |
| 课题组网站 | 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 项目 | ✅ |
| Derper | https://amiap.hzau.edu.cn/derp |
Tailscale DERP | ✅ |
内网访问 (Tailscale VPN)
| 服务 | URL | 说明 | 状态 |
|---|---|---|---|
| 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 |
数据库管理 | ✅ |
Supabase API 端点
https://amiap.hzau.edu.cn/supa/
├── auth/v1/ # 用户认证
├── rest/v1/ # 数据库 REST API
├── storage/v1/ # 文件存储
└── realtime/v1/ # 实时订阅
🚀 快速开始
1. 启动 Traefik 网关
cd /vol1/1000/docker_server/traefik
docker compose up -d
# 快速启动方式
cd supabase-stack
docker compose -f docker-compose.yml -f docker-compose.s3.yml up
2. 启动 Supabase 后端
cd supabase-stack
# 🔥 推荐:同时启动核心服务 + MinIO S3 对象存储
docker compose -f docker-compose.yml -f docker-compose.s3.yml up -d
# 查看所有服务状态
docker compose ps
# 测试 Storage API
python3 examples/test_https_storage.py
详细文档:
- supabase-stack/README_CN.md - 中文完整指南
- supabase-stack/README_STORAGE.md - Storage 使用指南
- supabase-stack/docs/QUICK_START.md - 快速入门
3. 部署课题组网站
cd web/group-site
# 复制你的 Vue 构建文件到 dist/
cp -r /path/to/your-vue-project/dist ./
# 启动
docker compose up -d
Vue 项目集成 Supabase:详见 VUE_API_INTEGRATION.md
4. 部署 ABM 数据库
cd web/ws
# 启动服务(Go 后端 + PostgreSQL)
docker compose up -d
# 查看日志
docker compose logs -f
访问:https://amiap.hzau.edu.cn/ABM
📊 存储架构说明
MinIO 内网化存储流程
公网访问流程:
用户(公网)
↓
https://amiap.hzau.edu.cn/supa/storage/v1/
↓ Traefik → Kong
Supabase Storage Service
↓ 内部网络(不暴露公网)
MinIO (http://minio:9000)
↓
物理存储: /vol1/1000/s3
内网访问流程 (需要 Tailscale VPN):
管理员(通过 Tailscale VPN)
↓
http://100.64.0.2:9000 (MinIO S3 API)
http://100.64.0.2:9001 (MinIO Console)
↓
物理存储: /vol1/1000/s3
关键特性
✅ 安全隔离: MinIO 不暴露到公网,仅通过内部网络访问
✅ 统一入口: 所有公网文件访问通过 Supabase Storage API
✅ 权限控制: 通过 Supabase RLS 实现细粒度权限管理
✅ 内网管理: 管理界面仅 Tailscale VPN 可访问
✅ 根路径重定向: 自动跳转到课题组网站
🔐 MinIO 访问
内网访问(需要 Tailscale VPN)
MinIO Console:
- URL:
http://100.64.0.2:9001 - 用户名:
bsxzZAJ3fvDquup - 密码: (见
supabase-stack/.env)
MinIO S3 API:
- URL:
http://100.64.0.2:9000 - Access Key: 同上
- Secret Key: 同上
公网访问(通过 Supabase Storage API)
import requests
BASE_URL = 'https://amiap.hzau.edu.cn/supa'
API_KEY = 'your_anon_key' # 见 supabase-stack/.env
headers = {
'apikey': API_KEY,
'Authorization': f'Bearer {API_KEY}'
}
# 上传文件
with open('file.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
)
📁 目录结构
/vol1/1000/docker_server/traefik/
│
├── 📁 核心配置
│ ├── docker-compose.yml # Traefik 网关 + Derper
│ ├── .gitignore # Git 忽略规则
│ ├── README.md # 本文档(完整指南)
│ └── ARCHITECTURE_SUMMARY.md # 架构总览(已整合)
│
├── 📁 docs/ # 部署策略文档
│ ├── strategy-1-path-prefix.md # 路径前缀方案(当前使用)
│ ├── strategy-2-subdomain.md # 子域名方案
│ ├── strategy-3-hybrid.md # 混合方案
│ └── strategy-comparison-report.md # 策略对比分析
│
├── 📁 supabase-stack/ # 🔥 Supabase 后端服务
│ ├── docker-compose.yml # 核心服务(PostgreSQL, Auth, REST, etc.)
│ ├── docker-compose.s3.yml # MinIO 对象存储(内网)
│ ├── .env # 环境变量和凭证
│ ├── README_CN.md # 中文使用指南
│ ├── README_STORAGE.md # Storage 对象存储指南
│ ├── MINIO_GUIDE.md # MinIO S3 完整使用指南
│ ├── docs/ # 详细文档
│ │ ├── QUICK_START.md # 快速入门
│ │ ├── OPERATIONS_GUIDE.md # 运维指南
│ │ ├── VUE_API_INTEGRATION.md # Vue 集成教程
│ │ └── FINAL_ARCHITECTURE_MINIO_INTERNAL.md # MinIO 内网化详细说明
│ └── examples/ # 示例代码
│ ├── storage_client.py # Python 客户端
│ ├── storage_client.js # JavaScript 客户端
│ └── test_https_storage.py # 测试脚本
│
└── 📁 web/ # Web 应用项目
├── redirect-root/ # 根路径重定向(到 /group/)
├── group-site/ # 课题组网站(Vue.js)
├── ws/ # ABM 数据库项目
│ ├── docker-compose.yml # 项目配置
│ ├── backend/ # Go 后端
│ └── postgres_data/ # PostgreSQL 数据
├── gzy/ # GZY 项目(待部署)
└── zz/ # ZZ 项目(待部署)
🛠️ 常用命令
查看服务状态
# 查看所有相关容器
docker ps | grep -E "traefik|supabase|minio"
# Traefik + Derper
cd /vol1/1000/docker_server/traefik
docker compose ps
# Supabase 服务
cd supabase-stack
docker compose ps
# Web 应用
cd web/ws
docker compose ps
重启服务
# 重启 Traefik
cd /vol1/1000/docker_server/traefik
docker compose restart traefik
# 重启 Supabase 特定服务
cd supabase-stack
docker compose restart kong
docker compose restart storage
# 重启 Supabase + MinIO 全部服务
docker compose -f docker-compose.yml -f docker-compose.s3.yml restart
# 重启 Web 应用
cd web/ws
docker compose restart
停止服务
# 停止所有服务
docker compose down
# 停止并删除数据卷(慎用!)
docker compose down -v
更新服务
# 拉取最新镜像
docker compose pull
# 重新构建和启动
docker compose up -d --build
查看日志
# Traefik 日志
docker compose logs -f traefik
# Supabase 日志
cd supabase-stack
docker compose logs -f kong
docker compose logs -f storage
docker logs supabase-minio-1 --tail 50
# Web 应用日志
cd web/ws
docker compose logs -f
# 查看所有容器日志
docker compose logs -f --tail=100
测试 API
# 测试根路径重定向
curl -I https://amiap.hzau.edu.cn
# 测试 Supabase Storage
curl https://amiap.hzau.edu.cn/supa/storage/v1/bucket
# 测试 Supabase Auth
curl https://amiap.hzau.edu.cn/supa/auth/v1/health
# 测试 ABM 服务
curl https://amiap.hzau.edu.cn/ABM
# 测试 MinIO 内网访问(需要 Tailscale VPN)
curl -I http://100.64.0.2:9001
# 运行 MinIO 完整功能测试
cd supabase-stack
python3 examples/test_https_storage.py
📚 详细文档
Traefik 部署策略
| 文档 | 说明 |
|---|---|
| strategy-1-path-prefix.md | 路径前缀方案(当前使用) |
| strategy-2-subdomain.md | 子域名方案 |
| strategy-3-hybrid.md | 混合方案 |
| strategy-comparison-report.md | 策略对比分析 |
Supabase 文档
| 文档 | 说明 |
|---|---|
| supabase-stack/README_CN.md | 🔥 完整使用指南(中文) |
| supabase-stack/README_STORAGE.md | Storage 对象存储指南 |
| supabase-stack/MINIO_GUIDE.md | MinIO S3 完整使用指南 |
| supabase-stack/docs/QUICK_START.md | 快速入门 |
| supabase-stack/docs/OPERATIONS_GUIDE.md | 运维指南 |
| supabase-stack/docs/VUE_API_INTEGRATION.md | Vue 集成教程 |
| supabase-stack/docs/FINAL_ARCHITECTURE_MINIO_INTERNAL.md | MinIO 内网化详细说明 |
示例代码
| 文件 | 说明 |
|---|---|
| supabase-stack/examples/storage_client.py | Python 完整客户端 |
| supabase-stack/examples/storage_client.js | JavaScript 完整客户端 |
| supabase-stack/examples/test_https_storage.py | 测试脚本 |
🔍 故障排查
Traefik 无法启动
# 检查端口占用
sudo netstat -tlnp | grep ':80\|:443\|:8080'
# 查看 Traefik 日志
cd /vol1/1000/docker_server/traefik
docker compose logs traefik
# 查看证书状态
docker compose logs traefik | grep -i "certificate"
Supabase 服务问题
cd supabase-stack
# 查看所有服务状态
docker compose ps
# 查看特定服务日志
docker compose logs -f kong
docker compose logs -f storage
docker compose logs -f db
# 重启服务
docker compose restart
常见问题:
- supabase-pooler 一直重启 - 可以忽略,不影响功能(详见 README_CN.md)
- Storage API 403 错误 - 检查 RLS 策略和 API 密钥
- 数据库连接失败 - 检查 PostgreSQL 是否正常运行
Supabase Storage API 404
# 检查 Kong 状态
docker ps | grep kong
docker logs supabase-kong --tail 50
# 确认 Kong 健康
docker inspect supabase-kong --format='{{.State.Health.Status}}'
# 检查 Storage 服务
docker compose logs -f storage
MinIO 内网无法访问
# 确认 Tailscale 连接
tailscale status
ping 100.64.0.2
# 检查 MinIO 容器状态
docker ps | grep minio
docker logs supabase-minio-1 --tail 50
# 检查 MinIO 端口
docker port supabase-minio-1
根路径不跳转
# 检查 redirect-root 容器
docker ps | grep redirect-root
docker logs redirect-root --tail 20
# 测试重定向
curl -I https://amiap.hzau.edu.cn
Web 应用问题
cd web/ws
# 查看容器状态
docker compose ps
# 查看日志
docker compose logs -f
# 进入容器调试
docker compose exec webws /bin/sh
SSL 证书问题
# 查看证书状态
cd /vol1/1000/docker_server/traefik
docker compose logs traefik | grep -i "certificate"
# 删除旧证书重新申请(慎用!)
docker volume rm traefik_acme-data
docker compose up -d
⚙️ 配置说明
Traefik 配置
docker-compose.yml 关键配置:
services:
traefik:
image: traefik:v3.0
command:
- "--api.dashboard=true"
- "--providers.docker=true"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.email=lyzeng@hzau.edu.cn"
ports:
- "80:80"
- "443:443"
- "8080:8080" # Dashboard
访问 Traefik Dashboard:http://服务器IP:8080
Supabase 配置
主要配置文件:
.env- 环境变量(密钥、数据库配置等)docker-compose.yml- 核心服务docker-compose.s3.yml- MinIO 对象存储
关键环境变量:
# API 密钥
ANON_KEY=eyJhbGc... # 前端使用
SERVICE_ROLE_KEY=eyJ... # 后端使用
# 数据库
POSTGRES_PASSWORD=your-password
# MinIO 对象存储
MINIO_ROOT_USER=bsxzZAJ3fvDquup
MINIO_ROOT_PASSWORD=your-minio-password
# 内网访问
MinIO S3 API: http://100.64.0.2:9000
MinIO Console: http://100.64.0.2:9001
Web 应用配置
每个项目独立配置,示例(web/ws):
services:
webws:
labels:
- "traefik.enable=true"
- "traefik.http.routers.webws.rule=Host(`amiap.hzau.edu.cn`) && PathPrefix(`/ABM`)"
- "traefik.http.routers.webws.entrypoints=websecure"
- "traefik.http.routers.webws.tls.certresolver=myresolver"
📝 开发指南
添加新的 Web 应用
- 在
web/下创建项目目录 - 创建
docker-compose.yml - 配置 Traefik 标签
示例:
services:
myapp:
image: myapp:latest
networks:
- frontend
labels:
- "traefik.enable=true"
- "traefik.http.routers.myapp.rule=Host(`amiap.hzau.edu.cn`) && PathPrefix(`/myapp`)"
- "traefik.http.routers.myapp.entrypoints=websecure"
- "traefik.http.routers.myapp.tls.certresolver=myresolver"
- "traefik.http.middlewares.myapp-stripprefix.stripprefix.prefixes=/myapp"
- "traefik.http.routers.myapp.middlewares=myapp-stripprefix"
networks:
frontend:
external: true
前端开发集成 Supabase
Vue 项目集成:
// src/lib/supabaseClient.js
import { createClient } from '@supabase/supabase-js'
export const supabase = createClient(
'https://amiap.hzau.edu.cn/supa',
'your-anon-key'
)
Storage API 使用
Python:
from examples.storage_client import SupabaseStorageClient
client = SupabaseStorageClient(
'https://amiap.hzau.edu.cn/supa',
'your-service-role-key'
)
# 上传文件
client.upload_file('bucket', 'photo.jpg', 'uploads/photo.jpg')
# 生成临时下载链接
url = client.create_signed_url('bucket', 'uploads/photo.jpg', 3600)
JavaScript:
const client = new SupabaseStorageClient(
'https://amiap.hzau.edu.cn/supa',
'your-service-role-key'
);
// 上传文件
await client.uploadFile('bucket', fileObject, 'uploads/photo.jpg');
// 生成临时下载链接
const url = await client.createSignedUrl('bucket', 'uploads/photo.jpg', 3600);
🎯 最佳实践
部署流程
- 开发环境 → 本地测试
- 测试环境 → 内网测试
- 生产环境 → 公网部署
备份策略
# 备份 Supabase 数据库
cd supabase-stack
docker exec supabase-db pg_dump -U postgres postgres > backup_$(date +%Y%m%d).sql
# 备份 MinIO 数据
tar -czf minio_backup_$(date +%Y%m%d).tar.gz /vol1/1000/s3/
# 备份配置文件
tar -czf config_backup_$(date +%Y%m%d).tar.gz .env docker-compose*.yml
监控和日志
# 实时监控资源使用
docker stats
# 查看所有容器日志
docker compose logs -f --tail=100
# 日志持久化(可选)
mkdir -p /var/log/docker
docker compose logs > /var/log/docker/traefik_$(date +%Y%m%d).log
性能优化
- 数据库连接池 - Supabase pooler(可选)
- CDN 加速 - 静态资源使用 CDN
- 缓存策略 - Traefik 支持缓存中间件
- 负载均衡 - 多实例部署
🔒 安全配置
SSL/TLS 证书
- 使用 Let's Encrypt 自动申请和续期
- 证书存储在
acme-dataDocker volume 中 - 自动 HTTP 到 HTTPS 重定向
访问控制
- ✅ MinIO 不暴露到公网,仅内网访问
- ✅ Supabase Dashboard 仅内网访问(
http://100.64.0.2:18000) - ✅ Traefik Dashboard 端口 8080(建议配置认证)
- ✅ 生产环境建议配置防火墙规则
API 密钥管理
ANON_KEY- 前端使用,权限受 RLS 限制SERVICE_ROLE_KEY- 后端使用,完全权限,需严格保密- 所有公网服务使用 HTTPS + Let's Encrypt 证书
- 公网文件访问通过 Supabase API(支持权限控制)
📞 技术支持
相关链接
项目信息
- 域名: amiap.hzau.edu.cn
- 服务器: HZAU Lab Server
- 部署日期: 2025-11-22
- 维护团队: Lab Admin
快速导航:
版本: v3.0 (MinIO 内网化)
更新日期: 2025-11-23
状态: ✅ 生产就绪
🎉 开始使用 Traefik + Supabase 部署平台!