first commit
This commit is contained in:
@@ -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 # 后端服务配置
|
||||
```
|
||||
Reference in New Issue
Block a user