如何在Procfile中运行两个进程?

时间:2016-09-22 14:17:01

标签: python heroku flask bokeh procfile

我有一个Flask应用程序,我已经嵌入了一个Bokeh服务器图,我无法让他们都在Heroku上工作。我正在尝试在Heorku上部署,我可以从Procfile启动Bokeh应用程序或Flask应用程序,但不能同时启动它们。因此,要么显示Flask提供的内容,要么显示Bokeh图。

当我在Procfile中使用以下行进行部署时,Bokeh内容会显示在网页上,但不会出现在Flask中:

web: bokeh serve --port=$PORT --host=bokehapp.herokuapp.com --host=* --address=0.0.0.0 --use-xheaders bokeh_script.py

如果我使用以下内容部署,我只获取Flask内容,而不是Bokeh图:

web: gunicorn app:app

在第二种情况下,我使用子进程在app.py Flask脚本中启动Bokeh:

bokeh_process = subprocess.Popen(
    ['bokeh', 'serve','--allow-websocket-origin=bokehapp.herokuapp.com','--log-level=debug','standard_way_with_curdoc.py'], stdout=subprocess.PIPE)

Heroku日志不会显示任何错误。

我还尝试了第三种选择:

web: bokeh serve --port=$PORT --host=bokehapp.herokuapp.com --host=* --address=0.0.0.0 --use-xheaders bokeh_script.py
web: gunicorn app:app

这仅显示Flask内容。似乎只考虑了第二名工人。

那么,我的问题是如何修改Procfile以考虑这两个进程? 或者也许我一起接近这个错误?您可以提供的任何线索将不胜感激。

1 个答案:

答案 0 :(得分:6)

每个Heroku dyno都会分配一个公共网络端口,您可以从启动应用程序之前由Heroku预先分配的$PORT变量中获取该端口。这种不幸的副作用是你只能在一个dyno中运行一个公共Web服务器。

我认为您需要做的第一件事就是通过Flask服务器将所有请求路由到您的应用程序。例如,您可以向Flask应用添加/bokeh/<path:path>路由,使用requests将所有请求转发到散景服务器,然后将响应发送回客户端。通过此更改,您现在可以拥有一个公共Web服务器,并且散景服务器可以作为后台服务运行,无需公共访问。

现在您可以将Flask应用程序部署到Heroku,并让它接收自己的请求和散景服务器的请求。下一步是找出部署散景服务器的位置。

执行此操作的正确方法是在单独的dyno上部署散景。 Flask dyno将知道如何将请求转发给bokeh,因为您将拥有一个包含散景服务器URL的配置项。

如果你想把所有东西托管在一个dyno上,我认为你也可以,尽管我自己从未尝试过这个并且无法证实它是可行的。一体化配置不太理想,而不是Heroku推荐的,但根据dyno networking documentation,您可以私下监听除$PORT之外的任何网络端口。这些都没有公开曝光,但是文档似乎暗示在dyno中运行的进程可以通过私有端口进行通信。例如,您可以在$PORT$PORT + 1上的散景服务器上启动Flask应用,并让Flask在内部将所有散景请求转发到$PORT + 1