Reverse-proxying: Flask app with Bokeh server on Nginx

J K cas.xyz at googlemail.com
Wed May 24 06:34:19 UTC 2017


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 at daoine.org>
> To: J K via nginx <nginx at nginx.org>
> Cc: J K <cas.xyz at googlemail.com>
> Subject: Re: Re :Re: Re:Reverse-proxying: Flask app with Bokeh server
>         on Nginx
> Message-ID: <20170516164907.GE10157 at 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 at daoine.org
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx/attachments/20170524/89d4d432/attachment-0001.html>


More information about the nginx mailing list