0%

How to deploy full-stack Flask app to Heroku

前言

一个全栈的小项目,里面既有前端也有后端,在这里前端是vue, 后端是flask

前端的编译结果输出到flask/dist文件夹里。

后端的flask程序做成了模块,也就是说在flask/app/__init__.py里有一个create_app()的函数。

现在的问题是,怎样把它们一起部署到heroku上, 并在部署时完成自动编译?

1
2
3
4
5
6
7
8
9
10
11
12
your-app
├── flask
│ ├── app
│ ├── dist
│ └── test
└── vue
├── build
├── config
├── node_modules
├── src
├── static
└── test

最基础的flask部署方式

如果flask没有做模块化,部署方式也很简单
通常flask的主程序都是这么写的:

一个名为app.py的程序,内容如下

1
2
3
4
5
6
7
8
9
10
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
return 'hello, world'

if __name__ == '__main__':
app.run()

部署到heroku时,Procfile这么写:

1
web: gunicorn app:app

这里gunicorn是python的HTTP服务器,类似于java的tomcat

app:app的写法解释一下:

  • 第一个app是指app.py
  • 第二个app指上述程序中的app变量

理解这个写法的含义很关键,之后全栈程序的部署也要相应的调整。

全栈程序需要的调整

  1. 程序入口

    在一开始的文件夹结构中,我们的flask程序做成了模块,不存在类似于app.py的程序。所以要新建一个,在这里我们叫它heroku.py

    内容也很简单:

    1
    2
    3
    4
    5
    6
    import app

    heroku = app.create_app()

    if __name__ == "__main__":
    heroku.run()
  2. Procfile的调整

    由于我们的flask程序在flask文件夹里,相对于Procfile位置不同,所以要加上--chdir ./flask的参数。

    同时由于我们的程序名称为heroku.py,变量名称为heroku,都需要做相应的调整,于是Profile如下所示:

    1
    web: gunicorn --chdir ./flask heroku:heroku
  3. 前端编译的设置
    由于我们的前端存放于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"
    ]
    }
  4. 完整结构

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    your-app
    ├── flask
    │ ├── app
    │ ├── dist
    │ └── test
    │ └── heroku.py
    └── vue
    ├── build
    ├── config
    ├── node_modules
    ├── src
    ├── static
    └── test
    └── Procfile
    └── package.json
  5. 添加环境变量。

    把本地flask项目中.env文件的内容配置到heroku里面。

    1
    cat .env | tr '\n' ' ' | xargs heroku config:set -a your_app
  6. 在heroku的设置页面添加python的buildpack
    顺序为:

    • nodejs
    • python
  7. npm install troubleshooting

    在第一次部署node程序的时候,heroku默认只安装dependencies中的依赖。如果想让heroku安装devDependencies的话,需要设置如下环境变量。

    1
    heroku config:set NPM_CONFIG_PRODUCTION=false