Hi Francis, Initially, without https, everything was running well. I was deploying a Bokeh server with the 'company_abc' app, and used a Flask app to render the website and handle login/redirecting/etc. Everything was behind a Nginx server.
Then, I installed https the Bokeh app would not be rendered on the website. The Flask app worked fine, as before. I think what's happening is that Nginx sends a request to the Flask app. Flask then pulls the Bokeh session with session=pull_session <http://bokeh.pydata.org/en/0.12.4/docs/reference/client.html#bokeh.client.session.pull_session> (url=url,app_path="/company_abc") and creates a script tag with bokeh_script=autoload_server <http://bokeh.pydata.org/en/latest/docs/reference/embed.html#bokeh.embed.autoload_server> (None,app_path="/company_abc/",session_id=session.id,url=url_https) That's then embedded into the html page by return render_template("company_abc.html", bokeh_script=bokeh_script) The script tag looks like this: <script src="https://example.com/company_abc/autoload.js?bokeh- autoload-element=c5c9bdb5-40e8-46a2-9bf0-40a9d396ce97" id="c5c9bdb5-40e8-46a2-9bf0-40a9d396ce97" data-bokeh-model-id="" data-bokeh-doc-id="" ></script> Now, when the browser opens the 'company_abc.html' page it sends a request to the Nginx server. This should then proxy to the Bokeh server. Does this sound correct? Now, I have done some changes and get a different error. The Bokeh app I'm starting now with bokeh serve company_abc.py --allow-websocket-origin=example.com --allow-websocket-origin=www.example.com --port=5006 \ --host="*" --use-xheaders So, it's running on localhost, port 5006. In the Flask app I redefined the route to the app as follows: @app.route("/company_abc/") def company_abc(): url='http://127.0.0.1:5006/' session=pull_session(url=url,app_path="/company_abc") url_https='https://example.com/' bokeh_script=autoload_server(None,app_path="/company_abc/",session_id= session.id,url=url_https) return render_template("company_abc.html", bokeh_script=bokeh_script) For the Nginx config file I followed the template from the Bokeh User Guide <http://bokeh.pydata.org/en/latest/docs/user_guide/server.html#reverse-proxying-with-nginx-and-ssl> : location /company_abc/ { proxy_pass http://127.0.0.1:5006; 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; } } Now, with these setting I get the following errors in Chrome: GET https://example.com/static/css/bokeh.min.css?v= 7246afcfffc127faef7c138bce4742e9 example.com/:9 GET https://example.com/static/css/bokeh-widgets.min.css?v= d9cb9322d940f107727b091ff98d9c70 example.com/:12 GET https://example.com/static/js/bokeh-widgets.min.js?v= 1af1302b8bd7fcc88c7bcafb8771497b example.com/:11 GET https://example.com/static/js/bokeh.min.js?v= 9d3af13f493d36073a89714f6a5240c6 example.com/:12 GET https://example.com/static/js/bokeh-widgets.min.js?v= 1af1302b8bd7fcc88c7bcafb8771497b 404 (NOT FOUND) (index):14 Uncaught ReferenceError: Bokeh is not defined at (index):14 (anonymous) @ (index):14 (index):37 Uncaught ReferenceError: Bokeh is not defined at HTMLDocument.fn ((index):37) The log file for the Bokeh server shows no errors: 2017-05-17 10:17:49,640 Starting Bokeh server version 0.12.4 2017-05-17 10:17:49,641 Host wildcard '*' can expose the application to HTTP host header attacks. Host wildcard should only be used for testing purpose. 2017-05-17 10:17:49,647 Starting Bokeh server on port 5006 with applications at paths ['/geomorphix'] 2017-05-17 10:17:49,647 Starting Bokeh server with process id: 15851 2017-05-17 10:18:08,829 200 GET /geomorphix/ (37.201.192.96) 845.69ms Interestingly, when I manually execute the lines url='http://127.0.0.1:5006/' session=pull_session(url=url,app_path="/company_abc") url_https='https://example.com/' bokeh_script=autoload_server(None,app_path="/company_abc/",session_id= session.id,url=url_https) The Bokeh log file says that a WebSocket is opened and a ServerConnection is created: 2017-05-17 10:21:09,915 WebSocket connection opened 2017-05-17 10:21:10,769 ServerConnection created What does the new error mean? Why is a WebSocket opened and ServerConnection created only when I manually pull a session? Thanks! Message: 3 > Date: Tue, 16 May 2017 17:49:07 +0100 > From: Francis Daly <[email protected]> > To: J K via nginx <[email protected]> > Cc: J K <[email protected]> > Subject: Re: Re :Re: Re:Reverse-proxying: Flask app with Bokeh server > on Nginx > Message-ID: <[email protected]> > Content-Type: text/plain; charset=utf-8 > > On Mon, May 15, 2017 at 11:59:27AM +0200, J K via nginx wrote: > > Hi there, > > To recap: > > you had installed a "flask" web server and a "bokeh" web server. You > put the "flask" one behind nginx, so that clients would talk to nginx > and to bokeh. > > And the clients were happy to talk http to nginx and http to bokeh. > > Then you enabled https on nginx, so that clients would talk https to > nginx and http to bokeh. > > And the clients did not want to talk http to bokeh after talking https > to nginx. > > So right now, you are trying to put the "bokeh" web server behind > nginx too. > > There are various ips and ports and url prefixes that appear in various > configuration files; it is worth making sure that you are very clear on > what each one is for. That will make it possible to see what needs to > be done to put bokeh behind nginx. > > > > > > 3. in the Flask app, I changed the URL > > > > to:url='https://138.197.132.46:5006/bokeh/' > > > > You can't mix 'https://' and :5006 port in same url - this way the > > > request > > > goes to port 5006 but it expects to be also encrypted but if I > understand > > > correctly bokeh doesn't support SSL. > > > > What I forgot to add you need to change the 'url' (note the domain > part) > > > to: > > > > > > url='https://yourdomain/bokeh/' > > > > > > by looking at your error messages it seems that the 'url' is also > directly > > > used for client requests (probably placed in the html templated) - > which > > > means you can't use plain IP because then the browser most likely will > just > > > generate a SSL certificate and domain mismatch. > > > Thanks for answering again. > > > > I followed your advise and change the Flask app script so that I have one > > URL to pull the Bokeh session and another one to create the HTML script: > > > > def company_abc(): > > > > url='http://127.0.0.1:5006/bokeh' > > So: what is that url for? > > Is it a thing that the client web browser will try to access, or a thing > that something internal to flask will try to access, or a thing that > something internal to bokeh will try to access? > > When you can say what it is, then it may become clear what value it > should have. > > > session=pull_session(url=url,app_path="/company_abc") > > > > url_https='https://www.example.com' > > Same question. What is the purpose of that? Which of (browser, flask, > bokeh) will try to use it? > > > > > proxy_pass http://127.0.0.1:5006; # you > suggested > > > 127.0. > > > > *1*.1, but I figured that was a typo > > > > > > The proxy_pass address should be wherever your "bokeh" http server is > > > actually listening. > > > > > > Which probably means that whatever you use up there... > > > > > > > command=/opt/envs/virtual/bin/bokeh serve company_abc.py > company_xyz.py > > > > geomorphix.py --prefix=/bokeh/ --allow-websocket-origin=www. > example.com > > > > --allow-websocket-origin=example.com --host=138.197.132.46:5006 > > > > --use-xheaders > > > > > > you should also use up there as --host. > > > > > > I suspect that making them both be 127.0.0.1 will be the easiest > > > way of reverse-proxying things; but I also suspect that the > > > "--allow-websocket-origin" part suggests that you may want to configure > > > nginx to reverse proxy the web socket connection too. Notes are at > > > http://nginx.org/en/docs/http/websocket.html > > > > > > It will be helpful to have a very clear picture of what talks to what, > > > when things are working normally; that should make it easier to be > > > confident that the same links are in place with nginx in the mix. > > > As you suggested, I did the following: > > > > 1. in '/etc/supervisor/conf.d/bokeh_serve.conf' I changed the host to > > 127.0.0.1: > > > > [program:bokeh_serve] > > > > command=/opt/envs/virtual/bin/bokeh serve company_abc.py > --prefix=/bokeh/ > > --allow-websocket-origin=www.example.com --allow-websocket-origin= > > example.com --host=127.0.0.1:5006 <http://138.197.132.46:5006/> > > --use-xheaders > > What is "--allow-websocket-origin" for? Is it causing any breakage here? > > (Can you temporarily run with all websocket origins allowed, until > things work; and then add back the restrictions to confirm that things > still work?) > > > 2. I configure nginx to reverse proxy the web socket connection by adding > > the following lines to each location block in > '/etc/nginx/sites-available/ > > default': > > That may or may not be needed in "each location". Maybe it is only needed > in the "bokeh" location; the intended data flow diagram will show how > things should be configured. > > > 3. In the Flask web app code I changed the URL of the route accordingly > to > > 127.0.0.1: > > > > @app.route("/company_abc/") > > > > @login_required > > > > @roles_accepted('company_abc', 'admin') > > > > def geomorphix(): > > > > url='http://127.0.0.1:5006/bokeh' > > Same question as above: is that something that flask uses, or something > that the web browser uses? > > Because the web browser will fail to access http://127.0.0.1:5006/ > > > When I enter the website with the Bokeh script in my browser, I get a > > connection refused error: > > > > GET http://127.0.0.1:5006/bokeh/example/autoload.js?bokeh- > autoload-element=? > > 9cf799610fb8&bokeh-session-id=8tvMFfJwtVFccTctGHIRPPsT3h6IF6 > nUFkJ8l6ZQALXl > > net::ERR_CONNECTION_REFUSED > > That makes it look like the "url=" is something that the web browser uses. > > The web browser should only be accessing your https://nginx-server > service, so urls that the web browser will use should refer to that. > > Possibly "url='/bokeh'" will Just Work for you. > > You mentioned the bokeh documentation at > > http://bokeh.pydata.org/en/latest/docs/user_guide/server. > html#reverse-proxying-with-nginx-and-ssl > > and another link at > > http://stackoverflow.com/questions/38081389/bokeh- > server-reverse-proxying-with-nginx-gives-404/38505205#38505205 > > in your first mail. Does your current nginx configuration resemble either > of those? > > Good luck with it, > > f > -- > Francis Daly [email protected] > >
_______________________________________________ nginx mailing list [email protected] http://mailman.nginx.org/mailman/listinfo/nginx
