У меня проблемы с тем, чтобы сервер bokeh отображал визуализацию при использовании https. У меня есть подобный стек, где сервер bokeh работает как положено с http. Кроме того, я могу получить соединение https для статического файла bokeh.html. Однако передача тега script в мой template.html не работает с https.
У меня nginx в качестве обратного прокси-сервера перед Gunicorn, на котором запущено приложение для фляги. Приложение фляги извлекает сеанс с работающего сервера bokeh на конкретном порту. Процесс сервера bokeh и процесс gunicorn / flask контролируются супервизором.
Я просмотрел существующую документацию по боке:
https://bokeh.pydata.org/en/latest/docs/user_guide/server.html#reverse-proxying-with-nginx-and-ssl
Я также просмотрел некоторые похожие вопросы здесь на SO:
Как настроить Nginx с подачей Gunicorn и Bokeh
Боке Служите HTTPS вместо HTTP
Как включить SSL / HTTPS на боке 0.12.5?
Обеспечение безопасности содержимого сценария для отображения HTTPS (Bokeh)
Я пробовал сочетания опций дляlative_urls = True / False в приложении фляги и --allow-websocket-origin = "myIP" / ["*"] при раскрутке сервера bokeh.
В этот момент я думаю, что мне просто не хватает чего-то очевидного, и я надеюсь, что кто-то еще увидит это. Я думаю, что ключевым моментом является то, что https работает вверх и вниз по стеку, когда обслуживает статический файл bokeh.html или другой контент, но терпит неудачу при попытке встроить сервер bokeh. Я подозреваю, что мне чего-то не хватает, как заставить колбу вытащить сеанс.
Заранее спасибо!
Ниже приведены все соответствующие разделы конфигурации и файлы flask.app:
Содержимое: / etc / nginx / sites-available / flask_settings
upstream gunicorn_flask {
server 127.0.0.1:6000 fail_timeout=0;
}
server {
listen 443 ssl http2 default_server;
server_name ###.###.###.###;
include snippets/self-signed.conf;
include snippets/ssl-params.conf;
access_log /var/log/nginx/https_access.log;
error_log /var/log/nginx/https_error.log;
ssl on;
location / {
proxy_pass http://gunicorn_flask;
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_buffering off;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header Host $host:$server_port;
}
}
server {
listen 80;
server_name ###.###.###.###;
return 301 https://$server_name$request_uri;
}
Содержимое: /etc/nginx/snippets/self-signed.conf
ssl_certificate /path/to/my/file.crt;
ssl_certificate_key /path/to/my/file.key;
Содержимое: /etc/nginx/snippets/ssl-params.conf
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
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-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=63072000";
ssl_dhparam /etc/ssl/certs/dhparam.pem;
Содержимое: /etc/supervisor/conf.d/bokeh.conf
[program:my_bokeh_viz]
directory=/my/path/to/bokeh/viz
command=/my/path/to/bokeh/bin/bokeh serve --allow-websocket-origin=###.###.###.### --address=127.0.0.1 --port 6001 --use-xheaders /my/path/to/bokeh/viz.py
autostart=true
autorestart=true
stderr_logfile=/var/log/my_bokeh_viz/Bokeh_Flask.err.log
stdout_logfile=/var/log/my_bokeh_viz/Bokeh_Flask.out.log
Содержимое: /etc/supervisor/conf.d/gunicorn.conf
[program:gunicorn_bokeh]
directory=/my/path/to/flask/app
command=/my/path/to/anaconda3/bin/gunicorn my_flask_app:app --bind 127.0.0.1:6000 --pythonpath /my/path/to/flask/app
autostart=true
autorestart=true
stderr_logfile=/var/log/gunicorn_bokeh/Bokeh_Flask.err.log
stdout_logfile=/var/log/gunicorn_bokeh/Bokeh_Flask.out.log
Содержимое: /path/to/my/flask/app.py
--- Relevant section of flask app.py
@app.route('/web/path/to/bokeh/viz', methods = ['GET'])
@login_required
def show_bokeh_viz():
host_url = 'http://127.0.0.1:6001/my_bokeh_viz'
my_session = pull_session(url = host_url)
client_url = 'http://###.###.###.###/web/path/to/bokeh/viz'
my_script = server_session(model = None,
session_id = my_session.id,
url = client_url,
relative_urls = False)
return render_template("embed.html", script = my_script, template = "Flask")
@app.route('/testing', methods = ['GET'])
@login_required
def show_test():
return render_template("stocks.html")
Содержимое: /path/to/my/flask/app/templates/embed.html
<!doctype html>
<html>
<body>
{{ script|safe }}
</body>
</html>
Источник страницы из отображаемого результата:
<!doctype html>
<html>
<body>
<script
src="https://###.###.###.###/web/path/to/my/bokeh/viz/autoload.js?bokeh-autoload-element=a4c3a28c-8bab-4e54-8ba8-8423914078aa&bokeh-app-path=/web/path/to/my/bokeh/viz&bokeh-absolute-url=https://###.###.###.###/web/path/to/my/bokeh/viz&bokeh-session-id=2GYRA1MPiBBX0qzlIB5ZEMyWQkV9AD1Br1KdgtZoew5P"
id="a4c3a28c-8bab-4e54-8ba8-8423914078aa"
data-bokeh-model-id=""
data-bokeh-doc-id=""
></script>
</body>
</html>