У меня есть приложение 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 - нет.