以前一直在想怎么把一些写过的项目部署到云服务器上,方便展示。之前一直都听说过 Heroku,简单查了下确实可以方便我们的项目部署,最近闲来无事,准备拿 what-digit-you-write(一个将 Flask 和 Tensorflow2 相结合的手写数字识别 Web 应用)来练练手,并将部署到 Heroku 的过程记录如下。
关于 Heroku
1. 注册 Heroku
首先要去 Heroku 上注册一个账号,这里建议使用 gmail 或者 outlook 邮箱,注册的过程中建议挂着梯子以防注册过程时无法现实验证码。如果一直没有收到邮件,建议查一下自己的垃圾邮箱或者已删除邮件是否有注册验证的邮件。
2. 下载 Heroku CLI 程序
下载链接在 https://devcenter.heroku.com/articles/heroku-cli#download-and-install。在后续的的部署中,都需要用到 heroku
这一命令。
3. 登录 Heroku
1 | heroku login |
此时会跳转到网页请求登录,这个时候建议保持梯子连接的稳定,否则容易刷新不出页面的情况,如果连接了梯子仍然无法现实,建议耐心的多刷新几次。
准备项目
heroku 的部署也是需要 Git 操作的。因此,如果有一个现成的 Git 项目,那么可以跳到 下一节。
如果此时项目还不是 Git 项目,那么操作下也很简单:
1 | git init |
注意
- 文件的添加情况请根据实际场景来完成,并且要避免添加一些无用的大文件,这是因为 Heroku 项目的部署有文件大小的限制(上线 500M),如果最终项目大于了限制数则会导致部署失败;
- 此时还不需要
git push origin <branch>
又因为我们的项目是一个 Python Web 项目,所以我们还需要导出依赖配置文件 requirements.txt
:
1 | pip freeze > requirements.txt |
容易踩坑的地方
关于存在与 GPU 相关的依赖
首先 Heroku
服务器是没有 GPU 的,所以既然我们使用了 Tensorflow
,那么我们就要注意把与 GPU 和 CUDA 相关的依赖项去掉(比如 cudnn
和 cudatoolkit
,如果不去掉会因为无法下载依赖导致部署失败),并下载 tensorflow-cpu
版本(默认的 Tensorflow
会包含 GPU 模块,这会导致最终项目的空间占用大于 500M,从而导致部署失败)。如果你使用的是 Pytorch
,也是一样的操作逻辑。
关于 Python 版本的问题
不同的 Heroku
版本,在后台运行的 Python 版本都是不同的,具体的可以查看这个文档 。
我们的项目需要依赖 Python3.7,并且我们使用的 tensorflow-cpu 版本为 2.1.0
这也与 Python 的版本相关。而我们下载 Heroku 版本为 22,是不支持 Python3.7 的。此时,我们有两个方式可以选择:
- 继续使用当前的
Heroku
版本,但是需要修改tensorflow-cpu
的版本 (对于 Python3.10 能支持的tensorflow-cpu
最低版本为2.8.0
); - 修改 Python 版本(参考这个文档),并需要修改
Heroku Stack
为20
(参考这个文档).
如果需要在已经存在的项目上修改 Heroku Stack
,那么可以使用如下命令修改:
1 | heroku stack:set heroku-20 |
如果是想在新创建项目的时候,指定 Heroku Stack
,也可以使用如下的方式:
1 | heroku create <your-app-name> --stack heroku-20 |
这里我两个方案都尝试了,最后选择了方案一。
部署到 Heroku
1. 创建 Heroku 仓库
在 Git 项目目录下,使用如下命令:
1 | heroku craete <appname> |
如果创建成功,heroku
会为 Git 仓库添加一个 heroku
的远端链接,方便我们之后可以直接 push
到 heroku
仓库中。
2. 使用 Gunicorn
毕竟是要部署 Flask
项目,这里还是建议使用 Gunicorn
来启动服务。首先需要在 requirements.txt
添加两个依赖:
1 | gunicorn |
这里不指定版本也没有问题。然后在项目目录下,创建一个文件名 Procfile
,没有文件后缀,文件内容只有一行,就是为了让 Heroku
在部署项目后启动我们的服务:
1 | web: gunicron <your-app-main-file>:app |
由于在 what-digit-you-write
中,我的主程序为 app.py
,所以我的 Procfile
内容为:
1 | web: gunicorn app:app |
部署项目
如果我们在 准备项目 阶段成功避免了坑点(删掉 GPU 相关依赖,修改 Tensorflow
为 cpu 版本,对应好 Heroku Stack
版本和 Python
版本),并在上一小节中正确配置了 gunicorn。那么此时我们的项目,应该是可以直接通过以下指令直接部署到 Heroku
上的。
1 | git push heroku master |
然后我可以查看部署项目的日志情况,检查一下是否顺利:
1 | heroku logs |
如果是一般的项目问题此时应该可以正常启动了,但是如果你的项目用了 Tensorflow
(可能用了 Pytorch
也是)会出现下面的问题,导致项目部署失败。
这里我参照的解决方法是这篇博客。简单来说,我们只需要往 requirements.txt
中添加一个 3.19.0
版本以上的 protobuf
的依赖就可以了。
1 | protobuf==3.19.0 |
这时需要我们对修改后的 requirements.txt
添加到 Git 中,并提交到 Heroku
仓库远端。重新部署项目后,再检查一下 heroku logs
最新的日志情况,如果成功启动了项目,那么就可以打开演示项目地址进行体验了:
1 | heroku open |