We're using Flask to route users to Bokeh servers. The system is running inside a Docker image. Everything works well. But now we want to add authentication, which is proving difficult because we don't want to map the bokeh server ports to the client.
Let me show you how it's currently working (without authentication):
Flask app.py (routing):
...
@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 (template):
...
{% extends "base.html" %}
{% block content %}
{{ script|safe }}
{% endblock %}
...
Bokeh server is started using python's Panel from the commandline (localhost:5000 represents the Flask server):
panel serve report_x --port 5001 --allow-websocket-origin localhost:5000
The Bokeh server is served up using a main.ipynb file:
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()
Our Docker image exposes the ports of the flask server, and the bokeh server(s):
...
RUN pip install -r /app/requirements.txt
EXPOSE 5000:5000
EXPOSE 5001:5001
...
Lastly, when we run the docker container we map the ports:
# success!
docker run -p 5000:5000 -p 5001:5001 report_server:0.1
If we run the docker image this way everything works perfectly.
But if we run it without mapping the bokeh server, we can't reach the bokeh server (even though it's internally exposed as you can see in the DockerFile):
# fail
docker run -p 5000:5000 report_server:0.1
For security purposes, we only want to map one port to the outside world. Is there something we're missing about how to embed Bokeh servers in Flask that would allow only Flask to talk to the Bokeh server?