Deploy Bokeh flask app on Heroku -- I tried everything possible with no success

Hi,

I’m developing a simple Bokeh app that is embedded in Flask and I want deploy it on Heroku.

I think I covered most of the disscusions related to this issue on Guithub, Stackoverflow, and bokeh discourse.

the website is not allowing me to add more than 2 links in one topic, please review the issue on stackoverflow @ https://stackoverflow.com/questions/59902513/deploy-bokeh-flask-app-on-heroku-i-tried-everything-possible-with-no-success

Have you see @samirak93’s howto?

Yes, i’ve already checked it out. It’d be way much better if he shared the code that has the ports parts.

@samirak93 can you comment on some of these issues?

I just checked @samirak93 code out again. He is actually deploying bokeh app on heroku not embeding bokeh into flask which is the thing i’m trying to do.

UPDATE:

I’ve been trying to implement the same thing @samirak93 did but it didn’t work.

I got 500: Internal Server Error which was cause by nodejs as mentioned in the following error message in heroku logs. I tried to add nodejs in the requirements.txt file and still no success

2020-01-25T09:39:23.794218+00:00 app[web.1]: Traceback (most recent call last):
2020-01-25T09:39:23.794228+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/tornado/web.py", line 1469, in _execute
2020-01-25T09:39:23.794232+00:00 app[web.1]: result = yield result
2020-01-25T09:39:23.794234+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/tornado/gen.py", line 1015, in run
2020-01-25T09:39:23.794236+00:00 app[web.1]: value = future.result()
2020-01-25T09:39:23.794247+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/tornado/concurrent.py", line 237, in result
2020-01-25T09:39:23.794250+00:00 app[web.1]: raise_exc_info(self._exc_info)
2020-01-25T09:39:23.794252+00:00 app[web.1]: File "<string>", line 3, in raise_exc_info
2020-01-25T09:39:23.794254+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/tornado/gen.py", line 1024, in run
2020-01-25T09:39:23.794256+00:00 app[web.1]: yielded = self.gen.send(value)
2020-01-25T09:39:23.794259+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/types.py", line 208, in send
2020-01-25T09:39:23.794261+00:00 app[web.1]: return self.__wrapped.send(val)
2020-01-25T09:39:23.794263+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/bokeh/server/views/doc_handler.py", line 61, in get
2020-01-25T09:39:23.794266+00:00 app[web.1]: template_variables=session.document.template_variables)
2020-01-25T09:39:23.794276+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/bokeh/embed/server.py", line 227, in server_html_page_for_session
2020-01-25T09:39:23.794278+00:00 app[web.1]: bundle = bundle_for_objs_and_resources(None, resources)
2020-01-25T09:39:23.794280+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/bokeh/embed/bundle.py", line 184, in bundle_for_objs_and_resources
2020-01-25T09:39:23.794282+00:00 app[web.1]: ext = bundle_models(models)
2020-01-25T09:39:23.794284+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/bokeh/util/compiler.py", line 338, in bundle_models
2020-01-25T09:39:23.794287+00:00 app[web.1]: _bundle_cache[key] = bundle = _bundle_models(custom_models)
2020-01-25T09:39:23.794289+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/bokeh/util/compiler.py", line 551, in _bundle_models
2020-01-25T09:39:23.794291+00:00 app[web.1]: custom_impls = _compile_models(custom_models)
2020-01-25T09:39:23.794293+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/bokeh/util/compiler.py", line 528, in _compile_models
2020-01-25T09:39:23.794295+00:00 app[web.1]: compiled = nodejs_compile(impl.code, lang=impl.lang, file=impl.file)
2020-01-25T09:39:23.794297+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/bokeh/util/compiler.py", line 111, in nodejs_compile
2020-01-25T09:39:23.794299+00:00 app[web.1]: output = _run_nodejs([compilejs_script], dict(code=code, lang=lang, file=file, bokehjs_dir=bokehjs_dir))
2020-01-25T09:39:23.794302+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/bokeh/util/compiler.py", line 475, in _run_nodejs
2020-01-25T09:39:23.794304+00:00 app[web.1]: return _run(_nodejs_path(), argv, input)
2020-01-25T09:39:23.794306+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/bokeh/util/compiler.py", line 451, in _nodejs_path
2020-01-25T09:39:23.794308+00:00 app[web.1]: _nodejs = _detect_nodejs()
2020-01-25T09:39:23.794310+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/bokeh/util/compiler.py", line 443, in _detect_nodejs
2020-01-25T09:39:23.794312+00:00 app[web.1]: '("conda install nodejs" or follow https://nodejs.org/en/download/)')
2020-01-25T09:39:23.794322+00:00 app[web.1]: RuntimeError: node.js v6.10.0 or higher is needed to allow compilation of custom models ("conda install nodejs" or follow https://nodejs.org/en/download/)
2020-01-25T09:39:23.795169+00:00 app[web.1]: 2020-01-25 09:39:23,795 500 GET /myapp (78.XX.XXXX.XXX) 244.84ms

Did you install nodejs, as the message instructs?

Yes i did include it in the requirments.txt file and it should be installed when the app deployed to heroku. Unfortunately, i got the same error :frowning:

In that case wherever it installed is not any place Bokeh knows where to look. You will have to explicitly tell Bokeh where to look with an environment variable:

http://docs.bokeh.org/en/latest/docs/reference/settings.html#phantomjs-path

I’m confused about the requirements.txt comment, though. NodeJS is not a Python package. AFAIK the pip installable package is just Python bindings, and not actually NodeJS.

I think you have some confusion. The requirements.txt file is use by the pip package manager to install Python (only) packages from PyPI. By contrast, conda is the package manager for the Anaconda distribution, and can install both Python packages, also also things besides Python packages (e.g. NodeJS). However, conda does not use the requirements.txt file. If you aren’t using Anaconda on your Heroku instance, you will need to find some other way to install NodeJS, since the pip installable “nodejs” package is not actually the real, full NodeJS runtime. It is only:

Python bindings and utils for Node.js and io.js.

So as far as I can tell, you are not, in fact, actually installing NodeJS. This is the first problem to solve (I don’t know how to install packages on Heroku, I can’t help here) because it is causing the Internal Server Error you show above. There is no point in worrying about anything else until you figure out how to install NodeJS.

Thanks of the clarification Bryan!

I got Internal Server Error when I tried to deploy the app the same way @samirak93 did it, which is by running Bokeh on Heroku without using Flask.

in this comment, I’m embedding Bokeh into Flask and then deploy it to Heroku.

note that, the Heroku’s logs is healthy and no issues showing up. the only problem I have is after I deploy the app and open up the page, it takes too long to load and then it give this error
Failed to load resource: net::ERR_CONNECTION_TIMED_OUT
which I think is caused by using HTTPS

@ziyad If you want/need the Bokeh server to terminate SSL you will have to configure SSL certs for that to happen:

https://docs.bokeh.org/en/latest/docs/user_guide/server.html#ssl-termination

I tried to resolve the issues but couldn’t do it. I found a Github repo for deploying bokeh-flask on heroku and that worked for me.

Repo: https://github.com/knohyou/Flask-Heroku-Bokeh

Also there was a Discourse topic on the same. If @ArtemAleksieiev is active here, maybe he could give us some info as to how he managed to deploy it.

https://discourse.bokeh.org/t/deploying-flask-bokeh-to-heroku/4039

Thanks @Bryan and @samirak93 for the support and feedback.

I gave up on trying to deploy my app by embedding it into Flask. Instead, I deployed Bokeh app as stand-alone app to Heroku.

When I tried @samirak93 's way , it didn’t work because nodejs has to be installed via conda.

I resolved the issue by installing conda buildpack to my heroku app at first, then add nodejs to the requirements.

in case someone faced the same issue in the future, here are the steps:
1- install buildpack to your existing Heroku app :
heroku buildpacks:set https://github.com/pl31/heroku-buildpack-conda.git -a [heroku_app_name]

2- to install nodejs and other requirements:

  • create a a text file named environment.yml
  • add the required libraries to be installed during the deployment structured as follow:

I will write up a blog post soon and I will share it :slight_smile:

2 Likes