619 lines
12 KiB
Markdown
619 lines
12 KiB
Markdown
# 后台前端与后端系统从零到一上线教程
|
||
|
||
本文档适用于当前项目:
|
||
|
||
- 后端:`backend/`,FastAPI
|
||
- 后台前端:`admin-web/`,Vue 3 + Vite
|
||
- 域名:`ghxiangqin.com`
|
||
- 对外接口地址:`https://ghxiangqin.com/api/v1`
|
||
|
||
目标效果:
|
||
|
||
- 访问 `https://ghxiangqin.com/` 打开后台管理系统
|
||
- 访问 `https://ghxiangqin.com/api/v1/...` 调用后端接口
|
||
- 外网只开放 `80` 和 `443`
|
||
- `backend` 只在服务器本机监听 `127.0.0.1:8000`
|
||
|
||
---
|
||
|
||
## 1. 上线方案总览
|
||
|
||
这套项目推荐按下面方式部署:
|
||
|
||
1. `admin-web` 不长期跑 `npm run dev`
|
||
2. `admin-web` 执行 `npm run build`,生成静态文件
|
||
3. 静态文件交给 Nginx 直接托管
|
||
4. `backend` 用 `uvicorn` 跑在本机端口 `127.0.0.1:8000`
|
||
5. 宝塔/Nginx 对外只暴露一个站点域名 `ghxiangqin.com`
|
||
6. Nginx 负责把 `/api/` 请求转发到 `backend`
|
||
|
||
最后的访问关系如下:
|
||
|
||
- `https://ghxiangqin.com/` -> 后台前端静态页面
|
||
- `https://ghxiangqin.com/api/v1/*` -> FastAPI 后端
|
||
- `https://ghxiangqin.com/health` -> 后端健康检查
|
||
|
||
---
|
||
|
||
## 2. 服务器准备
|
||
|
||
建议服务器环境:
|
||
|
||
1. Linux 服务器一台
|
||
2. 已安装宝塔面板
|
||
3. 已安装 Nginx
|
||
4. 已安装 MySQL 8
|
||
5. 已安装 Redis
|
||
6. 已安装 Python 3.10 或更高版本
|
||
7. 已安装 Node.js 18 或更高版本
|
||
|
||
还需要提前准备:
|
||
|
||
1. 域名 `ghxiangqin.com`
|
||
2. 域名 A 记录解析到服务器公网 IP
|
||
3. 服务器安全组/防火墙放行 `80`、`443`
|
||
|
||
---
|
||
|
||
## 3. 上传项目代码
|
||
|
||
把整个项目上传到服务器,比如:
|
||
|
||
```bash
|
||
/www/wwwroot/xqxcx
|
||
```
|
||
|
||
建议最终目录结构如下:
|
||
|
||
```text
|
||
/www/wwwroot/xqxcx/
|
||
├─ admin-web/
|
||
├─ backend/
|
||
├─ miniprogram/
|
||
└─ 其它文档
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 创建数据库
|
||
|
||
登录 MySQL,执行:
|
||
|
||
```sql
|
||
CREATE DATABASE dating_app DEFAULT CHARACTER SET utf8mb4;
|
||
```
|
||
|
||
如果数据库名不是 `dating_app`,后面 `.env` 里要同步改。
|
||
|
||
---
|
||
|
||
## 5. 配置后端环境变量
|
||
|
||
进入后端目录:
|
||
|
||
```bash
|
||
cd /www/wwwroot/xqxcx/backend
|
||
```
|
||
|
||
复制环境变量模板:
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
```
|
||
|
||
然后编辑 `.env`,至少改这些值:
|
||
|
||
```env
|
||
APP_NAME=dating-mini-program-api
|
||
APP_ENV=production
|
||
APP_DEBUG=false
|
||
API_V1_PREFIX=/api/v1
|
||
|
||
MYSQL_HOST=127.0.0.1
|
||
MYSQL_PORT=3306
|
||
MYSQL_USER=root
|
||
MYSQL_PASSWORD=你的数据库密码
|
||
MYSQL_DATABASE=dating_app
|
||
|
||
REDIS_HOST=127.0.0.1
|
||
REDIS_PORT=6379
|
||
REDIS_DB=0
|
||
REDIS_PASSWORD=
|
||
|
||
JWT_SECRET_KEY=换成一串复杂随机字符串
|
||
JWT_ALGORITHM=HS256
|
||
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=10080
|
||
|
||
WX_APPID=你的小程序APPID
|
||
WX_SECRET=你的小程序SECRET
|
||
|
||
COS_REGION=你的腾讯云COS地域
|
||
COS_SECRET_ID=你的COS_SECRET_ID
|
||
COS_SECRET_KEY=你的COS_SECRET_KEY
|
||
COS_BUCKET=你的COS桶名
|
||
COS_BASE_URL=你的COS访问地址
|
||
|
||
WX_TEMPLATE_AUDIT_RESULT=审核结果模板ID
|
||
WX_TEMPLATE_MATCH_SUCCESS=匹配成功模板ID
|
||
```
|
||
|
||
注意:
|
||
|
||
1. `APP_DEBUG` 上线必须改成 `false`
|
||
2. `JWT_SECRET_KEY` 不要继续用默认值
|
||
3. 如果 Redis 没设密码,`REDIS_PASSWORD` 可以留空
|
||
|
||
---
|
||
|
||
## 6. 安装后端依赖
|
||
|
||
仍在 `backend/` 目录执行:
|
||
|
||
```bash
|
||
python3 -m venv .venv
|
||
source .venv/bin/activate
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
如果服务器命令是 `python`,就把 `python3` 改成 `python`。
|
||
|
||
---
|
||
|
||
## 7. 执行数据库迁移
|
||
|
||
在 `backend/` 目录执行:
|
||
|
||
```bash
|
||
source .venv/bin/activate
|
||
alembic upgrade head
|
||
```
|
||
|
||
成功后,数据库里会生成项目需要的数据表。
|
||
|
||
---
|
||
|
||
## 8. 初始化后台管理员账号
|
||
|
||
在 `backend/` 目录执行:
|
||
|
||
```bash
|
||
source .venv/bin/activate
|
||
python scripts/init_admin.py
|
||
```
|
||
|
||
初始化后,后台默认管理员一般可用:
|
||
|
||
- 用户名:`admin`
|
||
- 密码:以脚本实际输出或项目默认说明为准
|
||
|
||
首次登录后建议立刻改密码。
|
||
|
||
---
|
||
|
||
## 9. 启动后端服务
|
||
|
||
### 9.1 临时启动测试
|
||
|
||
先手动启动确认能跑:
|
||
|
||
```bash
|
||
cd /www/wwwroot/xqxcx/backend
|
||
source .venv/bin/activate
|
||
uvicorn main:app --host 127.0.0.1 --port 8000
|
||
```
|
||
|
||
然后本机检查:
|
||
|
||
```bash
|
||
curl http://127.0.0.1:8000/health
|
||
```
|
||
|
||
正常应返回:
|
||
|
||
```json
|
||
{"status":"ok"}
|
||
```
|
||
|
||
### 9.2 正式常驻启动
|
||
|
||
生产环境建议用宝塔的 Python 项目管理器、Supervisor,或 systemd 来托管进程。
|
||
如果你用宝塔的 Supervisor,命令可填:
|
||
|
||
```bash
|
||
cd /www/wwwroot/xqxcx/backend && /www/wwwroot/xqxcx/backend/.venv/bin/uvicorn main:app --host 127.0.0.1 --port 8000
|
||
```
|
||
|
||
关键点:
|
||
|
||
1. 只监听 `127.0.0.1`
|
||
2. 不要直接暴露 `8000` 给公网
|
||
3. 对外统一走 Nginx 反向代理
|
||
|
||
---
|
||
|
||
## 10. 打包后台前端
|
||
|
||
进入前端目录:
|
||
|
||
```bash
|
||
cd /www/wwwroot/xqxcx/admin-web
|
||
```
|
||
|
||
安装依赖:
|
||
|
||
```bash
|
||
npm install
|
||
```
|
||
|
||
执行打包:
|
||
|
||
```bash
|
||
npm run build
|
||
```
|
||
|
||
打包完成后会生成:
|
||
|
||
```text
|
||
admin-web/dist/
|
||
```
|
||
|
||
说明:
|
||
|
||
1. `dist/` 里是纯静态文件
|
||
2. 不需要再运行 `npm run dev`
|
||
3. 不需要给前端单独开端口
|
||
|
||
---
|
||
|
||
## 11. 创建宝塔站点
|
||
|
||
在宝塔面板里创建站点:
|
||
|
||
1. 域名填:`ghxiangqin.com`
|
||
2. 如果需要,也加上:`www.ghxiangqin.com`
|
||
3. PHP 版本选“纯静态”或不启用 PHP
|
||
4. 网站目录建议设为:
|
||
|
||
```text
|
||
/www/wwwroot/ghxiangqin.com
|
||
```
|
||
|
||
创建完成后,把 `admin-web/dist/` 里的所有文件复制到这个目录:
|
||
|
||
```text
|
||
/www/wwwroot/ghxiangqin.com
|
||
```
|
||
|
||
注意是复制 `dist` 目录中的内容,不是把 `dist` 整个目录原样套进去。
|
||
|
||
最终应该像这样:
|
||
|
||
```text
|
||
/www/wwwroot/ghxiangqin.com/index.html
|
||
/www/wwwroot/ghxiangqin.com/assets/...
|
||
```
|
||
|
||
---
|
||
|
||
## 12. 配置 Nginx 反向代理
|
||
|
||
### 12.1 未配置 SSL 证书前的可用版
|
||
|
||
如果你还没申请 HTTPS 证书,先用下面配置:
|
||
|
||
```nginx
|
||
server {
|
||
listen 80;
|
||
server_name ghxiangqin.com www.ghxiangqin.com;
|
||
|
||
root /www/wwwroot/ghxiangqin.com;
|
||
index index.html index.htm;
|
||
|
||
client_max_body_size 20m;
|
||
|
||
location / {
|
||
try_files $uri $uri/ /index.html;
|
||
}
|
||
|
||
location /api/ {
|
||
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;
|
||
}
|
||
|
||
location /health {
|
||
proxy_pass http://127.0.0.1:8000/health;
|
||
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;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 12.2 配置 SSL 证书后的正式版
|
||
|
||
在宝塔站点中先申请 Let's Encrypt 证书,成功后再用 HTTPS 配置。
|
||
如果证书由宝塔自动配置,通常只需要保留宝塔生成的证书路径,再加上下面的 `location` 即可。
|
||
|
||
示例正式版:
|
||
|
||
```nginx
|
||
server {
|
||
listen 80;
|
||
server_name ghxiangqin.com www.ghxiangqin.com;
|
||
return 301 https://$host$request_uri;
|
||
}
|
||
|
||
server {
|
||
listen 443 ssl http2;
|
||
server_name ghxiangqin.com www.ghxiangqin.com;
|
||
|
||
ssl_certificate /www/server/panel/vhost/cert/ghxiangqin.com/fullchain.pem;
|
||
ssl_certificate_key /www/server/panel/vhost/cert/ghxiangqin.com/privkey.pem;
|
||
|
||
root /www/wwwroot/ghxiangqin.com;
|
||
index index.html index.htm;
|
||
|
||
client_max_body_size 20m;
|
||
|
||
location / {
|
||
try_files $uri $uri/ /index.html;
|
||
}
|
||
|
||
location /api/ {
|
||
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;
|
||
}
|
||
|
||
location /health {
|
||
proxy_pass http://127.0.0.1:8000/health;
|
||
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;
|
||
}
|
||
}
|
||
```
|
||
|
||
说明:
|
||
|
||
1. `/` 用于托管后台前端静态页面
|
||
2. `/api/` 反代到 FastAPI
|
||
3. `try_files ... /index.html` 是为了支持 Vue 路由刷新
|
||
4. `client_max_body_size 20m` 是为了后续上传图片时不被拦截
|
||
|
||
---
|
||
|
||
## 13. 申请 SSL 证书
|
||
|
||
微信小程序正式环境要求接口必须是 `HTTPS`,所以上线最终一定要配置证书。
|
||
|
||
宝塔操作步骤:
|
||
|
||
1. 打开站点 `ghxiangqin.com`
|
||
2. 进入 `SSL`
|
||
3. 选择 Let's Encrypt
|
||
4. 申请证书
|
||
5. 申请成功后启用证书
|
||
6. 按需开启“强制 HTTPS”
|
||
|
||
如果 Nginx 保存时报:
|
||
|
||
```text
|
||
no "ssl_certificate" is defined for the "listen ... ssl" directive
|
||
```
|
||
|
||
说明你先写了 `listen 443 ssl`,但证书还没配好。
|
||
这时先用“未配置 SSL 证书前的可用版”,不要先写 `443 ssl`。
|
||
|
||
---
|
||
|
||
## 14. 检查后台前端和后端联通
|
||
|
||
先确认以下地址是否正常:
|
||
|
||
1. 后端健康检查
|
||
`https://ghxiangqin.com/health`
|
||
|
||
2. 后端公开配置
|
||
`https://ghxiangqin.com/api/v1/auth/public-config`
|
||
|
||
3. 后台首页
|
||
`https://ghxiangqin.com/`
|
||
|
||
如果后台登录页能打开,但登录失败,重点检查:
|
||
|
||
1. `backend` 进程是否真的在运行
|
||
2. Nginx `/api/` 反向代理是否生效
|
||
3. MySQL 是否可连接
|
||
4. 管理员账号是否初始化完成
|
||
|
||
---
|
||
|
||
## 15. 小程序侧需要同步的配置
|
||
|
||
当前代码默认接口地址已经切到:
|
||
|
||
```text
|
||
https://ghxiangqin.com/api/v1
|
||
```
|
||
|
||
但微信公众平台还需要额外配置合法域名。
|
||
|
||
需要在微信公众平台配置:
|
||
|
||
1. `request 合法域名` 添加
|
||
`https://ghxiangqin.com`
|
||
|
||
2. 如果图片走你自己的域名,也要把图片域名加入合法域名
|
||
|
||
如果没配置,真机或正式版会报:
|
||
|
||
```text
|
||
request:fail url not in domain list
|
||
```
|
||
|
||
---
|
||
|
||
## 16. 后台前端更新流程
|
||
|
||
以后后台前端改了代码,更新方式如下:
|
||
|
||
```bash
|
||
cd /www/wwwroot/xqxcx/admin-web
|
||
npm install
|
||
npm run build
|
||
```
|
||
|
||
然后把新的 `dist/` 内容覆盖到:
|
||
|
||
```text
|
||
/www/wwwroot/ghxiangqin.com/
|
||
```
|
||
|
||
一般不需要重启 Nginx。
|
||
|
||
---
|
||
|
||
## 17. 后端更新流程
|
||
|
||
以后后端改了代码,更新方式如下:
|
||
|
||
```bash
|
||
cd /www/wwwroot/xqxcx/backend
|
||
source .venv/bin/activate
|
||
pip install -r requirements.txt
|
||
alembic upgrade head
|
||
```
|
||
|
||
然后重启后端进程管理器中的服务,例如:
|
||
|
||
1. 宝塔 Python 项目
|
||
2. Supervisor
|
||
3. systemd
|
||
|
||
---
|
||
|
||
## 18. 常见问题排查
|
||
|
||
### 18.1 首页能打开,但接口 404
|
||
|
||
说明前端静态站点正常,但 `/api/` 反代没有生效。
|
||
重点检查 Nginx 里是否有:
|
||
|
||
```nginx
|
||
location /api/ {
|
||
proxy_pass http://127.0.0.1:8000;
|
||
}
|
||
```
|
||
|
||
### 18.2 接口 502 Bad Gateway
|
||
|
||
说明 Nginx 找不到后端。
|
||
检查:
|
||
|
||
1. `uvicorn` 是否运行中
|
||
2. 是否监听在 `127.0.0.1:8000`
|
||
3. 宝塔反代目标地址是否写对
|
||
|
||
### 18.3 刷新后台子页面 404
|
||
|
||
说明 Vue 路由回退没配好。
|
||
确保 Nginx 有:
|
||
|
||
```nginx
|
||
location / {
|
||
try_files $uri $uri/ /index.html;
|
||
}
|
||
```
|
||
|
||
### 18.4 宝塔保存 Nginx 失败
|
||
|
||
如果错误里提到 SSL 证书缺失,就说明证书还没配置好。
|
||
先删掉:
|
||
|
||
```nginx
|
||
listen 443 ssl http2;
|
||
```
|
||
|
||
等证书申请完成后再启用 HTTPS 配置。
|
||
|
||
### 18.5 小程序请求失败
|
||
|
||
检查:
|
||
|
||
1. `https://ghxiangqin.com/api/v1/auth/public-config` 是否可访问
|
||
2. 微信后台是否配置合法域名
|
||
3. SSL 证书是否有效
|
||
4. 是否被防火墙拦截
|
||
|
||
---
|
||
|
||
## 19. 推荐的最终部署结构
|
||
|
||
推荐结构如下:
|
||
|
||
```text
|
||
/www/wwwroot/
|
||
├─ xqxcx/
|
||
│ ├─ backend/
|
||
│ ├─ admin-web/
|
||
│ └─ miniprogram/
|
||
└─ ghxiangqin.com/
|
||
├─ index.html
|
||
└─ assets/
|
||
```
|
||
|
||
说明:
|
||
|
||
1. 源码放在 `xqxcx/`
|
||
2. 前端打包结果单独放在站点目录 `ghxiangqin.com/`
|
||
3. Nginx 直接托管站点目录
|
||
4. 后端继续从源码目录运行
|
||
|
||
---
|
||
|
||
## 20. 一次完整上线的最短操作清单
|
||
|
||
按顺序执行:
|
||
|
||
1. 上传项目到服务器
|
||
2. 创建 MySQL 数据库 `dating_app`
|
||
3. 配置 `backend/.env`
|
||
4. 创建后端虚拟环境并安装依赖
|
||
5. 执行 `alembic upgrade head`
|
||
6. 执行 `python scripts/init_admin.py`
|
||
7. 启动 `backend` 到 `127.0.0.1:8000`
|
||
8. 执行 `admin-web/npm install`
|
||
9. 执行 `admin-web/npm run build`
|
||
10. 把 `dist/` 内容复制到 `/www/wwwroot/ghxiangqin.com/`
|
||
11. 在宝塔站点配置 Nginx:`/` 静态站点,`/api/` 反代后端
|
||
12. 访问 `http://ghxiangqin.com/health` 检查后端
|
||
13. 访问 `http://ghxiangqin.com/` 检查后台
|
||
14. 申请 SSL 证书
|
||
15. 切换到 HTTPS
|
||
16. 在微信公众平台配置 `https://ghxiangqin.com` 为合法域名
|
||
|
||
---
|
||
|
||
## 21. 本项目当前已经确认的地址
|
||
|
||
当前项目中已经统一使用:
|
||
|
||
```text
|
||
后台前端默认接口地址:
|
||
https://ghxiangqin.com/api/v1
|
||
|
||
小程序默认接口地址:
|
||
https://ghxiangqin.com/api/v1
|
||
```
|
||
|
||
所以只要 Nginx 的 `/api/` 反代配置正确,前后端就能直接连通。
|
||
|