I am not able to show the Bokeh server app when I add SSL to my Nginx proxy server; the Index page shows up with SSL, but the page with embed Bokeh server document does not show the plot. Without SSL everything works fine. I am running the webserver on an internal private network, hence the certificate created is just self signed.
I am using the --use-xheaders
option when running the Bokeh server. I use server_document
to embed Bokeh doc. If I in the app route for the bokeh url specify regular http:// then I get an browser error related to mixed content.
Blocked loading mixed active content “http://10.73.162.4:5100/bokeh/sliders/autoload.js?bokeh-auto…ers&bokeh-absolute-url=http://10.73.162.4:5100/bokeh/sliders”
If I instead use https://
then nothing happens (seems to be time out on the bokeh script). Browser reports in the XHR among others “No headers for this request”; (since the Bokeh server is running on http://
then this is expected I guess).
Starting Bokeh server:
bokeh serve sliders/ --prefix /bokeh --allow-websocket 10.73.162.4 --address 10.73.162.4 --port 5100 --use-xheaders
Gunicorn:
gunicorn --bind 0.0.0.0:8000 wsgi:app
Using Bokeh version 2.0.2 (not the latest due to bug related to some transformation), CentOS 8.
So I do not understand how to get the Nginx proxy to show the Bokeh doc with setup with SSL for Nginx part. Any help appreciated.
nginx conf
server {
listen 443 ssl;
server_name 10.73.162.4;
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
#
# # enables all versions of TLS, but not SSLv2 or v3 which are deprecated.
ssl_protocols TLSv1.1 TLSv1.2;
#
# # disables all weak ciphers
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-A-$
#
ssl_prefer_server_ciphers on;
# bokeh apps are run with prefix option where prefix bokeh
location /bokeh {
proxy_pass http://10.73.162.4:5100;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host:$server_port;
}
location / {
proxy_pass http://0.0.0.0:8000;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
application/route.py
from flask import render_template, request
from flask import current_app as app
from bokeh.embed import server_document, server_session
from bokeh.client import pull_session
# setup all the routes
@app.route('/')
@app.route('/index')
def home():
"""Landing page."""
return render_template(
'index.html',
title = 'Index',
)
BOKEH_PREFIX = 'bokeh/'
BOKEH_IP = '10.73.162.4'
BOKEH_PORT = '5100'
@app.route('/sliders')
def sliders():
title = 'Sliders'
app_name = 'sliders'
bk_app = '{}{}'.format(BOKEH_PREFIX, app_name)
app_url = 'https://{}:{}/{}'.format(
BOKEH_IP,
BOKEH_PORT,
bk_app
)
print(app_url)
bokeh_script = server_document(url = app_url, relative_urls = False)
print(bokeh_script)
return render_template("bk_app.html", bokeh_script = bokeh_script, title = title, url = app_url)
application/templates/bk_app.html
<!-- bk_app.html -->
<!doctype html>
<html>
<head>
<title>{{title}}</title>
</head>
<body>
<div>
<ul>
<li>
<a href="{{ url_for('home') }}">Index</a>
</li>
</ul>
</div>
<div>
{{ bokeh_script|safe }}
</div>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-2.0.2.min.js"
crossorigin="anonymous"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.0.2.min.js"
crossorigin="anonymous"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.0.2.min.js"
crossorigin="anonymous"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-api-2.0.2.min.js"
crossorigin="anonymous"></script>
</body>
</html>
application/templates/index.html
<!-- index.html -->
<!doctype html>
<html>
<head>
<title>{{title}}</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/template.css') }}">
{% block head %}{% endblock %}
</head>
<body>
<ul>
<li>
<a href="{{ url_for('sliders') }}">Sliders</a>
</li>
</ul>
</body>
</html>
**application/init.py
from flask import Flask
def create_app():
"""Initialize the core application."""
app = Flask(
__name__,
instance_relative_config = False,
template_folder = 'templates',
static_folder = 'static'
)
with app.app_context():
# Include our Routes
from . import routes
return app
wsgi.py
from application import create_app
app = create_app()
if __name__ == "__main__":
app.run(host='0.0.0.0', port = 8000, debug = True)