Скрипт Bokeh server_document загружается с IP (HTTP), но не с домена (HTTPS) - PullRequest
0 голосов
/ 11 мая 2019

У меня есть приложение Bokeh, встроенное в Flask и Gunicorn (см. flask_gunicorn_embed.py ). Это работает нормально, когда я получаю доступ ко всему через IP-адрес веб-сервера, но не когда все прокси через Nginx. Он будет загружать все из Flask, но не из Bokeh (autoload.js).


Пример:

Я запускаю Flask через Gunicorn с

gunicorn --workers 9 --bind 0.0.0.0:5000 --timeout 120 --log-file /some/directory/to/gunicorn/logs/gunicorn.log -m 0700 flask:app

Теперь я могу получить доступ ко всему от Flask до http://xxx.xxx.xxx.xxx:5000. Я адаптировал flask_gunicorn_embed.py , и самые важные биты

script = server_document('http://xxx.xxx.xxx.xxx:%d/bkapp' % port, resources=None)
sockets, port = bind_sockets("0.0.0.0", 0)
bokeh_tornado = BokehTornado({'/bkapp': bkapp}, extra_websocket_origins=["xxx.xxx.xxx.xxx:5000"])

Если я сейчас захожу на страницу, которая использует этот сервер Bokeh, все работает нормально. Загружается

http://xxx.xxx.xxx.xxx:XXXXX/bkapp/autoload.js?bokeh-autoload-element=1001&bokeh-app-path=/bkapp&bokeh-absolute-url=http://xxx.xxx.xxx.xxx:XXXXX/bkapp&resources=none

и отображает графики, а также создает веб-сокет для обратных вызовов.


Это без Nginx в качестве обратного прокси. Я не хочу использовать IP-адрес веб-сервера, потому что мне нужно использовать HTTPS, для которого требуется домен.

Таким образом, у меня есть следующая конфигурация Nginx:

server {
    listen 80;
    server_name example.com;

    return 301 https://$server_name/;
}

server {
    listen 443;
    server_name example.com;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    client_max_body_size 50M;

    location / {
        include proxy_params;
        proxy_pass http://127.0.0.1:5000;
        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;
        proxy_buffering off;
    }

    location /static {
        alias /some/directory/to/flask/static;
    }
}

И я запускаю Flask через Gunicorn с

gunicorn --workers 9 --bind 127.0.0.1:5000 --timeout 120 --log-file /some/directory/to/gunicorn/logs/gunicorn.log -m 0700 flask:app

Теперь я могу получить доступ ко всему от Flask до https://example.com. flask_gunicorn_embed.py теперь выглядит как

script = server_document('https://example.com:%d/bkapp' % port, resources=None)
sockets, port = bind_sockets("0.0.0.0", 0)
bokeh_tornado = BokehTornado({'/bkapp': bkapp}, extra_websocket_origins=["example.com"])

Тем не менее, каждый запрос, который генерируется с помощью Bokeh server_document

https://example.com:XXXXX/bkapp/autoload.js?bokeh-autoload-element=1001&bokeh-app-path=/bkapp&bokeh-absolute-url=https://example.com:XXXXX/bkapp&resources=none

приводит к истечению тайм-аута или к соединению, отклоненному и, следовательно, к загрузке сценариев.


Как сделать так, чтобы он подключался и загружал скрипт?

Он должен быть как-то связан с Nginx, потому что если я запрашиваю файл через IP-адрес, он все равно работает (из-за bind_sockets("0.0.0.0", 0)). Но я не могу понять, что является причиной этой проблемы.


Edit:

Кажется, проблема в том, что он использует HTTPS. Моя конфигурация Nginx такая же, как приведенная в документации Bokeh . В документации сказано использовать --use_xheaders, что невозможно, потому что я не использую bokeh serve.

У меня есть

conf = {'use_xheaders': True}
bokeh_tornado = BokehTornado({'/bkapp': bkapp}, extra_websocket_origins=["example.com"], **conf)
bokeh_http = HTTPServer(bokeh_tornado, xheaders=True)

но он по-прежнему не загружает сценарии для страниц HTTPS.

http://example_no_https.com загружает страницы через порты, а https://example.com - нет.

1 Ответ

0 голосов
/ 12 мая 2019

use_xheaders - это аргумент для класса Bokeh Server (который передает его Торнадо HTTPServer), а не BokehTornado.Если вы не используете Server, потому что вы координируете BokehTornado и HTTPServer самостоятельно, то вам придется вручную настроить эту опцию на HTTP-сервере, поскольку у вас нет класса Server, выполняющего ее за вас:

http_server_kwargs.setdefault('xheaders', opts.use_xheaders)
HTTPServer(..., **http_server_kwargs)
...