Update DESIGN.md and OPS_MANUAL.md for domain and subpath deployment
- Add www.ityb.me domain info and /careerbot subpath architecture docs - Document BASE_PATH routing prefix mechanism in DESIGN.md - Update all URLs from IP to domain in OPS_MANUAL.md - Update Nginx config section to reflect subpath proxy - Update new project deployment guide with subpath pattern Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
501f8985ec
commit
2c1688b4bb
53
DESIGN.md
53
DESIGN.md
@ -7,6 +7,14 @@ CareerBot 是一个个人职业展示网站,集成了 AI 智能对话助手。
|
||||
- **访问者(招聘方)**:浏览候选人的职业背景,通过 AI 对话深入了解候选人,上传 JD 进行匹配分析
|
||||
- **管理员(候选人)**:管理个人资料、教育/工作经历、技能等内容,配置 LLM,管理访问令牌,查看招聘意向消息,生成定制简历
|
||||
|
||||
### 线上地址
|
||||
|
||||
| 用途 | 地址 |
|
||||
|------|------|
|
||||
| 主页 | `http://www.ityb.me/careerbot/` |
|
||||
| 管理后台 | `http://www.ityb.me/careerbot/admin/login` |
|
||||
| Gitea 代码仓库 | `http://www.ityb.me:3000` |
|
||||
|
||||
### 技术栈
|
||||
|
||||
| 层级 | 技术 |
|
||||
@ -19,6 +27,7 @@ CareerBot 是一个个人职业展示网站,集成了 AI 智能对话助手。
|
||||
| 认证 | JWT (管理员) / Cookie (访问者) |
|
||||
| 密码加密 | bcrypt |
|
||||
| 文件处理 | python-docx, PyPDF2, Pillow |
|
||||
| 反向代理 | Nginx (子路径部署) |
|
||||
|
||||
---
|
||||
|
||||
@ -28,8 +37,8 @@ CareerBot 是一个个人职业展示网站,集成了 AI 智能对话助手。
|
||||
CareerBot/
|
||||
├── app/
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py # FastAPI 应用入口,启动初始化
|
||||
│ ├── config.py # Pydantic Settings 配置
|
||||
│ ├── main.py # FastAPI 应用入口,路由挂载,启动初始化
|
||||
│ ├── config.py # Pydantic Settings 配置(含 BASE_PATH)
|
||||
│ ├── database.py # SQLAlchemy 引擎、Session、init_db
|
||||
│ ├── models.py # 全部 ORM 模型定义
|
||||
│ ├── routers/
|
||||
@ -125,6 +134,39 @@ CareerBot/
|
||||
└─────────────────────┘
|
||||
```
|
||||
|
||||
### 3.1 子路径部署架构(BASE_PATH)
|
||||
|
||||
CareerBot 部署在域名的 `/careerbot` 子路径下,通过 `BASE_PATH` 配置实现全局路径前缀管理:
|
||||
|
||||
```
|
||||
浏览器请求: http://www.ityb.me/careerbot/api/profile
|
||||
│
|
||||
▼
|
||||
Nginx (:80)
|
||||
location /careerbot/ → proxy_pass http://127.0.0.1:8000/careerbot/
|
||||
│
|
||||
▼
|
||||
FastAPI (uvicorn :8000)
|
||||
app.include_router(public.router, prefix="/careerbot")
|
||||
→ 匹配路由: @router.get("/api/profile")
|
||||
→ 实际路径: /careerbot/api/profile
|
||||
```
|
||||
|
||||
**前缀注入机制:**
|
||||
|
||||
| 层级 | 方式 | 说明 |
|
||||
|------|------|------|
|
||||
| Python 路由 | `app.include_router(prefix=BASE)` | 所有路由自动加前缀,路由装饰器不变 |
|
||||
| 静态文件 | `app.mount(f"{BASE}/static", ...)` | CSS/JS/图片通过 `/careerbot/static/` 访问 |
|
||||
| Jinja2 模板 | `templates.env.globals["base"]` | 模板中用 `{{ base }}` 引用前缀 |
|
||||
| 前端 JS | `window.BASE_PATH` | 在模板中注入,JS 文件通过全局变量使用 |
|
||||
| RedirectResponse | `url=f"{BASE}/login"` | Python 重定向使用完整路径 |
|
||||
| DB 存储路径 | `photo_url = f"{BASE}/uploads/..."` | 持久化数据中的 URL 包含前缀 |
|
||||
|
||||
**配置位置:**
|
||||
- `app/config.py` → `BASE_PATH: str = "/careerbot"`
|
||||
- 修改此值即可将应用迁移到其他子路径
|
||||
|
||||
---
|
||||
|
||||
## 4. 数据模型(类图)
|
||||
@ -641,8 +683,11 @@ data: {"content": "", "done": true} ← 结束标记
|
||||
### 前端处理逻辑 (chat.js)
|
||||
|
||||
```javascript
|
||||
// 0. BASE_PATH 由模板注入: window.BASE_PATH = "{{ base }}"
|
||||
const BASE_PATH = window.BASE_PATH || '';
|
||||
|
||||
// 1. POST FormData (session_id + message + file?)
|
||||
const response = await fetch('/api/chat', { method: 'POST', body: formData });
|
||||
const response = await fetch(BASE_PATH + '/api/chat', { method: 'POST', body: formData });
|
||||
|
||||
// 2. 读取 ReadableStream
|
||||
const reader = response.body.getReader();
|
||||
@ -696,3 +741,5 @@ while (true) {
|
||||
| BackgroundTask 做意图检测 | 避免阻塞 SSE 流或导致连接异常 |
|
||||
| 意图检测用独立 DB Session | BackgroundTask 执行时请求级 Session 已关闭 |
|
||||
| FAB 按钮用内层 span flex | Chrome 对 button 元素的 flex 布局有渲染 bug |
|
||||
| 子路径部署 + BASE_PATH | 支持同域名多项目部署,一处配置全局生效 |
|
||||
| Jinja2 globals + window.BASE_PATH | 模板和静态 JS 统一获取路径前缀,避免硬编码 |
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
|------|------|
|
||||
| 云服务商 | 阿里云 ECS |
|
||||
| 公网 IP | `39.106.14.107` |
|
||||
| 域名 | `ityb.me` / `www.ityb.me` |
|
||||
| 操作系统 | Alibaba Cloud Linux 3 (OpenAnolis Edition) |
|
||||
| 配置 | 2 核 CPU / 2GB 内存 / 40GB 磁盘 |
|
||||
| Python 版本 | 3.11.13 |
|
||||
@ -36,8 +37,9 @@ ssh root@39.106.14.107 # root 直连
|
||||
|
||||
| 系统 | 地址 | 账号 | 密码 |
|
||||
|------|------|------|------|
|
||||
| CareerBot 管理后台 | `http://39.106.14.107/admin/login` | `ln0422@gmail.com` | `qshs123456` |
|
||||
| Gitea 代码管理 | `http://39.106.14.107:3000` | `ln0422` | `Qshs123456_` |
|
||||
| CareerBot 主页 | `http://www.ityb.me/careerbot/` | (访问令牌或匿名) | - |
|
||||
| CareerBot 管理后台 | `http://www.ityb.me/careerbot/admin/login` | `ln0422@gmail.com` | `qshs123456` |
|
||||
| Gitea 代码管理 | `http://www.ityb.me:3000` | `ln0422` | `Qshs123456_` |
|
||||
|
||||
### 2.3 ECS 用户密码
|
||||
|
||||
@ -52,21 +54,24 @@ ssh root@39.106.14.107 # root 直连
|
||||
## 3. 服务架构
|
||||
|
||||
```
|
||||
外部访问
|
||||
外部访问 (www.ityb.me)
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Nginx (:80) │
|
||||
│ 配置: /etc/nginx/sites-enabled/ │
|
||||
│ 日志: /var/log/nginx/ │
|
||||
├─────────────────────────────────────────┤
|
||||
│ http://39.106.14.107/ │
|
||||
│ → proxy_pass http://127.0.0.1:8000 │
|
||||
│ → CareerBot (uvicorn) │
|
||||
├─────────────────────────────────────────┤
|
||||
│ http://39.106.14.107:3000 │
|
||||
│ → Gitea (直接监听,未经 Nginx 代理) │
|
||||
└─────────────────────────────────────────┘
|
||||
┌──────────────────────────────────────────────────────┐
|
||||
│ Nginx (:80) │
|
||||
│ 配置: /etc/nginx/sites-enabled/ │
|
||||
│ 日志: /var/log/nginx/ │
|
||||
├──────────────────────────────────────────────────────┤
|
||||
│ http://www.ityb.me/ │
|
||||
│ → 302 重定向到 /careerbot/ │
|
||||
│ │
|
||||
│ http://www.ityb.me/careerbot/ │
|
||||
│ → proxy_pass http://127.0.0.1:8000/careerbot/ │
|
||||
│ → CareerBot (uvicorn, FastAPI prefix=/careerbot) │
|
||||
├──────────────────────────────────────────────────────┤
|
||||
│ http://www.ityb.me:3000 │
|
||||
│ → Gitea (直接监听,未经 Nginx 代理) │
|
||||
└──────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 端口使用
|
||||
@ -226,12 +231,12 @@ WantedBy=multi-user.target
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name 39.106.14.107;
|
||||
server_name www.ityb.me ityb.me 39.106.14.107;
|
||||
|
||||
client_max_body_size 10M;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
location /careerbot/ {
|
||||
proxy_pass http://127.0.0.1:8000/careerbot/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
@ -242,16 +247,20 @@ server {
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
|
||||
location /uploads/ {
|
||||
alias /home/deploy/apps/CareerBot/uploads/;
|
||||
# 根路径重定向到 CareerBot
|
||||
location = / {
|
||||
return 302 /careerbot/;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
关键配置说明:
|
||||
- **子路径部署**:CareerBot 部署在 `/careerbot/` 子路径下,后续其他项目可使用其他路径
|
||||
- `proxy_pass` 尾部带 `/careerbot/`:将完整路径透传给 FastAPI(FastAPI 通过 `prefix="/careerbot"` 匹配路由)
|
||||
- `proxy_buffering off` + `proxy_cache off`:**必须关闭**,否则 SSE 流式对话无法实时返回
|
||||
- `proxy_read_timeout 300s`:LLM 长回复可能需要较长时间
|
||||
- `client_max_body_size 10M`:允许上传最大 10MB 文件
|
||||
- 静态文件和上传文件通过 FastAPI StaticFiles 挂载在 `/careerbot/static/` 和 `/careerbot/uploads/`,无需单独 Nginx location
|
||||
|
||||
### 6.3 防火墙规则
|
||||
|
||||
@ -330,7 +339,7 @@ uvicorn app.main:app --host 127.0.0.1 --port 8000
|
||||
|
||||
### 8.2 AI 对话不工作
|
||||
|
||||
- 检查管理后台 LLM Config 是否已配置(API URL、API Key、Model Name)
|
||||
- 检查管理后台(`http://www.ityb.me/careerbot/admin/llm-config`)LLM Config 是否已配置(API URL、API Key、Model Name)
|
||||
- 点击 "Test Connection" 测试连通性
|
||||
- 确认 ECS 能访问外网:`curl https://api.deepseek.com`
|
||||
|
||||
@ -364,24 +373,25 @@ ps aux --sort=-rss | head -10
|
||||
|
||||
后续在同一台 ECS 上部署新项目的标准流程:
|
||||
|
||||
1. **Gitea 上创建仓库**:`http://39.106.14.107:3000` → New Repository
|
||||
1. **Gitea 上创建仓库**:`http://www.ityb.me:3000` → New Repository
|
||||
|
||||
2. **本地推送代码**
|
||||
3. **ECS 上克隆并配置**:
|
||||
```bash
|
||||
cd ~/apps
|
||||
git clone http://39.106.14.107:3000/ln0422/新项目.git
|
||||
git clone http://www.ityb.me:3000/ln0422/新项目.git
|
||||
# 安装依赖、初始化等
|
||||
```
|
||||
|
||||
4. **创建 systemd 服务**(参考 careerbot.service,注意更换端口号)
|
||||
|
||||
5. **添加 Nginx 站点配置**:
|
||||
5. **添加 Nginx 站点配置**(在同一个 `careerbot.conf` 文件或新建独立 conf 文件中,添加新的 `location /新路径/` 块):
|
||||
```bash
|
||||
sudo vim /etc/nginx/sites-available/新项目.conf
|
||||
sudo ln -s /etc/nginx/sites-available/新项目.conf /etc/nginx/sites-enabled/
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
```
|
||||
> 建议参考 CareerBot 的子路径部署模式:`location /新路径/ { proxy_pass http://127.0.0.1:新端口/新路径/; }`
|
||||
|
||||
6. **如需新端口**:防火墙 + 阿里云安全组同步放行
|
||||
|
||||
@ -393,4 +403,4 @@ ps aux --sort=-rss | head -10
|
||||
2. **Gitea 端口**:3000 端口对外开放,建议设置强密码,或后续通过 Nginx 代理并限制访问
|
||||
3. **数据库文件**:`careerbot.db` 不应对外暴露,uvicorn 仅监听 127.0.0.1 已确保安全
|
||||
4. **定期更新**:定期执行 `sudo dnf update -y` 更新系统安全补丁
|
||||
5. **HTTPS**:后续绑定域名后建议配置 Let's Encrypt SSL 证书
|
||||
5. **HTTPS**:域名 `ityb.me` 已绑定,建议配置 Let's Encrypt SSL 证书(`certbot --nginx -d www.ityb.me -d ityb.me`)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user