Compare commits
No commits in common. "main" and "v1.0" have entirely different histories.
20
DESIGN.md
20
DESIGN.md
@ -9,21 +9,11 @@ CareerBot 是一个个人职业展示网站,集成了 AI 智能对话助手。
|
|||||||
|
|
||||||
### 线上地址
|
### 线上地址
|
||||||
|
|
||||||
| 用途 | 地址 | 分支 | 特性 |
|
| 用途 | 地址 |
|
||||||
|------|------|------|------|
|
|------|------|
|
||||||
| 展示版主页(无聊天) | `https://www.ityb.me/` | branch1 | 隐藏对话按钮,纯展示 |
|
| 主页 | `http://www.ityb.me/careerbot/` |
|
||||||
| 完整版主页(含聊天) | `https://career.ityb.me/careerbot/` | main (trunk) | 含 AI 对话、JD 匹配、简历生成 |
|
| 管理后台 | `http://www.ityb.me/careerbot/admin/login` |
|
||||||
| 管理后台 | `https://career.ityb.me/careerbot/admin/login` | main (trunk) | 管理员入口 |
|
| Gitea 代码仓库 | `http://www.ityb.me:3000` |
|
||||||
| Gitea 代码仓库 | `https://git.ityb.me` | - | 自托管 Git |
|
|
||||||
|
|
||||||
### 分支策略
|
|
||||||
|
|
||||||
| 分支 | 部署域名 | BASE_PATH | 用途 |
|
|
||||||
|------|---------|-----------|------|
|
|
||||||
| `main`(trunk) | `career.ityb.me` | `/careerbot` | 主线开发,保留全部功能 |
|
|
||||||
| `branch1` | `www.ityb.me` / `ityb.me` | `""`(根路径) | 展示变体,隐藏 AI 对话按钮,共享 trunk 的数据库和上传目录 |
|
|
||||||
|
|
||||||
数据层面两分支共用同一 SQLite 数据库和上传目录,后端资料同步,仅前端展示差异。
|
|
||||||
|
|
||||||
### 技术栈
|
### 技术栈
|
||||||
|
|
||||||
|
|||||||
220
OPS_MANUAL.md
220
OPS_MANUAL.md
@ -37,10 +37,9 @@ ssh root@39.106.14.107 # root 直连
|
|||||||
|
|
||||||
| 系统 | 地址 | 账号 | 密码 |
|
| 系统 | 地址 | 账号 | 密码 |
|
||||||
|------|------|------|------|
|
|------|------|------|------|
|
||||||
| CareerBot 展示版(branch1) | `https://www.ityb.me/` | (访问令牌或匿名) | - |
|
| CareerBot 主页 | `http://www.ityb.me/careerbot/` | (访问令牌或匿名) | - |
|
||||||
| CareerBot 完整版(trunk) | `https://career.ityb.me/careerbot/` | (访问令牌或匿名) | - |
|
| CareerBot 管理后台 | `http://www.ityb.me/careerbot/admin/login` | `ln0422@gmail.com` | `qshs123456` |
|
||||||
| CareerBot 管理后台 | `https://career.ityb.me/careerbot/admin/login` | `ln0422@gmail.com` | `qshs123456` |
|
| Gitea 代码管理 | `http://www.ityb.me:3000` | `ln0422` | `Qshs123456_` |
|
||||||
| Gitea 代码管理 | `https://git.ityb.me` | `ln0422` | `Qshs123456_` |
|
|
||||||
|
|
||||||
### 2.3 ECS 用户密码
|
### 2.3 ECS 用户密码
|
||||||
|
|
||||||
@ -55,39 +54,24 @@ ssh root@39.106.14.107 # root 直连
|
|||||||
## 3. 服务架构
|
## 3. 服务架构
|
||||||
|
|
||||||
```
|
```
|
||||||
外部访问
|
外部访问 (www.ityb.me)
|
||||||
│
|
│
|
||||||
▼
|
▼
|
||||||
┌────────────────────────────────────────────────────────────────┐
|
┌──────────────────────────────────────────────────────┐
|
||||||
│ Nginx (:80 / :443) │
|
│ Nginx (:80) │
|
||||||
│ 配置: /etc/nginx/sites-enabled/ │
|
│ 配置: /etc/nginx/sites-enabled/ │
|
||||||
│ 日志: /var/log/nginx/ │
|
│ 日志: /var/log/nginx/ │
|
||||||
├────────────────────────────────────────────────────────────────┤
|
├──────────────────────────────────────────────────────┤
|
||||||
│ https://www.ityb.me/ (主域,展示版 branch1) │
|
│ http://www.ityb.me/ │
|
||||||
│ https://ityb.me/ ┤ │
|
│ → 302 重定向到 /careerbot/ │
|
||||||
│ → proxy_pass http://127.0.0.1:8001/ │
|
│ │
|
||||||
│ → CareerBot branch1 (uvicorn, BASE_PATH="", FAB 隐藏) │
|
│ http://www.ityb.me/careerbot/ │
|
||||||
│ │
|
│ → proxy_pass http://127.0.0.1:8000/careerbot/ │
|
||||||
│ https://www.ityb.me/careerbot/* → 404(已主动屏蔽) │
|
│ → CareerBot (uvicorn, FastAPI prefix=/careerbot) │
|
||||||
│ 仅 /careerbot/uploads/* 由 branch1 后端兜底(供 trunk 上传 │
|
├──────────────────────────────────────────────────────┤
|
||||||
│ 的头像 URL 在 branch1 页面正常显示) │
|
│ http://www.ityb.me:3000 │
|
||||||
├────────────────────────────────────────────────────────────────┤
|
│ → Gitea (直接监听,未经 Nginx 代理) │
|
||||||
│ https://career.ityb.me/careerbot/ (完整版 trunk) │
|
└──────────────────────────────────────────────────────┘
|
||||||
│ → proxy_pass http://127.0.0.1:8000/careerbot/ │
|
|
||||||
│ → CareerBot main (uvicorn, BASE_PATH="/careerbot", 完整功能) │
|
|
||||||
├────────────────────────────────────────────────────────────────┤
|
|
||||||
│ https://git.ityb.me │
|
|
||||||
│ → proxy_pass http://127.0.0.1:3000 │
|
|
||||||
│ → Gitea │
|
|
||||||
│ │
|
|
||||||
│ http://39.106.14.107/careerbot/ (IP 直连兼容 trunk) │
|
|
||||||
│ http://39.106.14.107:3000 (IP 直连兼容 Gitea) │
|
|
||||||
└────────────────────────────────────────────────────────────────┘
|
|
||||||
|
|
||||||
两个 CareerBot 实例共享同一 DB + uploads:
|
|
||||||
/home/deploy/apps/CareerBot/careerbot.db ← 权威数据源
|
|
||||||
/home/deploy/apps/CareerBot/uploads/ ← 权威上传目录
|
|
||||||
branch1 通过 systemd 环境变量 DATABASE_URL / UPLOAD_DIR 指向这里
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 端口使用
|
### 端口使用
|
||||||
@ -95,47 +79,38 @@ ssh root@39.106.14.107 # root 直连
|
|||||||
| 端口 | 服务 | 监听地址 | 防火墙 | 安全组 |
|
| 端口 | 服务 | 监听地址 | 防火墙 | 安全组 |
|
||||||
|------|------|---------|--------|--------|
|
|------|------|---------|--------|--------|
|
||||||
| 22 | SSH | 0.0.0.0 | 已放行 | 已放行 |
|
| 22 | SSH | 0.0.0.0 | 已放行 | 已放行 |
|
||||||
| 80 | Nginx (HTTP → HTTPS) | 0.0.0.0 | 已放行 | 已放行 |
|
| 80 | Nginx → CareerBot | 0.0.0.0 | 已放行 | 已放行 |
|
||||||
| 443 | Nginx (HTTPS) | 0.0.0.0 | 已放行 | 已放行 |
|
| 443 | HTTPS (预留) | - | 已放行 | 已放行 |
|
||||||
| 3000 | Gitea | 0.0.0.0 | 已放行 | 已放行 |
|
| 3000 | Gitea | 0.0.0.0 | 已放行 | 已放行 |
|
||||||
| 8000 | CareerBot trunk (uvicorn) | 127.0.0.1 | 内部 | 无需 |
|
| 8000 | CareerBot (uvicorn) | 127.0.0.1 | 内部 | 无需 |
|
||||||
| 8001 | CareerBot branch1 (uvicorn) | 127.0.0.1 | 内部 | 无需 |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 4. 文件目录结构
|
## 4. 文件目录结构
|
||||||
|
|
||||||
```
|
```
|
||||||
/home/deploy/apps/CareerBot/ ← Trunk 项目根目录(main 分支,:8000)
|
/home/deploy/apps/CareerBot/ ← 项目根目录
|
||||||
├── venv/ ← Python 虚拟环境
|
├── venv/ ← Python 虚拟环境
|
||||||
├── app/ ← 应用代码
|
├── app/ ← 应用代码
|
||||||
├── templates/ ← 页面模板
|
├── templates/ ← 页面模板
|
||||||
├── careerbot.db ← SQLite 数据库(主数据源,branch1 也读写这里)
|
├── careerbot.db ← SQLite 数据库(重要数据!)
|
||||||
├── uploads/ ← 用户上传文件(主目录,branch1 也访问这里)
|
├── uploads/ ← 用户上传文件
|
||||||
├── requirements.txt
|
├── requirements.txt
|
||||||
├── init_data.py
|
├── init_data.py
|
||||||
|
├── start.bat / stop.bat ← Windows 本地启动脚本(线上不用)
|
||||||
├── DESIGN.md ← 设计文档
|
├── DESIGN.md ← 设计文档
|
||||||
└── OPS_MANUAL.md ← 本文档
|
└── OPS_MANUAL.md ← 本文档
|
||||||
|
|
||||||
/home/deploy/apps/CareerBot-branch1/ ← Branch1 项目根目录(branch1 分支,:8001)
|
|
||||||
├── venv/ ← 独立虚拟环境
|
|
||||||
├── app/ ← BASE_PATH="" 的代码
|
|
||||||
├── templates/ ← 隐藏 FAB 的 index.html
|
|
||||||
└── (无独立 careerbot.db,通过环境变量指向 trunk 的)
|
|
||||||
|
|
||||||
/etc/systemd/system/
|
/etc/systemd/system/
|
||||||
├── careerbot.service ← CareerBot trunk systemd 服务
|
├── careerbot.service ← CareerBot systemd 服务
|
||||||
├── careerbot-branch1.service ← CareerBot branch1 systemd 服务
|
|
||||||
└── gitea.service ← Gitea systemd 服务
|
└── gitea.service ← Gitea systemd 服务
|
||||||
|
|
||||||
/etc/nginx/
|
/etc/nginx/
|
||||||
├── nginx.conf ← Nginx 主配置
|
├── nginx.conf ← Nginx 主配置
|
||||||
├── sites-available/
|
├── sites-available/
|
||||||
│ ├── careerbot.conf ← CareerBot 站点配置
|
│ └── careerbot.conf ← CareerBot 站点配置
|
||||||
│ └── gitea.conf ← Gitea 站点配置
|
|
||||||
└── sites-enabled/
|
└── sites-enabled/
|
||||||
├── careerbot.conf → ../sites-available/careerbot.conf
|
└── careerbot.conf → ../sites-available/careerbot.conf
|
||||||
└── gitea.conf → ../sites-available/gitea.conf
|
|
||||||
|
|
||||||
/usr/local/bin/gitea ← Gitea 二进制文件
|
/usr/local/bin/gitea ← Gitea 二进制文件
|
||||||
/etc/gitea/app.ini ← Gitea 配置文件
|
/etc/gitea/app.ini ← Gitea 配置文件
|
||||||
@ -226,7 +201,7 @@ ssh ecs "ss -tlnp"
|
|||||||
|
|
||||||
### 6.1 CareerBot systemd 服务
|
### 6.1 CareerBot systemd 服务
|
||||||
|
|
||||||
**Trunk(main 分支)**:`/etc/systemd/system/careerbot.service`
|
文件:`/etc/systemd/system/careerbot.service`
|
||||||
```ini
|
```ini
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=CareerBot Web Application
|
Description=CareerBot Web Application
|
||||||
@ -245,134 +220,47 @@ Environment=PATH=/home/deploy/apps/CareerBot/venv/bin:/usr/bin
|
|||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
```
|
```
|
||||||
|
|
||||||
**Branch1(branch1 分支,共享 trunk 数据)**:`/etc/systemd/system/careerbot-branch1.service`
|
关键参数:
|
||||||
```ini
|
- `--host 127.0.0.1`:只监听本地,由 Nginx 代理外部访问
|
||||||
[Unit]
|
|
||||||
Description=CareerBot branch1 (display-only, shared DB with trunk)
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
User=deploy
|
|
||||||
WorkingDirectory=/home/deploy/apps/CareerBot-branch1
|
|
||||||
ExecStart=/home/deploy/apps/CareerBot-branch1/venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8001
|
|
||||||
Restart=always
|
|
||||||
Environment=PATH=/home/deploy/apps/CareerBot-branch1/venv/bin:/usr/bin
|
|
||||||
Environment=DATABASE_URL=sqlite:////home/deploy/apps/CareerBot/careerbot.db
|
|
||||||
Environment=UPLOAD_DIR=/home/deploy/apps/CareerBot/uploads
|
|
||||||
Environment=BASE_PATH=
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
```
|
|
||||||
|
|
||||||
关键差异:
|
|
||||||
- **端口**:trunk 用 8000,branch1 用 8001
|
|
||||||
- **数据共享**:branch1 通过 `DATABASE_URL` 和 `UPLOAD_DIR` 环境变量指向 trunk 的数据库和上传目录
|
|
||||||
- **BASE_PATH**:branch1 设置为空串,应用部署在根路径
|
|
||||||
- **FAB 显示**:branch1 的 `templates/index.html` 已修改,对话按钮 `style="display:none;"`
|
|
||||||
- `Restart=always`:崩溃后自动重启
|
- `Restart=always`:崩溃后自动重启
|
||||||
|
- `RestartSec=5`:重启间隔 5 秒
|
||||||
|
|
||||||
### 6.2 Nginx 站点配置
|
### 6.2 Nginx 站点配置
|
||||||
|
|
||||||
文件:`/etc/nginx/sites-available/careerbot.conf`(含三段 server block + certbot 自动追加的 HTTPS 块)
|
文件:`/etc/nginx/sites-available/careerbot.conf`
|
||||||
|
|
||||||
```nginx
|
```nginx
|
||||||
# ===== TRUNK: career.ityb.me (完整版,/careerbot/ 子路径) =====
|
|
||||||
server {
|
|
||||||
server_name career.ityb.me;
|
|
||||||
client_max_body_size 10M;
|
|
||||||
|
|
||||||
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;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_buffering off; proxy_cache off; proxy_read_timeout 300s;
|
|
||||||
}
|
|
||||||
location = / { return 302 /careerbot/; }
|
|
||||||
|
|
||||||
listen 443 ssl; # by certbot
|
|
||||||
ssl_certificate /etc/letsencrypt/live/career.ityb.me/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/career.ityb.me/privkey.pem;
|
|
||||||
}
|
|
||||||
|
|
||||||
# ===== BRANCH1: www.ityb.me + ityb.me (展示版,根路径) =====
|
|
||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
server_name www.ityb.me ityb.me;
|
server_name www.ityb.me ityb.me 39.106.14.107;
|
||||||
return 301 https://$host$request_uri;
|
|
||||||
}
|
|
||||||
server {
|
|
||||||
listen 443 ssl;
|
|
||||||
server_name www.ityb.me ityb.me;
|
|
||||||
client_max_body_size 10M;
|
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/www.ityb.me/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/www.ityb.me/privkey.pem;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:8001/; # branch1
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_buffering off; proxy_cache off; proxy_read_timeout 300s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ===== IP 直连(向后兼容,HTTP only) =====
|
|
||||||
server {
|
|
||||||
listen 80 default_server;
|
|
||||||
server_name 39.106.14.107;
|
|
||||||
client_max_body_size 10M;
|
client_max_body_size 10M;
|
||||||
|
|
||||||
location /careerbot/ {
|
location /careerbot/ {
|
||||||
proxy_pass http://127.0.0.1:8000/careerbot/;
|
proxy_pass http://127.0.0.1:8000/careerbot/;
|
||||||
# ... 同 trunk ...
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
# SSE 流式响应支持(关键!关闭缓冲)
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_cache off;
|
||||||
|
proxy_read_timeout 300s;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 根路径重定向到 CareerBot
|
||||||
|
location = / {
|
||||||
|
return 302 /careerbot/;
|
||||||
}
|
}
|
||||||
location = / { return 302 /careerbot/; }
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
关键配置说明:
|
关键配置说明:
|
||||||
- **双域双实例**:career 子域名走 trunk(:8000),主域名走 branch1(:8001)
|
- **子路径部署**:CareerBot 部署在 `/careerbot/` 子路径下,后续其他项目可使用其他路径
|
||||||
- **SSL 证书**:`career.ityb.me` 和 `www.ityb.me+ityb.me` 分别独立证书(均由 certbot 自动申请续期)
|
- `proxy_pass` 尾部带 `/careerbot/`:将完整路径透传给 FastAPI(FastAPI 通过 `prefix="/careerbot"` 匹配路由)
|
||||||
- **主域路径隔离**:`www.ityb.me/careerbot/*` 返回 404(nginx 层不做任何特殊处理,请求透传到 branch1 后端,branch1 没有 /careerbot 前缀路由因此 404);仅 `/careerbot/uploads/*` 能命中 branch1 的二级挂载,用于显示 trunk 管理员上传的头像
|
|
||||||
- `proxy_buffering off` + `proxy_cache off`:**必须关闭**,否则 SSE 流式对话无法实时返回
|
- `proxy_buffering off` + `proxy_cache off`:**必须关闭**,否则 SSE 流式对话无法实时返回
|
||||||
- `proxy_read_timeout 300s`:LLM 长回复可能需要较长时间
|
- `proxy_read_timeout 300s`:LLM 长回复可能需要较长时间
|
||||||
|
- `client_max_body_size 10M`:允许上传最大 10MB 文件
|
||||||
### 6.3 Gitea 站点配置
|
- 静态文件和上传文件通过 FastAPI StaticFiles 挂载在 `/careerbot/static/` 和 `/careerbot/uploads/`,无需单独 Nginx location
|
||||||
|
|
||||||
文件:`/etc/nginx/sites-available/gitea.conf`(HTTPS 部分由 certbot 自动生成)
|
|
||||||
```nginx
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name git.ityb.me;
|
|
||||||
client_max_body_size 512M;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:3000;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_read_timeout 300s;
|
|
||||||
}
|
|
||||||
|
|
||||||
# certbot 自动追加 443 监听块 + 80→443 重定向
|
|
||||||
listen 443 ssl;
|
|
||||||
ssl_certificate /etc/letsencrypt/live/git.ityb.me/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/git.ityb.me/privkey.pem;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
关键说明:
|
|
||||||
- `client_max_body_size 512M`:支持大仓库 push/pull
|
|
||||||
- Gitea 仍在本机 3000 端口监听,Nginx 反向代理到 443(HTTPS)
|
|
||||||
- 端口 3000 保持对外开放作为备用访问方式
|
|
||||||
- 对应 Gitea 配置 `/etc/gitea/app.ini`:`ROOT_URL=https://git.ityb.me/`、`DOMAIN=git.ityb.me`、`SSH_DOMAIN=git.ityb.me`
|
|
||||||
|
|
||||||
### 6.3 防火墙规则
|
### 6.3 防火墙规则
|
||||||
|
|
||||||
@ -485,13 +373,13 @@ ps aux --sort=-rss | head -10
|
|||||||
|
|
||||||
后续在同一台 ECS 上部署新项目的标准流程:
|
后续在同一台 ECS 上部署新项目的标准流程:
|
||||||
|
|
||||||
1. **Gitea 上创建仓库**:`https://git.ityb.me` → New Repository
|
1. **Gitea 上创建仓库**:`http://www.ityb.me:3000` → New Repository
|
||||||
|
|
||||||
2. **本地推送代码**
|
2. **本地推送代码**
|
||||||
3. **ECS 上克隆并配置**:
|
3. **ECS 上克隆并配置**:
|
||||||
```bash
|
```bash
|
||||||
cd ~/apps
|
cd ~/apps
|
||||||
git clone https://git.ityb.me/ln0422/新项目.git
|
git clone http://www.ityb.me:3000/ln0422/新项目.git
|
||||||
# 安装依赖、初始化等
|
# 安装依赖、初始化等
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user