first commit

This commit is contained in:
Dev
2026-11-02 15:45:49 +08:00
commit 328b6917a3
24 changed files with 1824 additions and 0 deletions
+480
View File
@@ -0,0 +1,480 @@
# Goal Planner Linux 部署指南
## 环境要求
### 服务器
- Linux 服务器(Ubuntu 20.04+ / CentOS 7+)
- Python 3.11+(由 uv 管理,不依赖系统 Python)
- MySQL 5.7+ / 8.0(需提前安装)
- Nginx(需提前安装)
- [uv](https://docs.astral.sh/uv/)(Python 包管理工具)
> **关于 Python 版本**:项目要求 Python ≥ 3.10。CentOS 7 系统自带 Python 2.7.5,无需升级或卸载,uv 会自动下载和管理独立的 Python 版本,不会与系统 Python 冲突。系统工具(如 yum)依赖的 Python 2.7.5 完全不受影响。**推荐使用 Python 3.11**,wheel 生态最成熟,所有依赖都有预编译 wheel,安装秒完成;Python 3.12/3.14 部分包(如 greenlet、pydantic-core)在 CentOS 7 上缺少兼容的预编译 wheel,需要从源码编译,而 CentOS 7 的 GCC 4.8.5 不支持 C++11,会导致编译失败。
### 本地(仅构建前端时需要)
- Node.js 18+
---
## 1. 安装 uv
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```
安装完成后,需要让 uv 命令生效(二选一):
```bash
# 方式一:执行以下命令(推荐,立即生效)
source $HOME/.local/bin/env
# 方式二:重新连接 SSH
```
验证安装:
```bash
uv --version
```
---
## 2. 配置 MySQL
```bash
# 登录 MySQL
sudo mysql -u root -p
# 创建数据库和用户
CREATE DATABASE goal_planner CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'goal_planner'@'localhost' IDENTIFIED BY '你的数据库密码';
GRANT ALL PRIVILEGES ON goal_planner.* TO 'goal_planner'@'localhost';
FLUSH PRIVILEGES;
EXIT;
```
> 首次启动后端时,SQLAlchemy 会自动创建表结构,无需手动导入。
---
## 3. 上传项目
将项目上传到服务器,部署目录为 `/home/wwwroot/goal-planner`:
```bash
sudo mkdir -p /home/wwwroot/goal-planner
# 方式一:git clone
cd /home/wwwroot/goal-planner
git clone <你的仓库地址> .
# 方式二:scp 上传
# scp -r ./goal-planner/* user@server:/home/wwwroot/goal-planner/
```
---
## 4. 后端部署
### 4.1 配置环境变量
```bash
cd /home/wwwroot/goal-planner/backend
cp .env.example .env
```
编辑 `.env` 文件:
```bash
vi .env
```
填入实际配置:
```env
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_USER=goal_planner
MYSQL_PASSWORD=你的数据库密码
MYSQL_DATABASE=goal_planner
SECRET_KEY=替换为一个随机长字符串
ACCESS_TOKEN_EXPIRE_MINUTES=1440
LLM_PROVIDER=dashscope
OPENAI_API_KEY=你的API密钥
OPENAI_API_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
OPENAI_MODEL=qwen3-plus
ENABLE_SEARCH=true
```
> **重要**:`SECRET_KEY` 必须替换为随机字符串,可用 `openssl rand -hex 32` 生成。
### 4.2 使用 uv 创建虚拟环境并安装依赖
```bash
cd /home/wwwroot/goal-planner
# 创建虚拟环境,uv 会自动下载 Python 3.11(不依赖系统 Python)
uv venv .venv --python 3.11
# 激活虚拟环境
source .venv/bin/activate
# 安装依赖(使用清华镜像加速,强制只安装预编译 wheel)
uv pip install -r backend/requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple --only-binary :all:
```
> **说明**:`uv venv --python 3.11` 会将 Python 3.11 下载到 `~/.local/share/uv/python/` 目录,仅 uv 使用,不会覆盖或修改系统自带的 Python 2.7.5。虚拟环境放在项目根目录 `/home/wwwroot/goal-planner/.venv`,与 backend 同级。`--only-binary :all:` 强制只安装预编译 wheel,避免在 CentOS 7 的旧 GCC 上从源码编译失败。
### 4.3 验证后端启动
```bash
cd /home/wwwroot/goal-planner/backend
source /home/wwwroot/goal-planner/.venv/bin/activate
uvicorn main:app --host 127.0.0.1 --port 8000
```
看到 `Uvicorn running on http://127.0.0.1:8000` 即启动成功,`Ctrl+C` 停止。
### 4.4 后台运行
验证无误后,使用以下方式后台运行(推荐方式二):
**方式一:nohup(简单快速)**
```bash
cd /home/wwwroot/goal-planner/backend
source /home/wwwroot/goal-planner/.venv/bin/activate
nohup uvicorn main:app --host 127.0.0.1 --port 8000 > /home/wwwroot/goal-planner/backend/app.log 2>&1 &
```
常用操作:
```bash
# 查看日志
tail -f /home/wwwroot/goal-planner/backend/app.log
# 查看进程
ps aux | grep uvicorn
# 停止服务
kill $(ps aux | grep 'uvicorn main:app' | grep -v grep | awk '{print $2}')
```
**方式二:systemd 服务(推荐,开机自启 + 自动重启)**
见第 7 章。
---
## 5. 前端构建与部署
### 5.1 修改 API 接口地址
前端 API 地址硬编码在 `frontend/services/apiService.ts` 中:
```typescript
const API_BASE_URL = 'http://localhost:8000';
```
**部署前必须修改为实际的后端地址**。根据你的部署方式选择:
#### 方式一:使用 Nginx 反向代理(推荐)
将 API 地址改为相对路径,由 Nginx 统一代理:
```typescript
const API_BASE_URL = '/api-proxy';
```
这样前端请求 `/api-proxy/api/generate/` 会被 Nginx 转发到后端 `http://127.0.0.1:8000/api/generate/`,无需暴露后端端口。
#### 方式二:直接指向后端地址
如果你的后端运行在独立域名或端口上:
```typescript
const API_BASE_URL = 'http://你的服务器IP:8000';
```
> **注意**:此方式需要后端开放 8000 端口,并在 `main.py` 的 CORS 配置中添加前端域名。
### 5.2 修改后端 CORS 配置(方式一不需要)
如果使用方式二,需要修改 `backend/main.py` 中的 CORS 允许来源:
```python
origins = [
"http://你的域名",
"http://你的服务器IP",
]
```
### 5.3 本地构建前端
在本地开发机器上执行构建(不需要在服务器上安装 Node.js):
```bash
cd frontend
# 安装依赖
npm install
# 构建
npm run build
```
构建产物在 `frontend/dist/` 目录中。
### 5.4 上传静态文件到服务器
将本地构建产物上传到服务器:
```bash
# 在本地执行
scp -r frontend/dist/* user@你的服务器IP:/var/www/goal-planner/
```
或在服务器上从项目目录复制(如果已上传整个项目):
```bash
sudo mkdir -p /var/www/goal-planner
sudo cp -r /home/wwwroot/goal-planner/frontend/dist/* /var/www/goal-planner/
```
---
## 6. 配置 Nginx
创建 Nginx 配置文件:
```bash
sudo vi /etc/nginx/conf.d/goal-planner.conf
```
### 方式一:Nginx 反向代理(推荐)
前后端统一通过 Nginx 访问,后端不对外暴露端口:
```nginx
server {
listen 80;
server_name 你的域名或IP;
# 前端静态文件
root /var/www/goal-planner;
index index.html;
# 前端路由 - SPA 应用所有路径都返回 index.html
location / {
try_files $uri $uri/ /index.html;
}
# 后端 API 反向代理
location /api-proxy/ {
rewrite ^/api-proxy/(.*) /$1 break;
proxy_pass http://127.0.0.1:8000;
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;
proxy_http_version 1.1;
proxy_set_header Connection '';
}
# 静态资源缓存
location /assets/ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# 禁止访问隐藏文件
location ~ /\. {
deny all;
}
}
```
> **SSE 关键配置说明**:
> - `proxy_buffering off` — 禁用缓冲,确保 SSE 事件实时推送到客户端
> - `proxy_cache off` — 禁用缓存
> - `proxy_read_timeout 300s` — AI 生成可能耗时较长,增大超时时间
> - `proxy_http_version 1.1` + `Connection ''` — 保持长连接
### 方式二:前后端分离部署
后端直接监听 8000 端口对外服务:
```nginx
server {
listen 80;
server_name 你的域名或IP;
root /var/www/goal-planner;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /assets/ {
expires 30d;
add_header Cache-Control "public, immutable";
}
}
```
此方式下 `apiService.ts` 中的 `API_BASE_URL` 应设为 `http://你的域名或IP:8000`。
### 验证并重启 Nginx
```bash
sudo nginx -t
sudo systemctl restart nginx
```
---
## 7. 使用 systemd 管理后端进程
创建 systemd 服务文件,实现开机自启和进程管理:
```bash
sudo vi /etc/systemd/system/goal-planner.service
```
```ini
[Unit]
Description=Goal Planner Backend API
After=network.target mysql.service
[Service]
Type=simple
User=root
WorkingDirectory=/home/wwwroot/goal-planner/backend
ExecStart=/home/wwwroot/goal-planner/.venv/bin/uvicorn main:app --host 127.0.0.1 --port 8000
Restart=always
RestartSec=5
Environment=PYTHONUNBUFFERED=1
[Install]
WantedBy=multi-user.target
```
> 如果使用方式二(前后端分离),将 `--host 127.0.0.1` 改为 `--host 0.0.0.0` 以允许外部访问。
启动并设置开机自启:
```bash
sudo systemctl daemon-reload
sudo systemctl start goal-planner
sudo systemctl enable goal-planner
```
常用管理命令:
```bash
sudo systemctl status goal-planner # 查看状态
sudo systemctl restart goal-planner # 重启
sudo systemctl stop goal-planner # 停止
sudo journalctl -u goal-planner -f # 查看实时日志
```
---
## 8. 验证部署
```bash
# 检查后端健康状态
curl http://127.0.0.1:8000/api/health
# 预期返回: {"status":"ok"}
# 检查 Nginx 代理(方式一)
curl http://你的域名或IP/api-proxy/api/health
# 预期返回: {"status":"ok"}
# 浏览器访问
# http://你的域名或IP
```
---
## 9. HTTPS 配置(可选但推荐)
使用 Let's Encrypt 免费证书:
```bash
sudo apt install certbot python3-certbot-nginx # Ubuntu
sudo yum install certbot python3-certbot-nginx # CentOS
sudo certbot --nginx -d 你的域名
```
Certbot 会自动修改 Nginx 配置并配置 SSL 证书自动续期。
---
## 10. 更新部署
当代码更新后,执行以下步骤:
### 后端更新
```bash
# 服务器上拉取最新代码
cd /home/wwwroot/goal-planner
git pull
# 更新后端依赖(如有变动)
source /home/wwwroot/goal-planner/.venv/bin/activate
uv pip install -r backend/requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple --only-binary :all:
# 重启后端
sudo systemctl restart goal-planner
```
### 前端更新
```bash
# 本地构建
cd frontend
npm install
npm run build
# 上传到服务器
scp -r dist/* user@你的服务器IP:/var/www/goal-planner/
```
---
## 文件结构总览
```
/home/wwwroot/goal-planner/
├── .venv/ # uv 创建的 Python 虚拟环境(项目根目录)
├── backend/
│ ├── .env # 环境变量配置(含数据库密码、API密钥)
│ ├── .env.example # 环境变量模板
│ ├── main.py # FastAPI 入口
│ ├── config.py # 配置读取
│ ├── database.py # 数据库连接
│ ├── requirements.txt # Python 依赖
│ ├── models/ # 数据模型
│ └── routes/ # API 路由
│ ├── auth.py
│ ├── generate.py
│ └── plans.py
└── frontend/
├── dist/ # 构建产物 → 部署到 /var/www/goal-planner/
├── services/
│ └── apiService.ts # API 地址配置(需修改 API_BASE_URL)
├── package.json
└── vite.config.ts
/var/www/goal-planner/ # Nginx 静态文件目录
/etc/nginx/conf.d/goal-planner.conf # Nginx 配置
/etc/systemd/system/goal-planner.service # 后端服务配置
```