Files
labweb/docs/strategy-1-path-prefix.md
zly 9a261bb265 chore: 添加 .gitignore 和 Traefik 部署策略文档
.gitignore 更新:
- 添加 pixi 环境和 .claude 目录忽略
- 添加 supabase-stack 相关忽略规则
- 添加 web/ws/postgres_data/pgdata/ 数据库数据忽略

docs/ 文档:
- strategy-1-path-prefix.md: 路径前缀部署方案
- strategy-2-subdomain.md: 子域名部署方案
- strategy-3-hybrid.md: 混合部署方案
- strategy-comparison-report.md: 策略对比报告

这些文档详细说明了 Traefik 反向代理的三种部署策略,
为多应用部署提供参考方案。
2025-11-22 21:30:19 +08:00

9.5 KiB
Raw Blame History

策略 1路径前缀部署方案

📋 策略概述

核心思想:使用单一域名,通过 URL 路径前缀区分不同的网站或应用。

访问方式

https://amiap.hzau.edu.cn/ABM      # ABM 数据库
https://amiap.hzau.edu.cn/lab      # 实验室主页
https://amiap.hzau.edu.cn/docs     # 文档中心
https://amiap.hzau.edu.cn/         # 主站或 decoy 站点

🏗️ 技术架构

路由配置

services:
  nginx-abm:
    labels:
      - "traefik.http.routers.abm.rule=Host(`amiap.hzau.edu.cn`) && PathPrefix(`/ABM`)"
      - "traefik.http.routers.abm.priority=100"  # 关键配置!
      
  nginx-lab:
    labels:
      - "traefik.http.routers.lab.rule=Host(`amiap.hzau.edu.cn`) && PathPrefix(`/lab`)"
      - "traefik.http.routers.lab.priority=100"
      
  decoy-site:
    labels:
      - "traefik.http.routers.decoy.rule=Host(`amiap.hzau.edu.cn`) && Path(`/`)"
      - "traefik.http.routers.decoy.priority=1"  # 最低优先级

文件系统结构

容器 1 (ABM):
/usr/share/nginx/html/
└── ABM/                    ← 关键:路径必须对齐
    ├── index.html
    ├── css/
    ├── js/
    └── img/

容器 2 (Lab):
/usr/share/nginx/html/
└── lab/                    ← 路径对齐
    ├── index.html
    └── assets/

容器 3 (Docs):
/usr/share/nginx/html/
└── docs/                   ← 路径对齐
    ├── index.html
    └── static/

工作流程

1. 用户访问: https://amiap.hzau.edu.cn/ABM/
   ↓
2. Traefik 匹配: PathPrefix(/ABM), priority=100
   ↓
3. 转发到容器: GET /ABM/
   ↓
4. Nginx 查找: /usr/share/nginx/html/ABM/index.html
   ↓
5. 返回页面: HTML 中链接 <a href="page.html">
   ↓
6. 浏览器计算: /ABM/ + page.html = /ABM/page.html ✅

优点分析

1. 无需 DNS 配置

  • 优势:适用于没有 DNS 管理权限的场景
  • 场景:学校服务器、共享主机、临时测试环境
  • 成本:零额外配置成本

2. 证书管理简单

  • 优势:只需一个域名证书
  • 对比:子域名方案需要通配符证书或多个证书
  • 实施Let's Encrypt HTTP Challenge 即可

3. 部署快速

  • 优势:可以快速启动新项目
  • 时间5-10 分钟即可部署一个新网站
  • 流程:复制配置模板 → 调整路径 → 启动容器

4. 资源节约

  • 优势:共享同一个 SSL 连接和证书
  • 性能:减少 TLS 握手次数
  • 带宽:共享连接池

5. 适合小规模部署

  • 优势:网站数量 ≤ 5 个时管理简单
  • 维护:配置文件集中管理
  • 可控:问题排查相对容易

缺点分析

1. 必须配置优先级(容易出错)

问题

# 如果忘记设置 priority
PathPrefix(/ABM)          # priority 默认可能为 0
Path(/)                   # priority 默认可能为 0
# 可能导致路由匹配混乱

后果

  • CSS/JS 文件加载失败
  • 静态资源返回 404
  • 页面样式错乱

解决成本:每次添加网站都需要仔细检查优先级设置

2. 必须调整文件结构

问题

# 原始网站文件结构
/index.html
/css/style.css
/js/app.js

# 必须调整为
/ABM/index.html
/ABM/css/style.css
/ABM/js/app.js

后果

  • 需要重新组织文件
  • 可能破坏原有构建流程
  • 增加部署复杂度

解决成本:每个网站都需要手动调整结构

3. 不能使用 StripPrefix或受限使用

问题

# 使用 StripPrefix 会导致路径问题
PathPrefix(/ABM) + StripPrefix(/ABM)
# HTML: <a href="page.html">
# 访问: /page.html ❌ 丢失前缀

限制

  • 相对路径链接会失效
  • 需要修改 HTML 添加 <base> 标签
  • 或者所有链接改为绝对路径

解决成本:修改网站代码或构建流程

4. 路由规则复杂度增加

问题

# 需要处理的规则越来越多
PathPrefix(/ABM)           priority=100
PathPrefix(/lab)           priority=100
PathPrefix(/docs)          priority=100
PathPrefix(/api)           priority=100
PathPrefix(/downloads)     priority=100
...
Path(/)                    priority=1

后果

  • 配置文件变得冗长
  • 容易遗漏或重复
  • 维护成本上升

5. 性能稍差

原因

  • Traefik 需要匹配多个 PathPrefix 规则
  • 路径匹配比域名匹配慢 10-20%
  • 多个路由规则增加计算开销

影响

  • 高并发下略有影响
  • 规则越多越明显
  • 对小流量影响不大

6. 扩展性受限

问题

  • 网站数量增多时,优先级管理变得复杂
  • 容易出现优先级冲突
  • 调试困难度上升

临界点:当网站数量超过 5 个,维护成本指数级上升

7. 无法实现完全隔离

问题

  • 所有网站共享同一个域名
  • 无法为不同网站设置不同的安全策略
  • Cookie 作用域可能冲突(同域名)

🎯 适用场景

最适合的场景

1. 无 DNS 管理权限

场景:学校提供的服务器,无法添加子域名
方案:使用路径前缀,无需 DNS 配置
示例https://server.university.edu.cn/myproject

2. 临时项目或测试环境

场景:快速搭建演示环境,项目周期短
方案:路径前缀部署快速,无需长期维护
示例:展示给客户的 Demo 网站

3. 小规模部署≤3个网站

场景:个人博客、小团队项目
网站:主站 + 博客 + API 文档
维护:配置简单,管理容易

4. 预算受限

场景:不想购买多个域名或证书
成本:单域名 + 单证书
适用:个人项目、非盈利项目

⚠️ 不太适合的场景

1. 生产环境(网站 ≥5个

  • 优先级管理复杂
  • 维护成本高
  • 易出错

2. 高流量网站

  • 性能不是最优
  • 路由匹配有额外开销

3. 需要强隔离的多租户系统

  • 无法完全隔离
  • Cookie 可能冲突
  • 安全策略难以分离

4. 长期运行的企业应用

  • 扩展性受限
  • 不利于未来增长

📊 性能指标

路由匹配性能

单次路由匹配时间0.1-0.5ms
随网站数量线性增长:每增加 1 个网站 +0.05ms
临界点10 个网站时性能下降明显

内存占用

单个网站额外内存:~5MBTraefik 路由规则)
10 个网站:~50MB 路由规则内存

CPU 使用

路径匹配 CPU 开销:比子域名高 15-20%
高并发场景影响:中等流量下可忽略

🛠️ 最佳实践

1. 优先级设置规范

# 具体路径100-200
PathPrefix(/ABM/api)      priority=200
PathPrefix(/ABM)          priority=100

# 通用路径50
PathPrefix(/static)       priority=50

# 根路径1
Path(/)                   priority=1

2. 文件结构标准

# 严格遵循路径对齐原则
URL: /ABM/page.html
文件: /usr/share/nginx/html/ABM/page.html

# 使用脚本自动化调整
#!/bin/bash
mkdir -p /target/ABM
mv /source/* /target/ABM/

3. 配置模板化

# 创建配置模板
x-website-template: &website-template
  image: nginx:alpine
  networks:
    - frontend
  labels:
    - "traefik.enable=true"
    - "traefik.http.routers.SITENAME.entrypoints=web,websecure"
    - "traefik.http.routers.SITENAME.tls.certresolver=myresolver"
    
# 使用模板
nginx-abm:
  <<: *website-template
  volumes:
    - abm-data:/usr/share/nginx/html:ro
  labels:
    - "traefik.http.routers.abm.rule=Host(`amiap.hzau.edu.cn`) && PathPrefix(`/ABM`)"
    - "traefik.http.routers.abm.priority=100"

4. 监控和日志

# 定期检查路由匹配
docker logs traefik-reverse | grep "404\|403"

# 验证优先级配置
docker inspect traefik-reverse | jq '.Config.Labels'

💰 成本分析

时间成本

初次部署30-60 分钟
添加新网站10-20 分钟
维护成本:中等(需要管理优先级)

资源成本

域名1 个(共享)
证书1 个Let's Encrypt 免费)
服务器:共享,无额外需求

学习成本

Traefik 基础:中等
优先级规则:需要理解
文件结构调整:简单
总体:中等难度

🔄 迁移路径

从路径前缀迁移到子域名

步骤

  1. 申请 DNS 记录(保留旧路径)
  2. 添加子域名路由规则
  3. 调整文件结构(移回根目录)
  4. 通知用户新 URL
  5. 观察 1-2 周后删除旧路由

工具

#!/bin/bash
# 迁移脚本
# 从 /ABM/index.html 移回 /index.html
mv /usr/share/nginx/html/ABM/* /usr/share/nginx/html/
rmdir /usr/share/nginx/html/ABM

📝 决策建议

选择此策略的理由

  1. 你没有 DNS 管理权限
  2. 项目是临时性的(< 6 个月)
  3. 网站数量少(≤ 3 个)
  4. 快速部署优先于长期维护
  5. 预算有限,不想购买多个域名

不选择此策略的理由

  1. 你有 DNS 管理权限 → 选择策略 2
  2. 这是长期运行的生产环境 → 选择策略 2
  3. 网站数量会持续增长 → 选择策略 2
  4. 追求最佳性能和可维护性 → 选择策略 2

📚 相关文档


结论:路径前缀策略是一个权宜之计,适合快速部署和小规模场景,但不是长期最佳方案。如果有条件,建议尽早迁移到子域名策略。