<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Message: 4<br>
Date: Fri, 12 May 2017 18:26:39 +0300<br>
From: "Reinis Rozitis" <<a href="mailto:r@roze.lv">r@roze.lv</a>><br>
To: <<a href="mailto:nginx@nginx.org">nginx@nginx.org</a>><br>
Subject: Re: Re:Reverse-proxying: Flask app with Bokeh server on Nginx<br>
Message-ID: <<wbr>437D05EFD1A24D9292CCE7BE45B212<wbr>7C@Neiroze><br>
Content-Type: text/plain; format=flowed; charset="UTF-8";<br>
        reply-type=original<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>
> Now, when I open the app in the browser I get a 502 Bad Gateway, and the<br>
> Flask log file says the following:<br>
> raise IOError("Cannot pull session document because we failed to connect<br>
> to the server (to start the server, try the 'bokeh serve' command)")<br>
<br>
Well seems that the Flask app uses the url also for background requests.<br>
<br>
You can't mix 'https://' and :5006 port  in same url - this way the 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>
<br>
p.s. for best performance you could tweak that the Flask->bokeh requests go<br>
through http but for the html template/output sent to clients there is<br>
another variable or relative paths.<br>
<br>
<br>
rr<br>
<br>
<br>
<br>
------------------------------<br>
<br>
Message: 5<br>
Date: Fri, 12 May 2017 18:33:47 +0300<br>
From: "Reinis Rozitis" <<a href="mailto:r@roze.lv">r@roze.lv</a>><br>
To: <<a href="mailto:nginx@nginx.org">nginx@nginx.org</a>><br>
Subject: Re: Re:Reverse-proxying: Flask app with Bokeh server on Nginx<br>
Message-ID: <<wbr>24A35BED74E7436B9515F58950D010<wbr>34@Neiroze><br>
Content-Type: text/plain; format=flowed; charset="UTF-8";<br>
        reply-type=original<br>
<br>
What I forgot to add you need to change the 'url' (note the domain part) 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>
<br>
rr<br> </blockquote><div><br></div><div>Thanks for answering again.</div><div><br></div><div>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:</div></div></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><div><font face="monospace, monospace">def company_abc():</font></div></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><div><font face="monospace, monospace">url='<a href="http://127.0.0.1:5006/bokeh">http://127.0.0.1:5006/bokeh</a>'</font></div></div></div></div></blockquote></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><div><font face="monospace, monospace">session=pull_session(url=url,app_path="/</font><span style="font-family:monospace,monospace">company_abc</span><font face="monospace, monospace">")</font></div></div></div></div></blockquote></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><div><span style="font-family:monospace,monospace">url_https='<a href="https://www.example.com">https://www.example.com</a></span><span style="font-family:monospace,monospace">'</span></div></div></div></div></blockquote></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><span style="font-family:monospace,monospace">bokeh_script=autoload_server(None,app_path="/</span><span style="font-family:monospace,monospace">company_abc</span><span style="font-family:monospace,monospace">",session_id=<a href="http://session.id">session.id</a>,url=url_https)</span></div></div></div></blockquote></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><div><font face="monospace, monospace">return render_template("</font><span style="font-family:monospace,monospace">company_abc</span><font face="monospace, monospace">.html", bokeh_script=bokeh_script)</font></div></div></div></div></blockquote></blockquote><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div>This, however, results in the following error in Chrome:</div></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">GET <a href="https://www.geomorphix.net/geomorphix/autoload.js?bokeh-autoload-element=dd">https://www.geomorphix.net/geomorphix/autoload.js?bokeh-autoload-element=dd</a>…6035f61fef5e&bokeh-session-id=hLR9QX79ofSg4yu7DZb1oHFdT14Ai7EcVCyh1iArcBf5 </font></div></div></div></blockquote><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace"><br></font></div><div><font face="arial, helvetica, sans-serif">There's no other explanation. Both, Flask and Bokeh, log files don't contain error messages.</font></div></div></div><div class="gmail_extra"><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> <br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
------------------------------<br>
<br>
Message: 6<br>
Date: Fri, 12 May 2017 21:46:30 +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: Reverse-proxying: Flask app with Bokeh server on Nginx<br>
Message-ID: <<a href="mailto:20170512204630.GC10157@daoine.org">20170512204630.GC10157@<wbr>daoine.org</a>><br>
Content-Type: text/plain; charset=us-ascii<br>
<br>
On Fri, May 12, 2017 at 04:28:12PM +0200, J K via nginx wrote:<br>
<br>
Hi there,<br>
<br>
> > location /bokeh/ {<br>
> >     proxy_pass <a href="http://127.0.1.1:5006" rel="noreferrer" target="_blank">http://127.0.1.1:5006</a>;<br>
> ><br>
> >     # .. with the rest of directives<br>
> > }<br>
> ><br>
> > relaunch the Bokeh app with<br>
> ><br>
> > --prefix=/bokeh/<br>
> ><br>
> > and (if takes part in the url construction rather than application<br>
> > background requests) change the url variable in the Flask app<br>
> ><br>
> > url='http://###.###.###.##:<wbr>5006'<br>
> > to<br>
> > url='<a href="https://yourserver/bokeh/" rel="noreferrer" target="_blank">https://yourserver/bokeh/</a><wbr>'<br>
<br>
> 1. in '/etc/nginx/sites-available/<wbr>default' I added a new location as follow:<br>
><br>
> location /bokeh/ {<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 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></blockquote><div> </div><div><span style="font-size:12.8px">Hi Francis,</span><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Thanks for your answer!</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">As you suggested, I did the following:</div><blockquote style="font-size:12.8px;margin:0px 0px 0px 40px;border:none;padding:0px">1. in '/etc/supervisor/conf.d/bokeh_<span style="font-size:12.8px"><wbr>serve.conf' I changed the host to <a href="http://127.0.0.1/" target="_blank">127.0.0.1</a>:</span></blockquote><blockquote style="font-size:12.8px;margin:0px 0px 0px 40px;border:none;padding:0px"><div><blockquote style="font-size:12.8px;margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace, monospace">[program:bokeh_serve]</font></blockquote></div><div><blockquote style="font-size:12.8px;margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace, monospace">command=/opt/envs/virtual/bin/<wbr>bokeh serve company_abc.py --prefix=/bokeh/ --allow-websocket-origin=<a href="http://www.example.com/" target="_blank">www.e<wbr>xample.com</a> --allow-websocket-<wbr>origin=<a href="http://example.com/" target="_blank">example.com</a> --host=<a href="http://138.197.132.46:5006/" target="_blank">127.<wbr>0.0.1:5006</a> --use-xheaders</font></blockquote></div><span class="gmail-im"><div><span class="gmail-m_5412624857913668013gmail-im" style="font-size:12.8px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace, monospace">directory=/opt/webapps/flask_t<wbr>elemetry</font></blockquote></span></div><div><span class="gmail-m_5412624857913668013gmail-im" style="font-size:12.8px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace, monospace">autostart=false</font></blockquote></span></div><div><span class="gmail-m_5412624857913668013gmail-im" style="font-size:12.8px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace, monospace">autorestart=true</font></blockquote></span></div><div><span class="gmail-m_5412624857913668013gmail-im" style="font-size:12.8px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace, monospace">startretries=3<br></font><span style="font-family:monospace,monospace;font-size:12.8px">user=nobody</span></blockquote></span></div></span></blockquote><blockquote style="font-size:12.8px;margin:0px 0px 0px 40px;border:none;padding:0px">2. I configure nginx to r<span style="font-size:12.8px">everse proxy the web socket connection by adding the following lines to each location block in </span><span style="font-size:12.8px">'/etc/nginx/sites-<wbr>available/</span><span style="font-size:12.8px">default':<br></span></blockquote><blockquote style="font-size:12.8px;margin:0px 0px 0px 40px;border:none;padding:0px"><span class="gmail-m_5412624857913668013gmail-im"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace, monospace"><span style="font-size:12.8px">proxy_http_version 1.1;</span><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote></font><span style="font-size:12.8px;font-family:monospace,monospace">proxy_set_header Upgrade $http_upgrade;<br></span><span style="font-family:monospace,monospace;font-size:12.8px">proxy_set_header Connection "upgrade";<br></span></blockquote></span></blockquote><blockquote style="font-size:12.8px;margin:0px 0px 0px 40px;border:none;padding:0px">3. In the Flask web app code I changed the URL of the route accordingly to <a href="http://127.0.0.1/" target="_blank">127.0.0.1</a>:</blockquote><blockquote style="font-size:12.8px;margin:0px 0px 0px 40px;border:none;padding:0px"><span class="gmail-im"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace, monospace">@app.route("/company_abc/")</font></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace, monospace">@login_required</font></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace, monospace">@roles_accepted('company_abc', 'admin')</font></blockquote></span><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace, monospace">def geomorphix():</font></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace, monospace">    url='<a href="http://127.0.0.1:5006/bokeh" target="_blank">http://127.0.0.1:5006/<wbr>bokeh</a>'</font></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace, monospace">    session=pull_session(url=url,<wbr>app_path="/company_abc")</font></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace, monospace">    bokeh_script=autoload_server(<wbr>None,app_path="/geomorphix",<wbr>session_id=<a href="http://session.id/" target="_blank">session.id</a>,url=url)</font></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace, monospace">    return render_template("geomorphix.<wbr>html", bokeh_script=bokeh_script)</font></blockquote></blockquote><blockquote style="font-size:12.8px;margin:0px 0px 0px 40px;border:none;padding:0px"><br></blockquote><span style="font-size:12.8px">When I enter the website with the Bokeh script in my browser, I get a connection refused error:</span><blockquote style="font-size:12.8px;margin:0px 0px 0px 40px;border:none;padding:0px"><div><font face="monospace, monospace">GET <a href="http://127.0.0.1:5006/bokeh/example/autoload.js?bokeh-autoload-element=" target="_blank">http://127.0.0.1:5006/bokeh/<wbr>example/autoload.js?bokeh-<wbr>autoload-element=</a>…<wbr>9cf799610fb8&bokeh-session-id=<wbr>8tvMFfJwtVFccTctGHIRPPsT3h6IF6<wbr>nUFkJ8l6ZQALXl net::ERR_CONNECTION_REFUSED</font></div><div><font face="monospace, monospace"><br></font></div></blockquote><font face="monospace, monospace" style="font-size:12.8px">Looking at the log file of the Bokeh server, everything seems to be fine:</font><blockquote style="font-size:12.8px;margin:0px 0px 0px 40px;border:none;padding:0px"><div><font face="monospace, monospace">2017-05-15 08:56:19,267 Starting Bokeh server version 0.12.4</font></div><div><font face="monospace, monospace">2017-05-15 08:56:19,276 Starting Bokeh server on port 5006 with applications at paths ['/company_abc']</font></div><div><font face="monospace, monospace">2017-05-15 08:56:19,276 Starting Bokeh server with process id: 28771</font></div><div><font face="monospace, monospace">2017-05-15 08:56:24,530 WebSocket connection opened</font></div><div><font face="monospace, monospace"><div>2017-05-15 08:56:25,304 ServerConnection created</div><div><br></div></font></div></blockquote><font face="arial, helvetica, sans-serif" style="font-size:12.8px">Also the Flask log file shows no error:</font><blockquote style="font-size:12.8px;margin:0px 0px 0px 40px;border:none;padding:0px"><div><font face="monospace, monospace">[2017-05-15 08:56:13 +0000] [28760] [INFO] Starting gunicorn 19.6.0</font></div><div><font face="monospace, monospace">[2017-05-15 08:56:13 +0000] [28760] [INFO] Listening at: <a href="http://0.0.0.0:8118/" target="_blank">http://0.0.0.0:8118</a> (28760)</font></div><div><font face="monospace, monospace">[2017-05-15 08:56:13 +0000] [28760] [INFO] Using worker: sync</font></div><div><font face="monospace, monospace">[2017-05-15 08:56:13 +0000] [28765] [INFO] Booting worker with pid: 28765</font></div></blockquote><font face="arial, helvetica, sans-serif" style="font-size:12.8px"><div><font face="arial, helvetica, sans-serif"><br></font></div><br></font><div style="font-size:12.8px"><font face="arial, helvetica, sans-serif">The Nginx error log '/var/log/nginx/flask/error.<wbr>log' is empty.</font></div></div></div></div></div>