<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><span style="font-size:12.8px">Hi Francis,</span><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">you set me on the right track and I developed the solution. I differentiate the name of the Bokeh app (now company_abc-app) and the user (company_abc) and then created a location in the Nginx config file for the Bokeh app, specifically. Everything else goes through Flask, if it's not static. I posted the full source code here: <a href="https://stackoverflow.com/questions/43743029/reverse-proxying-flask-app-with-bokeh-server-on-nginx/44150473#44150473" target="_blank">https://stackoverflow.<wbr>com/questions/43743029/<wbr>reverse-proxying-flask-app-<wbr>with-bokeh-server-on-nginx/<wbr>44150473#44150473</a></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Thanks a lot for your help!</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Cheers!</div></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Message: 3<br>
Date: Tue, 16 May 2017 17:49:07 +0100<br>
From: Francis Daly <<a href="mailto:francis@daoine.org">francis@daoine.org</a>><br>
To: J K via nginx <<a href="mailto:nginx@nginx.org">nginx@nginx.org</a>><br>
Cc: J K <<a href="mailto:cas.xyz@googlemail.com">cas.xyz@googlemail.com</a>><br>
Subject: Re: Re :Re: Re:Reverse-proxying: Flask app with Bokeh server<br>
        on Nginx<br>
Message-ID: <<a href="mailto:20170516164907.GE10157@daoine.org">20170516164907.GE10157@<wbr>daoine.org</a>><br>
Content-Type: text/plain; charset=utf-8<br>
<br>
On Mon, May 15, 2017 at 11:59:27AM +0200, J K via nginx wrote:<br>
<br>
Hi there,<br>
<br>
To recap:<br>
<br>
you had installed a "flask" web server and a "bokeh" web server. You<br>
put the "flask" one behind nginx, so that clients would talk to nginx<br>
and to bokeh.<br>
<br>
And the clients were happy to talk http to nginx and http to bokeh.<br>
<br>
Then you enabled https on nginx, so that clients would talk https to<br>
nginx and http to bokeh.<br>
<br>
And the clients did not want to talk http to bokeh after talking https<br>
to nginx.<br>
<br>
So right now, you are trying to put the "bokeh" web server behind<br>
nginx too.<br>
<br>
There are various ips and ports and url prefixes that appear in various<br>
configuration files; it is worth making sure that you are very clear on<br>
what each one is for. That will make it possible to see what needs to<br>
be done to put bokeh behind nginx.<br>
<br>
<br>
> > >  3. in the Flask app, I changed the URL<br>
> > > to:url='<a href="https://138.197.132.46:5006/bokeh/" rel="noreferrer" target="_blank">https://138.197.132.<wbr>46:5006/bokeh/</a>'<br>
<br>
> > You can't mix 'https://' and :5006 port  in same url - this way the<br>
> > request<br>
> > goes to port 5006 but it expects to be also encrypted but if I understand<br>
> > correctly bokeh doesn't support SSL.<br>
<br>
> > What I forgot to add you need to change the 'url' (note the domain part)<br>
> > to:<br>
> ><br>
> > url='<a href="https://yourdomain/bokeh/" rel="noreferrer" target="_blank">https://yourdomain/bokeh/</a><wbr>'<br>
> ><br>
> > by looking at your error messages it seems that the 'url' is also directly<br>
> > used for client requests (probably placed in the html templated) - which<br>
> > means you can't use plain IP because then the browser most likely will just<br>
> > generate a SSL certificate and domain mismatch.<br>
<br>
> Thanks for answering again.<br>
><br>
> I followed your advise and change the Flask app script so that I have one<br>
> URL to pull the Bokeh session and another one to create the HTML script:<br>
><br>
> def company_abc():<br>
><br>
> url='<a href="http://127.0.0.1:5006/bokeh" rel="noreferrer" target="_blank">http://127.0.0.1:5006/<wbr>bokeh</a>'<br>
<br>
So: what is that url for?<br>
<br>
Is it a thing that the client web browser will try to access, or a thing<br>
that something internal to flask will try to access, or a thing that<br>
something internal to bokeh will try to access?<br>
<br>
When you can say what it is, then it may become clear what value it<br>
should have.<br>
<br>
> session=pull_session(url=url,<wbr>app_path="/company_abc")<br>
><br>
> url_https='<a href="https://www.example.com" rel="noreferrer" target="_blank">https://www.<wbr>example.com</a>'<br>
<br>
Same question. What is the purpose of that? Which of (browser, flask,<br>
bokeh) will try to use it?<br>
<br>
> > >                    proxy_pass <a href="http://127.0.0.1:5006" rel="noreferrer" target="_blank">http://127.0.0.1:5006</a>;  # you suggested<br>
> > 127.0.<br>
> > > *1*.1, but I figured that was a typo<br>
> ><br>
> > The proxy_pass address should be wherever your "bokeh" http server is<br>
> > actually listening.<br>
> ><br>
> > Which probably means that whatever you use up there...<br>
> ><br>
> > > command=/opt/envs/virtual/bin/<wbr>bokeh serve company_abc.py company_xyz.py<br>
> > > geomorphix.py --prefix=/bokeh/ --allow-websocket-origin=<a href="http://www.example.com" rel="noreferrer" target="_blank">www.<wbr>example.com</a><br>
> > > --allow-websocket-origin=<a href="http://example.com" rel="noreferrer" target="_blank">examp<wbr>le.com</a> --host=<a href="http://138.197.132.46:5006" rel="noreferrer" target="_blank">138.197.132.46:5006</a><br>
> > > --use-xheaders<br>
> ><br>
> > you should also use up there as --host.<br>
> ><br>
> > I suspect that making them both be 127.0.0.1 will be the easiest<br>
> > way of reverse-proxying things; but I also suspect that the<br>
> > "--allow-websocket-origin" part suggests that you may want to configure<br>
> > nginx to reverse proxy the web socket connection too. Notes are at<br>
> > <a href="http://nginx.org/en/docs/http/websocket.html" rel="noreferrer" target="_blank">http://nginx.org/en/docs/http/<wbr>websocket.html</a><br>
> ><br>
> > It will be helpful to have a very clear picture of what talks to what,<br>
> > when things are working normally; that should make it easier to be<br>
> > confident that the same links are in place with nginx in the mix.<br>
<br>
> As you suggested, I did the following:<br>
><br>
> 1. in '/etc/supervisor/conf.d/bokeh_<wbr>serve.conf' I changed the host to<br>
> <a href="http://127.0.0.1" rel="noreferrer" target="_blank">127.0.0.1</a>:<br>
><br>
> [program:bokeh_serve]<br>
><br>
> command=/opt/envs/virtual/bin/<wbr>bokeh serve company_abc.py --prefix=/bokeh/<br>
> --allow-websocket-origin=<a href="http://www.example.com" rel="noreferrer" target="_blank">www.<wbr>example.com</a> --allow-websocket-origin=<br>
> <a href="http://example.com" rel="noreferrer" target="_blank">example.com</a> --host=<a href="http://127.0.0.1:5006" rel="noreferrer" target="_blank">127.0.0.1:5006</a> <<a href="http://138.197.132.46:5006/" rel="noreferrer" target="_blank">http://138.197.132.46:5006/</a>><br>
>  --use-xheaders<br>
<br>
What is "--allow-websocket-origin" for? Is it causing any breakage here?<br>
<br>
(Can you temporarily run with all websocket origins allowed, until<br>
things work; and then add back the restrictions to confirm that things<br>
still work?)<br>
<br>
> 2. I configure nginx to reverse proxy the web socket connection by adding<br>
> the following lines to each location block in '/etc/nginx/sites-available/<br>
> default':<br>
<br>
That may or may not be needed in "each location". Maybe it is only needed<br>
in the "bokeh" location; the intended data flow diagram will show how<br>
things should be configured.<br>
<br>
> 3. In the Flask web app code I changed the URL of the route accordingly to<br>
> <a href="http://127.0.0.1" rel="noreferrer" target="_blank">127.0.0.1</a>:<br>
><br>
> @app.route("/company_abc/")<br>
><br>
> @login_required<br>
><br>
> @roles_accepted('company_abc', 'admin')<br>
><br>
> def geomorphix():<br>
><br>
>     url='<a href="http://127.0.0.1:5006/bokeh" rel="noreferrer" target="_blank">http://127.0.0.1:5006/<wbr>bokeh</a>'<br>
<br>
Same question as above: is that something that flask uses, or something<br>
that the web browser uses?<br>
<br>
Because the web browser will fail to access <a href="http://127.0.0.1:5006/" rel="noreferrer" target="_blank">http://127.0.0.1:5006/</a><br>
<br>
> When I enter the website with the Bokeh script in my browser, I get a<br>
> connection refused error:<br>
><br>
> GET <a href="http://127.0.0.1:5006/bokeh/example/autoload.js?bokeh-autoload-element=" rel="noreferrer" target="_blank">http://127.0.0.1:5006/bokeh/<wbr>example/autoload.js?bokeh-<wbr>autoload-element=</a>?<br>
> 9cf799610fb8&bokeh-session-id=<wbr>8tvMFfJwtVFccTctGHIRPPsT3h6IF6<wbr>nUFkJ8l6ZQALXl<br>
> net::ERR_CONNECTION_REFUSED<br>
<br>
That makes it look like the "url=" is something that the web browser uses.<br>
<br>
The web browser should only be accessing your <a href="https://nginx-server" rel="noreferrer" target="_blank">https://nginx-server</a><br>
service, so urls that the web browser will use should refer to that.<br>
<br>
Possibly "url='/bokeh'" will Just Work for you.<br>
<br>
You mentioned the bokeh documentation at<br>
<br>
<a href="http://bokeh.pydata.org/en/latest/docs/user_guide/server.html#reverse-proxying-with-nginx-and-ssl" rel="noreferrer" target="_blank">http://bokeh.pydata.org/en/<wbr>latest/docs/user_guide/server.<wbr>html#reverse-proxying-with-<wbr>nginx-and-ssl</a><br>
<br>
and another link at<br>
<br>
<a href="http://stackoverflow.com/questions/38081389/bokeh-server-reverse-proxying-with-nginx-gives-404/38505205#38505205" rel="noreferrer" target="_blank">http://stackoverflow.com/<wbr>questions/38081389/bokeh-<wbr>server-reverse-proxying-with-<wbr>nginx-gives-404/38505205#<wbr>38505205</a><br>
<br>
in your first mail. Does your current nginx configuration resemble either<br>
of those?<br>
<br>
Good luck with it,<br>
<br>
        f<br>
--<br>
Francis Daly        <a href="mailto:francis@daoine.org">francis@daoine.org</a><br>
<br>
<br></blockquote></div></div></div>