Flask + Vue 项目部署到腾讯云 + 宝塔 流程

第一次部署一个前后端分离的项目到云服务器,感觉很麻烦遂记录一下

1. 总体架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Vue 前端
├── 本地 build 得到dist文件夹
├── 上传到服务器
└── 在宝塔直接按照静态网页的方式托管静态文件

Flask 后端
├── 服务器上用 Gunicorn 跑
└── 监听 127.0.0.1:端口号


Nginx
├── 对外监听域名 3dsmax.redjinx.me
├── / → Vue 的 dist
└── /api/ → 转发给 Flask 127.0.0.1:5004

2. 目录结构

服务器上的结构:

1
2
3
4
5
6
7
8
9
/www/wwwroot/3dsmax.redjinx.me/
├── backend/
│ ├── app.py
│ ├── .env
│ ├── flask/ # 虚拟环境
│ └── gunicorn.log
└── dist/
├── index.html
└── assets/

3. Flask 后端启动方式

进入后端目录:

1
2
cd /backend
source flask/bin/activate #激活虚拟环境

启动 Gunicorn:

1
nohup gunicorn -w 4 -b 127.0.0.1:5004 app:app > gunicorn.log 2>&1 &

参数说明:

  • -w 4:4 个 worker
  • -b 127.0.0.1:5004:只监听本机 5004
  • app:app:前一个 app = app.py,后一个 app = Flask 实例变量名

4. 如何判断 Flask 是否真的跑起来

本机测试接口:

1
curl http://127.0.0.1:5004/api/students

判断标准:

返回结果 含义
返回 JSON 数据 后端正常
返回 JSON 错误 后端已跑起来,但业务逻辑/数据库有问题
connection refused Gunicorn 没启动
404 Not Found Gunicorn 跑了,但访问的接口路径不对

这次你最后看到数据库报错和接口数据,说明后端链路已经通了。


5. 数据库配置排查的核心思路

这次遇到的典型问题是:

1.flask已经改了用户和 密码但还是没访问到

原因:
.env文件中信息并没有被更新

2.数据库表格上传的时候报版本错误

云端数据库版本 utf8mb4 utf8mb4 unicode_ci
本地数据库也要与这个版本一致

6. 只重启当前项目的 Gunicorn

因为服务器上还有别的项目,不能直接:

1
pkill -f gunicorn

正确方式是只杀当前端口:

1
2
lsof -i:5004
kill -9 对应PID

或者:

1
pkill -f "5004"

然后重新启动:

1
2
3
cd backend
source flask/bin/activate
nohup gunicorn -w 4 -b 127.0.0.1:5004 app:app > gunicorn.log 2>&1 &

7. Nginx 配置方法

先用配置静态网页的方式,在宝塔里配置静态网页,将域名和本地文件对应起来
- root 指向 Vue 的 dist
- / 走前端静态页面
由于我在宝塔没找到改主文件配置的方法,于是把宝塔中关于这个新项目的nginx配置全关闭和删除了
,而是去服务器中,找宝塔给的nginx配置文件,具体位置:
1
cat /www/server/panel/vhost/nginx/项目名.conf

接下来在这个文件夹中修改具体的nginx配置

8. nginx配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
server
{
listen 80;
server_name 3dsmax.redjinx.me;
index index.html index.htm;
root /www/wwwroot/3dsmax.redjinx.me/dist;

location / {
try_files $uri $uri/ /index.html;
}

location /api/ {
proxy_pass http://127.0.0.1:5004;
proxy_http_version 1.1;

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_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}

关键点:

  • root 指向 Vue 的 dist
  • try_files ... /index.html; 用于支持 Vue 路由刷新
  • /api/ 转给 Flask

9. 启动nginx方式

检查配置:

1
nginx -tt

成功后重启:

1
/etc/init.d/nginx restart

10. 前端请求接口的正确写法

前端不要写死成:

1
2
3
// 错误
http://127.0.0.1:5004/api/students
http://3dsmax.redjinx.me:5004/api/students

正确写法是:

1
2
3
4
5
6
7
// 正确 - 相对路径
/api/students

// 或者 axios
const request = axios.create({
baseURL: '/api'
})

请求流程:

  1. 浏览器访问 https://3dsmax.redjinx.me/api/students
  2. Nginx 转发到 127.0.0.1:5004/api/students
  3. Gunicorn 接收请求
  4. Flask 处理接口
  5. 返回 JSON 给前端

11. 以后部署同类项目的最短流程

以后可以直接按这个顺序:

后端

1
2
3
cd backend
source flask/bin/activate
nohup gunicorn -w 4 -b 127.0.0.1:500x app:app > gunicorn.log 2>&1 &

前端

  1. 本地 npm run build
  2. 上传 dist 到服务器站点目录

Nginx

  • root 指向 dist
  • /try_files
  • /api/ → 反代 Flask

检查

1
2
3
nginx -tt
/etc/init.d/nginx restart
curl http://127.0.0.1:500x/你的接口