我们使用 Flask 将用户路由到 Bokeh 服务器。系统在 Docker 映像中运行。一切正常。但是现在我们想要添加身份验证,这很困难,因为我们不想将散景服务器端口映射到客户端。
让我向您展示它当前的工作方式(无需身份验证):
烧瓶 app.py(路由):
...
@app.route('/folder/report_x')
def page_folder_report_x():
''' embedded bokeh server for report_x '''
script = server_document('http://localhost:5001/report_x')
resp = {
'title': 'Report X',
'script': script,
'template': 'Flask', }
return render_template('embed.html', **resp)
...
app.run(host='0.0.0.0', port=5000, use_reloader=False)
Flask embed.py(模板):
...
{% extends "base.html" %}
{% block content %}
{{ script|safe }}
{% endblock %}
...
Bokeh 服务器是从命令行使用 python 的 Panel 启动的(localhost:5000 代表 Flask 服务器):
panel serve report_x --port 5001 --allow-websocket-origin localhost:5000
Bokeh 服务器使用 main.ipynb 文件提供服务:
import panel as pn
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.models.widgets import Button, DataTable, PreText
from bokeh.models.widgets import TableColumn, NumberFormatter, DateFormatter
...
gspec = pn.GridSpec(sizing_mode='stretch_both')
gspec[0:12, 0:12] = pn.WidgetBox(widgets)
...
gspec.servable()
我们的 Docker 镜像暴露了烧瓶服务器和散景服务器的端口:
...
RUN pip install -r /app/requirements.txt
EXPOSE 5000:5000
EXPOSE 5001:5001
...
最后,当我们运行 docker 容器时,我们映射端口:
# success!
docker run -p 5000:5000 -p 5001:5001 report_server:0.1
如果我们以这种方式运行 docker 镜像,一切都会完美运行。
但是如果我们在没有映射散景服务器的情况下运行它,我们将无法访问散景服务器(即使它在内部公开,正如您在 DockerFile 中看到的那样):
# fail
docker run -p 5000:5000 report_server:0.1
出于安全考虑,我们只想将一个端口映射到外部世界。关于如何在 Flask 中嵌入 Bokeh 服务器,是否只允许 Flask 与 Bokeh 服务器通信,我们是否遗漏了什么?