前言
一个全栈的小项目,里面既有前端也有后端,在这里前端是vue
, 后端是flask
。
前端的编译结果输出到flask/dist
文件夹里。
后端的flask程序做成了模块,也就是说在flask/app/__init__.py
里有一个create_app()的函数。
现在的问题是,怎样把它们一起部署到heroku上, 并在部署时完成自动编译?
1 | your-app |
最基础的flask部署方式
如果flask没有做模块化,部署方式也很简单
通常flask的主程序都是这么写的:
一个名为app.py
的程序,内容如下
1 | from flask import Flask |
部署到heroku时,Procfile这么写:
1 | web: gunicorn app:app |
这里gunicorn是python的HTTP服务器,类似于java的tomcat
app:app
的写法解释一下:
- 第一个app是指app.py
- 第二个app指上述程序中的app变量
理解这个写法的含义很关键,之后全栈程序的部署也要相应的调整。
全栈程序需要的调整
程序入口
在一开始的文件夹结构中,我们的flask程序做成了模块,不存在类似于
app.py
的程序。所以要新建一个,在这里我们叫它heroku.py
。内容也很简单:
1
2
3
4
5
6import app
heroku = app.create_app()
if __name__ == "__main__":
heroku.run()Procfile的调整
由于我们的flask程序在
flask
文件夹里,相对于Procfile位置不同,所以要加上--chdir ./flask
的参数。同时由于我们的程序名称为
heroku.py
,变量名称为heroku
,都需要做相应的调整,于是Profile如下所示:1
web: gunicorn --chdir ./flask heroku:heroku
前端编译的设置
由于我们的前端存放于vue文件夹里,为了能让heroku识别并编译,我们把整个项目先当作一个node程序,在项目文件夹里添加一个package.json文件。
并在scripts中写上vue项目的编译命令cd vue && npm install && npm run build
。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16{
"name": "your-app-name",
"version": "1.0.0",
"license": "MIT",
"engines": {
"node": "14.15.x",
"yarn": "1.22.x",
"npm": ">= 3.0.0"
},
"scripts": {
"heroku-postbuild": "cd vue && npm install && npm run build"
},
"cacheDirectories": [
"vue/node_modules"
]
}完整结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15your-app
├── flask
│ ├── app
│ ├── dist
│ └── test
│ └── heroku.py
└── vue
├── build
├── config
├── node_modules
├── src
├── static
└── test
└── Procfile
└── package.json添加环境变量。
把本地flask项目中
.env
文件的内容配置到heroku里面。1
cat .env | tr '\n' ' ' | xargs heroku config:set -a your_app
在heroku的设置页面添加python的buildpack
顺序为:- nodejs
- python
npm install troubleshooting
在第一次部署node程序的时候,heroku默认只安装dependencies中的依赖。如果想让heroku安装devDependencies的话,需要设置如下环境变量。
1
heroku config:set NPM_CONFIG_PRODUCTION=false