将 what-digit-you-write 部署到 Heroku上

以前一直在想怎么把一些写过的项目部署到云服务器上,方便展示。之前一直都听说过 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
2
3
git init
git add .
git commit -m "commit message"

注意

  1. 文件的添加情况请根据实际场景来完成,并且要避免添加一些无用的大文件,这是因为 Heroku 项目的部署有文件大小的限制(上线 500M),如果最终项目大于了限制数则会导致部署失败;
  2. 此时还不需要 git push origin <branch>

又因为我们的项目是一个 Python Web 项目,所以我们还需要导出依赖配置文件 requirements.txt:

1
pip freeze > requirements.txt

容易踩坑的地方

关于存在与 GPU 相关的依赖

首先 Heroku 服务器是没有 GPU 的,所以既然我们使用了 Tensorflow,那么我们就要注意把与 GPU 和 CUDA 相关的依赖项去掉(比如 cudnncudatoolkit,如果不去掉会因为无法下载依赖导致部署失败),并下载 tensorflow-cpu 版本(默认的 Tensorflow 会包含 GPU 模块,这会导致最终项目的空间占用大于 500M,从而导致部署失败)。如果你使用的是 Pytorch,也是一样的操作逻辑。

关于 Python 版本的问题

不同的 Heroku 版本,在后台运行的 Python 版本都是不同的,具体的可以查看这个文档

我们的项目需要依赖 Python3.7,并且我们使用的 tensorflow-cpu 版本为 2.1.0 这也与 Python 的版本相关。而我们下载 Heroku 版本为 22,是不支持 Python3.7 的。此时,我们有两个方式可以选择:

  1. 继续使用当前的 Heroku 版本,但是需要修改 tensorflow-cpu 的版本 (对于 Python3.10 能支持的 tensorflow-cpu 最低版本为 2.8.0);
  2. 修改 Python 版本(参考这个文档),并需要修改 Heroku Stack20(参考这个文档).

如果需要在已经存在的项目上修改 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 的远端链接,方便我们之后可以直接 pushheroku 仓库中。

2. 使用 Gunicorn

毕竟是要部署 Flask 项目,这里还是建议使用 Gunicorn 来启动服务。首先需要在 requirements.txt 添加两个依赖:

1
2
gunicorn
psycopg2

这里不指定版本也没有问题。然后在项目目录下,创建一个文件名 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
Author: Inno Fang
Link: http://innofang.github.io/2022/10/11/%E5%B0%86what-digit-you-write%E9%83%A8%E7%BD%B2%E5%88%B0heroku%E4%B8%8A/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-ND 4.0 unless stating additionally.