[prev in list] [next in list] [prev in thread] [next in thread] 

List:       nginx
Subject:    Re: Re: Re :Re: Re:Reverse-proxying: Flask app with Bokeh server on Nginx
From:       J K via nginx <nginx () nginx ! org>
Date:       2017-05-24 6:34:19
Message-ID: CA+xC81F5imdw5qY0xDdnFhAEKiaV0jCsfZe_7cugMm7JCX64Jg () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


Hi Francis,

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: https://stackoverflow.
com/questions/43743029/reverse-proxying-flask-app-
with-bokeh-server-on-nginx/44150473#44150473

Thanks a lot for your help!

Cheers!


> Message: 3
> Date: Tue, 16 May 2017 17:49:07 +0100
> From: Francis Daly <francis@daoine.org>
> To: J K via nginx <nginx@nginx.org>
> Cc: J K <cas.xyz@googlemail.com>
> Subject: Re: Re :Re: Re:Reverse-proxying: Flask app with Bokeh server
>         on Nginx
> Message-ID: <20170516164907.GE10157@daoine.org>
> 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        francis@daoine.org
>
>
>

[Attachment #5 (text/html)]

<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&#39;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 &lt;<a \
                href="mailto:francis@daoine.org">francis@daoine.org</a>&gt;<br>
To: J K via nginx &lt;<a href="mailto:nginx@nginx.org">nginx@nginx.org</a>&gt;<br>
Cc: J K &lt;<a href="mailto:cas.xyz@googlemail.com">cas.xyz@googlemail.com</a>&gt;<br>
                
Subject: Re: Re :Re: Re:Reverse-proxying: Flask app with Bokeh server<br>
            on Nginx<br>
Message-ID: &lt;<a href="mailto:20170516164907.GE10157@daoine.org">20170516164907.GE10157@<wbr>daoine.org</a>&gt;<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 &quot;flask&quot; web server and a &quot;bokeh&quot; web server. \
You<br> put the &quot;flask&quot; 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 &quot;bokeh&quot; 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>
&gt; &gt; &gt;   3. in the Flask app, I changed the URL<br>
&gt; &gt; &gt; to:url=&#39;<a href="https://138.197.132.46:5006/bokeh/" \
rel="noreferrer" target="_blank">https://138.197.132.<wbr>46:5006/bokeh/</a>&#39;<br> \
<br> &gt; &gt; You can&#39;t mix &#39;https://&#39; and :5006 port   in same url - \
this way the<br> &gt; &gt; request<br>
&gt; &gt; goes to port 5006 but it expects to be also encrypted but if I \
understand<br> &gt; &gt; correctly bokeh doesn&#39;t support SSL.<br>
<br>
&gt; &gt; What I forgot to add you need to change the &#39;url&#39; (note the domain \
part)<br> &gt; &gt; to:<br>
&gt; &gt;<br>
&gt; &gt; url=&#39;<a href="https://yourdomain/bokeh/" rel="noreferrer" \
target="_blank">https://yourdomain/bokeh/</a><wbr>&#39;<br> &gt; &gt;<br>
&gt; &gt; by looking at your error messages it seems that the &#39;url&#39; is also \
directly<br> &gt; &gt; used for client requests (probably placed in the html \
templated) - which<br> &gt; &gt; means you can&#39;t use plain IP because then the \
browser most likely will just<br> &gt; &gt; generate a SSL certificate and domain \
mismatch.<br> <br>
&gt; Thanks for answering again.<br>
&gt;<br>
&gt; I followed your advise and change the Flask app script so that I have one<br>
&gt; URL to pull the Bokeh session and another one to create the HTML script:<br>
&gt;<br>
&gt; def company_abc():<br>
&gt;<br>
&gt; url=&#39;<a href="http://127.0.0.1:5006/bokeh" rel="noreferrer" \
target="_blank">http://127.0.0.1:5006/<wbr>bokeh</a>&#39;<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>
&gt; session=pull_session(url=url,<wbr>app_path=&quot;/company_abc&quot;)<br>
&gt;<br>
&gt; url_https=&#39;<a href="https://www.example.com" rel="noreferrer" \
target="_blank">https://www.<wbr>example.com</a>&#39;<br> <br>
Same question. What is the purpose of that? Which of (browser, flask,<br>
bokeh) will try to use it?<br>
<br>
&gt; &gt; &gt;                              proxy_pass <a \
href="http://127.0.0.1:5006" rel="noreferrer" \
target="_blank">http://127.0.0.1:5006</a>;   # you suggested<br> &gt; &gt; 127.0.<br>
&gt; &gt; &gt; *1*.1, but I figured that was a typo<br>
&gt; &gt;<br>
&gt; &gt; The proxy_pass address should be wherever your &quot;bokeh&quot; http \
server is<br> &gt; &gt; actually listening.<br>
&gt; &gt;<br>
&gt; &gt; Which probably means that whatever you use up there...<br>
&gt; &gt;<br>
&gt; &gt; &gt; command=/opt/envs/virtual/bin/<wbr>bokeh serve company_abc.py \
company_xyz.py<br> &gt; &gt; &gt; geomorphix.py --prefix=/bokeh/ \
--allow-websocket-origin=<a href="http://www.example.com" rel="noreferrer" \
target="_blank">www.<wbr>example.com</a><br> &gt; &gt; &gt; \
--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> &gt; &gt; &gt; \
--use-xheaders<br> &gt; &gt;<br>
&gt; &gt; you should also use up there as --host.<br>
&gt; &gt;<br>
&gt; &gt; I suspect that making them both be 127.0.0.1 will be the easiest<br>
&gt; &gt; way of reverse-proxying things; but I also suspect that the<br>
&gt; &gt; &quot;--allow-websocket-origin&quot; part suggests that you may want to \
configure<br> &gt; &gt; nginx to reverse proxy the web socket connection too. Notes \
are at<br> &gt; &gt; <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>
 &gt; &gt;<br>
&gt; &gt; It will be helpful to have a very clear picture of what talks to what,<br>
&gt; &gt; when things are working normally; that should make it easier to be<br>
&gt; &gt; confident that the same links are in place with nginx in the mix.<br>
<br>
&gt; As you suggested, I did the following:<br>
&gt;<br>
&gt; 1. in &#39;/etc/supervisor/conf.d/bokeh_<wbr>serve.conf&#39; I changed the host \
to<br> &gt; <a href="http://127.0.0.1" rel="noreferrer" \
target="_blank">127.0.0.1</a>:<br> &gt;<br>
&gt; [program:bokeh_serve]<br>
&gt;<br>
&gt; command=/opt/envs/virtual/bin/<wbr>bokeh serve company_abc.py \
--prefix=/bokeh/<br> &gt; --allow-websocket-origin=<a href="http://www.example.com" \
rel="noreferrer" target="_blank">www.<wbr>example.com</a> \
--allow-websocket-origin=<br> &gt; <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> &lt;<a \
href="http://138.197.132.46:5006/" rel="noreferrer" \
target="_blank">http://138.197.132.46:5006/</a>&gt;<br> &gt;   --use-xheaders<br>
<br>
What is &quot;--allow-websocket-origin&quot; 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>
&gt; 2. I configure nginx to reverse proxy the web socket connection by adding<br>
&gt; the following lines to each location block in \
&#39;/etc/nginx/sites-available/<br> &gt; default&#39;:<br>
<br>
That may or may not be needed in &quot;each location&quot;. Maybe it is only \
needed<br> in the &quot;bokeh&quot; location; the intended data flow diagram will \
show how<br> things should be configured.<br>
<br>
&gt; 3. In the Flask web app code I changed the URL of the route accordingly to<br>
&gt; <a href="http://127.0.0.1" rel="noreferrer" target="_blank">127.0.0.1</a>:<br>
&gt;<br>
&gt; @app.route(&quot;/company_abc/&quot;)<br>
&gt;<br>
&gt; @login_required<br>
&gt;<br>
&gt; @roles_accepted(&#39;company_abc&#39;, &#39;admin&#39;)<br>
&gt;<br>
&gt; def geomorphix():<br>
&gt;<br>
&gt;        url=&#39;<a href="http://127.0.0.1:5006/bokeh" rel="noreferrer" \
target="_blank">http://127.0.0.1:5006/<wbr>bokeh</a>&#39;<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>
&gt; When I enter the website with the Bokeh script in my browser, I get a<br>
&gt; connection refused error:<br>
&gt;<br>
&gt; 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>
 &gt; 9cf799610fb8&amp;bokeh-session-id=<wbr>8tvMFfJwtVFccTctGHIRPPsT3h6IF6<wbr>nUFkJ8l6ZQALXl<br>
 &gt; net::ERR_CONNECTION_REFUSED<br>
<br>
That makes it look like the &quot;url=&quot; 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 &quot;url=&#39;/bokeh&#39;&quot; 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/boke \
h-<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>



_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic