如何在Heroku上部署Docker化的应用程序?

3
我希望在Heroku上部署一个基本的Flask应用程序。
这是我的应用程序的基本结构:
├── Dockerfile
├── Makefile
├── README.rst
├── app
│   ├── __init__.py
│   └── app.py
├── heroku.yml
├── poetry.lock
├── pyproject.toml
└── tests
    ├── __init__.py
    └── test_app.py

我希望每次将PR合并到我的项目的主分支时,应用程序都能够重新部署,因此我通过Heroku中的自动部署选项进行了设置。我能够在本地成功运行此应用程序以及通过docker容器(也是本地),但是Heroku无法部署该应用程序。我遇到的第一个错误是“无法检测到此应用程序的默认语言”,这导致我为此应用程序启用了构建包(python)。设置构建包后,我收到以下错误:“应用与构建包不兼容:https://buildpack-registry.s3.amazonaws.com/buildpacks/heroku/python.tgz... ! push failed”。我发现一些相关的讨论(例如this),这些讨论似乎表明Poetry可能是问题所在,而我需要一个“requirements.txt”,但即使生成了一个,我仍然会收到相同的错误。有人知道这里出了什么问题吗?我感觉有些根本性的问题,因为我甚至不需要构建包——docker镜像应该可以处理这个问题。另外,heroku.yml包含以下内容:
build:
  docker:
    web: Dockerfile

请告诉我是否需要更多关于我的应用程序设置的信息。
非常感谢!
更新1:
我已经成功通过 "heroku container:push web -a APP_NAME" 和 "heroku container:release web -a APP_NAME" 将我的docker镜像推送到Heroku,但是当我打开应用https://APP_NAME.herokuapp.com/时,我发现它无法启动,这并不奇怪,因为我的dockerfile没有以"RUN python app.py" 结尾 -- 如果我添加了那行代码并重新运行上述命令,那么整个过程会在构建镜像时停止,最后一行是“Running on ...”-- 我认为在此异步运行它不是正确的解决方案。
有什么建议吗?如果我成功让Heroku容器工作,那么我想这意味着我不能让Heroku每次更新主分支时都重建我的镜像,而是需要自己完成。

1
你需要告诉Heroku如何运行你的应用程序。你的Dockerfile文件中是否有CMD指令? - Petr Gazarov
谢谢,我想我已经解决了,至少部分地解决了,请看下面的答案。我仍然想知道Heroku是否提供任何持续集成工具来支持这种部署策略。我知道它有检查主分支以重新部署应用程序的选项,但如果我正在部署自己的Docker镜像,我认为这个选项不再可用。 - IVR
1个回答

3

我搞定了,以下是我的做法:

  1. 更改 Flask 应用程序的端口信息(这里有更多细节)。
  2. app.py 移动到顶层目录下(如 appdir/app.py 而不是 appdir/app/app.py)。
  3. 安装 gunicorn
  4. 在您的项目顶层创建一个 Procfile 文件,其中应包含 web: gunicorn app:app
  5. Dockerfile 中的最后一行应该不是 python app.py,而是 gunicorn app:app
  6. 运行命令 heroku container:push web -a APP_NAME; heroku container:release web -a APP_NAME

我仍然没有搞清楚持续集成如何适用于这里(也就是说,Heroku 本身是否提供了任何东西?),所以如果有人有任何建议,请告诉我。

更新

只是想补充一下,关于 CI 我最终使用了 GitHub Actions。 我创建了一个文件放在 .github/workflows/deploy.yaml 下,其中包含以下内容:

    - name: deploy
      env:
        HEROKU_API_KEY: ${{ secrets.HEROKU_API_TOKEN }}
        HEROKU_APP_NAME: "covid-monitor"
      run: |
        heroku container:login
        heroku container:push web -a $(appname)
        heroku container:release web -a $(appname)

请注意,为了使此功能正常工作,您需要将Heroku API令牌添加到GitHub secrets中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接