running multiple apps with Apache web server under subdirectory paths

I’m new to Bokeh and I’m trying to run multiple apps in one directory, like the demo site:

  1. http://demo.bokehplots.com/apps/movies
  2. http://demo.bokehplots.com/apps/selection_histogram
  3. http://demo.bokehplots.com/apps/weather
    First I’ll introduce the enviroment of the server I’m using. I’m running a RedHat 6.4 x86_64 with Apache 2.2.15, MySQL 5.1.73, and Anaconda 2.4 (Python 2.7, Bokeh 0.11.1). I have direct access to the server (it belongs to my department) and it has its own IP address. The web server on port 80 hosts a WordPress blog mainly and serveral static HTML pages, for example, domain.url will direct to domain.url/blog/ and that’s the main WP page, there’re links to domain.url/visualization/processing/ and under processing there’re some Java applets of our visualization projects. These files and index pages are under /var/www/html/visualization/processing.

I’m trying to show bokeh apps in a similar ways. If a vistor goes to domain.url/visualization/bokeh_apps, a page will show up like demo.bokehplots.com, and then the vistor can click to domain.url/visualization/bokeh_apps/proj01, domain.url/visualization/bokeh_apps/proj02, etc. So I assume the Apache server needs to redirect to different bokeh apps on different ports when it recognize the URL path.

The first problem I ran into is the host whitelist. I ran the command:

[[email protected] bokeh_apps]$ bokeh serve --show myapp --port 5100 --host 127.0.0.1:80

A Window popped out and I had to quit the “Elinks”, and the output kept going:

INFO:bokeh.server.tornado:Rejected connection from host 'localhost:5100' because it is not in the --host whitelist
WARNING:tornado.access:403 GET /myapp (::1) 1.71ms
DEBUG:bokeh.server.tornado:[pid 834] 0 clients connected

I googled and all I can find is a GitHub issue page. I read it but don’t understand whether there’s a solution in the tornado.py.

The second problem is that I dont’ know how to construct the structure.

I tried

cd /var/www/html/visualization/bokeh_apps/
bokeh serve --show myapp --port 5100 --host 127.0.0.1:80/visualization/bokeh_apps/

and it returned “invalid port in host value”. When I run locally in Python bokeh serve --show myapp ,
the address is like “localhost:5006/myapp” and doesn’t show any structure. Is there some trick to do this? I searched but didn’t find anything.

Thanks a lot for your help!

P.S. if Nignx has the solution for these 2 problems, it’s still quite unlikely that my supervisor will agree to swtich from Apache…

Hi Hexin,

Nginx is definitely not a requirement. It was simply the case that Nginx happened to be the thing we were familiar with, that we could document well in the time constraints we had. It should definitely be possible to use Bokeh behind other front-ends, and in fact I would very much like to document how to do that.

Here's a few high-level requirements that might help:

* Bokeh server apps use websockets. Whatever is in front of the bokeh server needs to be configured to forward websocket traffic. In an Nginx config, you'd have something like:

  proxy_pass http://127.0.0.1:5100;
  proxy_set_header Upgrade $http_upgrade;
     proxy_set_header Connection "upgrade";
  proxy_http_version 1.1;

Where the ip/port there is the internal ip/port that you have started the bokeh server on. It looks like there is some information about configuring Apache to forward websockets here:

  http://stackoverflow.com/questions/27526281/websockets-and-apache-proxy-how-to-configure-mod-proxy-wstunnel

* Bokeh server needs to receive the "Host" field from the HTML request. Whatever is in front of the bokeh server needs to forward this. In Nginx, it looks like this:

  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $host:$server_port;

I'm not sure offhand what that looks like for Apache (I have not used Apache, maybe someone else on the list can chime in).

* The Bokeh server host whitelist needs to have the *public-facing* host added. So if users are navigating to "foo.com" then the server needs to be started with

  --host "foo.com"

This value is matched up with the "Host" that the proxy forwards on to the bokeh server. They have to match. This is to guard against certain kinds of malicious attacks that involve spoofing Host fields in requests.

* You can add multiple --host fields. If you also want to be able to connect from localhost (for testing or whatever) then you'd need to add that, explicitly. If you don't specify any --host at all, then bokeh server adds "localhost" as a default, but if you add *any* --host then the server *only* configures the --host values that are explicitly given (no more default "localhost"). But note: adding "localhost" to the --host is probably not something you would want to do "in production", where all access to the server should go through Nginx, or Apache, or whatever.

* All of this assumes you are not also using/needing SSL (https), which would require a few additional configurations for the bokeh server, and probably quite alot of additional configuration for Apache.

···

---------

For completeness, I will say that another possible option is to simply run the server publicly-facing and then embed directly from the server using iframes, but there are a number of disadvantages to this approach (e.g. there's no way to scale things if necessary).

Thanks,

Bryan

On Apr 18, 2016, at 2:33 AM, Hexin Chen <[email protected]> wrote:

I'm new to Bokeh and I'm trying to run multiple apps in one directory, like the demo site:

  • http://demo.bokehplots.com/apps/movies
  • http://demo.bokehplots.com/apps/selection_histogram
  • http://demo.bokehplots.com/apps/weather
First I'll introduce the enviroment of the server I'm using. I'm running a RedHat 6.4 x86_64 with Apache 2.2.15, MySQL 5.1.73, and Anaconda 2.4 (Python 2.7, Bokeh 0.11.1). I have direct access to the server (it belongs to my department) and it has its own IP address. The web server on port 80 hosts a WordPress blog mainly and serveral static HTML pages, for example, domain.url will direct to domain.url/blog/ and that's the main WP page, there're links to domain.url/visualization/processing/ and under processing there're some Java applets of our visualization projects. These files and index pages are under /var/www/html/visualization/processing.

I'm trying to show bokeh apps in a similar ways. If a vistor goes to domain.url/visualization/bokeh_apps, a page will show up like demo.bokehplots.com, and then the vistor can click to domain.url/visualization/bokeh_apps/proj01, domain.url/visualization/bokeh_apps/proj02, etc. So I assume the Apache server needs to redirect to different bokeh apps on different ports when it recognize the URL path.

The first problem I ran into is the host whitelist. I ran the command:

[[email protected] bokeh_apps]$ bokeh serve --show myapp --port 5100 --host 127.0.0.1:80
A Window popped out and I had to quit the "Elinks", and the output kept going:

INFO:bokeh.server.tornado:Rejected connection from host 'localhost:5100' because it is not in the --
host whitelist
WARNING
:tornado.access:403 GET /myapp (::1) 1.71ms

DEBUG
:bokeh.server.tornado:[pid 834] 0 clients connected
I googled and all I can find is a GitHub issue page. I read it but don't understand whether there's a solution in the tornado.py.

The second problem is that I dont' know how to construct the structure.

I tried

cd /var/www/html/visualization/bokeh_apps/

bokeh serve
--show myapp --port 5100 --host 127.0.0.1:80/visualization/bokeh_apps/
and it returned "invalid port in host value". When I run locally in Python bokeh serve --show myapp, the address is like "localhost:5006/myapp" and doesn't show any structure. Is there some trick to do this? I searched but didn't find anything.

Thanks a lot for your help!

P.S. if Nignx has the solution for these 2 problems, it's still quite unlikely that my supervisor will agree to swtich from Apache...

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bok[email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/0ff064a9-8d71-4a53-a409-05e5c5763fdd%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Hi Hexin,

Here is some more info that might help you further along. I apologize I can't provide a complete example, I have to prepare some talks this week.

Using the vhost block below, things *almost* work. It is not connecting the websocket. I gather this is because I have Apache 2.2 installed via OSX brew, and I think you need Apache >= 2.4 (or perhaps extra config with earlier versions) to enable websocket forwarding. I will have to leave figuring that out to you or someone else on the mailing list:

  <VirtualHost *:8080>
      ServerName localhost

      CustomLog "/Users/bryan/Sites/logs/project.dev-access_log" combined
      ErrorLog "/Users/bryan/Sites/logs/project.dev-error_log"

      # for a bokeh server running internally on port 5100
      ProxyPreserveHost On
      ProxyPass /app http://127.0.0.1:5100/sliders/
      ProxyPassReverse /app http://127.0.0.1:5100/sliders/

      <Directory />
          Order Allow,Deny
          Allow From All
          Options -Indexes
      </Directory>
  
      # better to copy BokehJS static files to your normal /static location like this,
      # but other configurations would be possible...

      Alias /static /Users/bryan/work/bokeh/bokeh/server/static
      <Directory /Users/bryan/work/bokeh/bokeh/server/static>
          # directives to effect the static directory
          Options +Indexes
      </Directory>

  </VirtualHost>

Then I ran bokeh server like this:

  bokeh serve --port 5100 --host localhost:8080 sliders.py

With all of this, the initial connection and static resources load fine, but the websocket does not connect. So that is the part to figure out.

Things you will want to change for your actual deploy:

* the --host should not be localhost:8080, it should be *whatever users will actually navigate to*, i.e. the host name of the public facing apache server
* if you want bokeh server to serve the static files instead of copying them too your normal /static location as part of your deploy, you probably want to add a --prefix

I look forward to hearing back about how this works out, and also adding a fully complete Apache example to the User's Guide when I can devote time to it.

Bryan

···

On Apr 18, 2016, at 11:04 AM, Bryan Van de Ven <[email protected]> wrote:

Hi Hexin,

Nginx is definitely not a requirement. It was simply the case that Nginx happened to be the thing we were familiar with, that we could document well in the time constraints we had. It should definitely be possible to use Bokeh behind other front-ends, and in fact I would very much like to document how to do that.

Here's a few high-level requirements that might help:

* Bokeh server apps use websockets. Whatever is in front of the bokeh server needs to be configured to forward websocket traffic. In an Nginx config, you'd have something like:

  proxy_pass http://127.0.0.1:5100;
  proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  proxy_http_version 1.1;

Where the ip/port there is the internal ip/port that you have started the bokeh server on. It looks like there is some information about configuring Apache to forward websockets here:

  http://stackoverflow.com/questions/27526281/websockets-and-apache-proxy-how-to-configure-mod-proxy-wstunnel

* Bokeh server needs to receive the "Host" field from the HTML request. Whatever is in front of the bokeh server needs to forward this. In Nginx, it looks like this:

  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $host:$server_port;

I'm not sure offhand what that looks like for Apache (I have not used Apache, maybe someone else on the list can chime in).

* The Bokeh server host whitelist needs to have the *public-facing* host added. So if users are navigating to "foo.com" then the server needs to be started with

  --host "foo.com"

This value is matched up with the "Host" that the proxy forwards on to the bokeh server. They have to match. This is to guard against certain kinds of malicious attacks that involve spoofing Host fields in requests.

* You can add multiple --host fields. If you also want to be able to connect from localhost (for testing or whatever) then you'd need to add that, explicitly. If you don't specify any --host at all, then bokeh server adds "localhost" as a default, but if you add *any* --host then the server *only* configures the --host values that are explicitly given (no more default "localhost"). But note: adding "localhost" to the --host is probably not something you would want to do "in production", where all access to the server should go through Nginx, or Apache, or whatever.

* All of this assumes you are not also using/needing SSL (https), which would require a few additional configurations for the bokeh server, and probably quite alot of additional configuration for Apache.

---------

For completeness, I will say that another possible option is to simply run the server publicly-facing and then embed directly from the server using iframes, but there are a number of disadvantages to this approach (e.g. there's no way to scale things if necessary).

Thanks,

Bryan

On Apr 18, 2016, at 2:33 AM, Hexin Chen <[email protected]> wrote:

I'm new to Bokeh and I'm trying to run multiple apps in one directory, like the demo site:

  • http://demo.bokehplots.com/apps/movies
  • http://demo.bokehplots.com/apps/selection_histogram
  • http://demo.bokehplots.com/apps/weather
First I'll introduce the enviroment of the server I'm using. I'm running a RedHat 6.4 x86_64 with Apache 2.2.15, MySQL 5.1.73, and Anaconda 2.4 (Python 2.7, Bokeh 0.11.1). I have direct access to the server (it belongs to my department) and it has its own IP address. The web server on port 80 hosts a WordPress blog mainly and serveral static HTML pages, for example, domain.url will direct to domain.url/blog/ and that's the main WP page, there're links to domain.url/visualization/processing/ and under processing there're some Java applets of our visualization projects. These files and index pages are under /var/www/html/visualization/processing.

I'm trying to show bokeh apps in a similar ways. If a vistor goes to domain.url/visualization/bokeh_apps, a page will show up like demo.bokehplots.com, and then the vistor can click to domain.url/visualization/bokeh_apps/proj01, domain.url/visualization/bokeh_apps/proj02, etc. So I assume the Apache server needs to redirect to different bokeh apps on different ports when it recognize the URL path.

The first problem I ran into is the host whitelist. I ran the command:

[[email protected] bokeh_apps]$ bokeh serve --show myapp --port 5100 --host 127.0.0.1:80
A Window popped out and I had to quit the "Elinks", and the output kept going:

INFO:bokeh.server.tornado:Rejected connection from host 'localhost:5100' because it is not in the --
host whitelist
WARNING
:tornado.access:403 GET /myapp (::1) 1.71ms

DEBUG
:bokeh.server.tornado:[pid 834] 0 clients connected
I googled and all I can find is a GitHub issue page. I read it but don't understand whether there's a solution in the tornado.py.

The second problem is that I dont' know how to construct the structure.

I tried

cd /var/www/html/visualization/bokeh_apps/

bokeh serve
--show myapp --port 5100 --host 127.0.0.1:80/visualization/bokeh_apps/
and it returned "invalid port in host value". When I run locally in Python bokeh serve --show myapp, the address is like "localhost:5006/myapp" and doesn't show any structure. Is there some trick to do this? I searched but didn't find anything.

Thanks a lot for your help!

P.S. if Nignx has the solution for these 2 problems, it's still quite unlikely that my supervisor will agree to swtich from Apache...

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/0ff064a9-8d71-4a53-a409-05e5c5763fdd%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Hi Hexin,

OK I did try updating to Apache 2.4 and it works. Here is the configuration I used:

    <VirtualHost *:8080>
        ServerName localhost

        CustomLog "/Users/bryan/Sites/logs/access_log" combined
        ErrorLog "/Users/bryan/Sites/logs/error_log"

        ProxyPreserveHost On
        ProxyPass /sliders/ws ws://127.0.0.1:5100/sliders/ws
        ProxyPassReverse /sliders/ws ws://127.0.0.1:5100/sliders/ws

        ProxyPass /sliders http://127.0.0.1:5100/sliders/
        ProxyPassReverse /sliders http://127.0.0.1:5100/sliders/

        <Directory />
            Require all granted
            Options -Indexes
        </Directory>

        Alias /static /Users/bryan/work/bokeh/bokeh/server/static
        <Directory /Users/bryan/work/bokeh/bokeh/server/static>
            # directives to effect the static directory
            Options +Indexes
        </Directory>

    </VirtualHost>

With this Bokeh server invocation:

  bokeh serve --log-level=debug --port 5100 --host localhost:8080 sliders.py

Again you will need to customize for your particular deployment, but hopefully this points the way. As a final note, you do also need to make sure this Apache module is loaded:

  https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html

In order for the websocket forwarding to work. I also enabled mod_proxy_html but I don't know if that is necessary and I have to switch to other tasks.

Thanks,

Bryan

···

On Apr 18, 2016, at 12:26 PM, Bryan Van de Ven <[email protected]> wrote:

Hi Hexin,

Here is some more info that might help you further along. I apologize I can't provide a complete example, I have to prepare some talks this week.

Using the vhost block below, things *almost* work. It is not connecting the websocket. I gather this is because I have Apache 2.2 installed via OSX brew, and I think you need Apache >= 2.4 (or perhaps extra config with earlier versions) to enable websocket forwarding. I will have to leave figuring that out to you or someone else on the mailing list:

<VirtualHost *:8080>
     ServerName localhost

     CustomLog "/Users/bryan/Sites/logs/project.dev-access_log" combined
     ErrorLog "/Users/bryan/Sites/logs/project.dev-error_log"

     # for a bokeh server running internally on port 5100
     ProxyPreserveHost On
     ProxyPass /app http://127.0.0.1:5100/sliders/
     ProxyPassReverse /app http://127.0.0.1:5100/sliders/

     <Directory />
         Order Allow,Deny
         Allow From All
         Options -Indexes
     </Directory>

     # better to copy BokehJS static files to your normal /static location like this,
     # but other configurations would be possible...

     Alias /static /Users/bryan/work/bokeh/bokeh/server/static
     <Directory /Users/bryan/work/bokeh/bokeh/server/static>
         # directives to effect the static directory
         Options +Indexes
     </Directory>

</VirtualHost>

Then I ran bokeh server like this:

  bokeh serve --port 5100 --host localhost:8080 sliders.py

With all of this, the initial connection and static resources load fine, but the websocket does not connect. So that is the part to figure out.

Things you will want to change for your actual deploy:

* the --host should not be localhost:8080, it should be *whatever users will actually navigate to*, i.e. the host name of the public facing apache server
* if you want bokeh server to serve the static files instead of copying them too your normal /static location as part of your deploy, you probably want to add a --prefix

I look forward to hearing back about how this works out, and also adding a fully complete Apache example to the User's Guide when I can devote time to it.

Bryan

On Apr 18, 2016, at 11:04 AM, Bryan Van de Ven <[email protected]> wrote:

Hi Hexin,

Nginx is definitely not a requirement. It was simply the case that Nginx happened to be the thing we were familiar with, that we could document well in the time constraints we had. It should definitely be possible to use Bokeh behind other front-ends, and in fact I would very much like to document how to do that.

Here's a few high-level requirements that might help:

* Bokeh server apps use websockets. Whatever is in front of the bokeh server needs to be configured to forward websocket traffic. In an Nginx config, you'd have something like:

  proxy_pass http://127.0.0.1:5100;
  proxy_set_header Upgrade $http_upgrade;
   proxy_set_header Connection "upgrade";
  proxy_http_version 1.1;

Where the ip/port there is the internal ip/port that you have started the bokeh server on. It looks like there is some information about configuring Apache to forward websockets here:

  http://stackoverflow.com/questions/27526281/websockets-and-apache-proxy-how-to-configure-mod-proxy-wstunnel

* Bokeh server needs to receive the "Host" field from the HTML request. Whatever is in front of the bokeh server needs to forward this. In Nginx, it looks like this:

  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $host:$server_port;

I'm not sure offhand what that looks like for Apache (I have not used Apache, maybe someone else on the list can chime in).

* The Bokeh server host whitelist needs to have the *public-facing* host added. So if users are navigating to "foo.com" then the server needs to be started with

  --host "foo.com"

This value is matched up with the "Host" that the proxy forwards on to the bokeh server. They have to match. This is to guard against certain kinds of malicious attacks that involve spoofing Host fields in requests.

* You can add multiple --host fields. If you also want to be able to connect from localhost (for testing or whatever) then you'd need to add that, explicitly. If you don't specify any --host at all, then bokeh server adds "localhost" as a default, but if you add *any* --host then the server *only* configures the --host values that are explicitly given (no more default "localhost"). But note: adding "localhost" to the --host is probably not something you would want to do "in production", where all access to the server should go through Nginx, or Apache, or whatever.

* All of this assumes you are not also using/needing SSL (https), which would require a few additional configurations for the bokeh server, and probably quite alot of additional configuration for Apache.

---------

For completeness, I will say that another possible option is to simply run the server publicly-facing and then embed directly from the server using iframes, but there are a number of disadvantages to this approach (e.g. there's no way to scale things if necessary).

Thanks,

Bryan

On Apr 18, 2016, at 2:33 AM, Hexin Chen <[email protected]> wrote:

I'm new to Bokeh and I'm trying to run multiple apps in one directory, like the demo site:

  • http://demo.bokehplots.com/apps/movies
  • http://demo.bokehplots.com/apps/selection_histogram
  • http://demo.bokehplots.com/apps/weather
First I'll introduce the enviroment of the server I'm using. I'm running a RedHat 6.4 x86_64 with Apache 2.2.15, MySQL 5.1.73, and Anaconda 2.4 (Python 2.7, Bokeh 0.11.1). I have direct access to the server (it belongs to my department) and it has its own IP address. The web server on port 80 hosts a WordPress blog mainly and serveral static HTML pages, for example, domain.url will direct to domain.url/blog/ and that's the main WP page, there're links to domain.url/visualization/processing/ and under processing there're some Java applets of our visualization projects. These files and index pages are under /var/www/html/visualization/processing.

I'm trying to show bokeh apps in a similar ways. If a vistor goes to domain.url/visualization/bokeh_apps, a page will show up like demo.bokehplots.com, and then the vistor can click to domain.url/visualization/bokeh_apps/proj01, domain.url/visualization/bokeh_apps/proj02, etc. So I assume the Apache server needs to redirect to different bokeh apps on different ports when it recognize the URL path.

The first problem I ran into is the host whitelist. I ran the command:

[[email protected] bokeh_apps]$ bokeh serve --show myapp --port 5100 --host 127.0.0.1:80
A Window popped out and I had to quit the "Elinks", and the output kept going:

INFO:bokeh.server.tornado:Rejected connection from host 'localhost:5100' because it is not in the --
host whitelist
WARNING
:tornado.access:403 GET /myapp (::1) 1.71ms

DEBUG
:bokeh.server.tornado:[pid 834] 0 clients connected
I googled and all I can find is a GitHub issue page. I read it but don't understand whether there's a solution in the tornado.py.

The second problem is that I dont' know how to construct the structure.

I tried

cd /var/www/html/visualization/bokeh_apps/

bokeh serve
--show myapp --port 5100 --host 127.0.0.1:80/visualization/bokeh_apps/
and it returned "invalid port in host value". When I run locally in Python bokeh serve --show myapp, the address is like "localhost:5006/myapp" and doesn't show any structure. Is there some trick to do this? I searched but didn't find anything.

Thanks a lot for your help!

P.S. if Nignx has the solution for these 2 problems, it's still quite unlikely that my supervisor will agree to swtich from Apache...

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/0ff064a9-8d71-4a53-a409-05e5c5763fdd%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Thank you very much, Bryan!

It’s a really detailed walk-through. It took me some time to upgrade Apache from 2.2 to 2.4 and now I’ve loaded the modules and set the virtual host. However, I got 503 error Service Unavailable. The main site is running fine and the error only occurs when I try to visit the bokeh url

[[email protected] ~]# bokeh serve --log-level=debug --port 5100 --host “pub.domain”:80 /var/www/html/bokeh_app/sliders.py
DEBUG:bokeh.server.tornado:Allowed Host headers: [‘pub.domain:80’]
DEBUG:bokeh.server.tornado:These host origins can connect to the websocket: [‘pub.domain:80’, ‘localhost:5100’]
DEBUG:bokeh.server.tornado:Patterns are: [(’/sliders/?’, <class ‘bokeh.server.views.doc_handler.DocHandler’>, {‘application_context’: <bokeh.server.application_context.ApplicationContext object at 0x7fa1f3f0dad0>, ‘bokeh_websocket_path’: ‘/sliders/ws’}), (’/sliders/ws’, <class ‘bokeh.server.views.ws.WSHandler’>, {‘application_context’: <bokeh.server.application_context.ApplicationContext object at 0x7fa1f3f0dad0>, ‘bokeh_websocket_path’: ‘/sliders/ws’}), (’/sliders/autoload.js’, <class ‘bokeh.server.views.autoload_js_handler.AutoloadJsHandler’>, {‘application_context’: <bokeh.server.application_context.ApplicationContext object at 0x7fa1f3f0dad0>, ‘bokeh_websocket_path’: ‘/sliders/ws’}), (’/static/(.*)’, <class ‘bokeh.server.views.static_handler.StaticHandler’>)]
INFO:bokeh.command.subcommands.serve:Starting Bokeh server on port 5100 with applications at paths [’/sliders’]
DEBUG:bokeh.server.tornado:[pid 25108] 0 clients connected
DEBUG:bokeh.server.tornado:[pid 25108] /sliders has 0 sessions with 0 unused
DEBUG:bokeh.server.tornado:[pid 25108] 0 clients connected
DEBUG:bokeh.server.tornado:[pid 25108] /sliders has 0 sessions with 0 unused
DEBUG:bokeh.server.tornado:[pid 25108] 0 clients connected
DEBUG:bokeh.server.tornado:[pid 25108] /sliders has 0 sessions with 0 unused

Here’s my httpd.conf
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_html_module modules/mod_proxy_html.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so

<VirtualHost *:80>
ServerName pub.domain

CustomLog logs/bokeh-access.log combined           
ErrorLog logs/bokeh-error.log

# for a bokeh server running internally on port 5100
ProxyPreserveHost On
ProxyPass /bokeh_app/sliders/ws ws://127.0.0.1:5100/sliders/ws
ProxyPassReverse /bokeh_app/sliders/ws ws://127.0.0.1:5100/sliders/ws

ProxyPass /bokeh_app/sliders http://127.0.0.1:5100/sliders/
ProxyPassReverse /bokeh_app/sliders http://127.0.0.1:5100/sliders/

<Directory />
    Require all granted
    Options -Indexes
</Directory>

Then I also tried to open port 5100 withe firewalld to public, I visited the server.ip:5100/sliders and I can see the plotting.

[[email protected] ~]# bokeh serve --log-level=debug --port 5100 --host srv.ip:5100 /var/www/html/bokeh_app/sliders.py
DEBUG:bokeh.server.tornado:Allowed Host headers: [‘srv.ip:5100’]
DEBUG:bokeh.server.tornado:These host origins can connect to the websocket: [‘srv.ip:5100’, ‘localhost:5100’]
DEBUG:bokeh.server.tornado:Patterns are: [(’/sliders/?’, <class ‘bokeh.server.views.doc_handler.DocHandler’>, {‘application_context’: <bokeh.server.application_context.ApplicationContext object at 0x7f0000524b10>, ‘bokeh_websocket_path’: ‘/sliders/ws’}), (’/sliders/ws’, <class ‘bokeh.server.views.ws.WSHandler’>, {‘application_context’: <bokeh.server.application_context.ApplicationContext object at 0x7f0000524b10>, ‘bokeh_websocket_path’: ‘/sliders/ws’}), (’/sliders/autoload.js’, <class ‘bokeh.server.views.autoload_js_handler.AutoloadJsHandler’>, {‘application_context’: <bokeh.server.application_context.ApplicationContext object at 0x7f0000524b10>, ‘bokeh_websocket_path’: ‘/sliders/ws’}), (’/static/(.*)’, <class ‘bokeh.server.views.static_handler.StaticHandler’>)]
INFO:bokeh.command.subcommands.serve:Starting Bokeh server on port 5100 with applications at paths [’/sliders’]
DEBUG:bokeh.server.tornado:[pid 29638] 0 clients connected
DEBUG:bokeh.server.tornado:[pid 29638] /sliders has 0 sessions with 0 unused
INFO:tornado.access:200 GET /sliders (browser.ip) 69.91ms
INFO:bokeh.server.views.ws:WebSocket connection opened
DEBUG:bokeh.server.views.ws:Receiver created for Protocol(u’1.0’)
DEBUG:bokeh.server.views.ws:ServerHandler created for Protocol(u’1.0’)
INFO:bokeh.server.views.ws:ServerConnection created
DEBUG:bokeh.server.session:Sending pull-doc-reply from session ‘KBic9cpoZvfKqVaIaZqcnp92nfjX2Yf9ZFEuerk0l7ZY’
DEBUG:bokeh.server.tornado:[pid 29638] 1 clients connected
DEBUG:bokeh.server.tornado:[pid 29638] /sliders has 1 sessions with 0 unused

I don’t know why the application is not responding to the requests from Apache, although the settings seems fine to me.

Thanks a lot!

Hexin

···

On Tuesday, April 19, 2016 at 2:58:27 AM UTC+8, Bryan Van de ven wrote:

Hi Hexin,

OK I did try updating to Apache 2.4 and it works. Here is the configuration I used:

<VirtualHost *:8080>

    ServerName localhost



    CustomLog "/Users/bryan/Sites/logs/access_log" combined

    ErrorLog "/Users/bryan/Sites/logs/error_log"



    ProxyPreserveHost On

    ProxyPass /sliders/ws ws://[127.0.0.1:5100/sliders/ws](http://127.0.0.1:5100/sliders/ws)

    ProxyPassReverse /sliders/ws ws://[127.0.0.1:5100/sliders/ws](http://127.0.0.1:5100/sliders/ws)



    ProxyPass /sliders [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)

    ProxyPassReverse /sliders [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)





    <Directory />

        Require all granted

        Options -Indexes

    </Directory>



    Alias /static /Users/bryan/work/bokeh/bokeh/server/static

    <Directory /Users/bryan/work/bokeh/bokeh/server/static>

        # directives to effect the static directory

        Options +Indexes

    </Directory>



</VirtualHost>

With this Bokeh server invocation:

    bokeh serve --log-level=debug --port 5100 --host localhost:8080 sliders.py

Again you will need to customize for your particular deployment, but hopefully this points the way. As a final note, you do also need to make sure this Apache module is loaded:

    [https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html](https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html)

In order for the websocket forwarding to work. I also enabled mod_proxy_html but I don’t know if that is necessary and I have to switch to other tasks.

Thanks,

Bryan

On Apr 18, 2016, at 12:26 PM, Bryan Van de Ven [email protected] wrote:

Hi Hexin,

Here is some more info that might help you further along. I apologize I can’t provide a complete example, I have to prepare some talks this week.

Using the vhost block below, things almost work. It is not connecting the websocket. I gather this is because I have Apache 2.2 installed via OSX brew, and I think you need Apache >= 2.4 (or perhaps extra config with earlier versions) to enable websocket forwarding. I will have to leave figuring that out to you or someone else on the mailing list:

<VirtualHost *:8080>

 ServerName localhost
 CustomLog "/Users/bryan/Sites/logs/project.dev-access_log" combined
 ErrorLog "/Users/bryan/Sites/logs/project.dev-error_log"
 # for a bokeh server running internally on port 5100
 ProxyPreserveHost On
 ProxyPass /app [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)
 ProxyPassReverse /app [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)
 <Directory />
     Order Allow,Deny
     Allow From All
     Options -Indexes
 </Directory>
 # better to copy BokehJS static files to your normal /static location like this,
 # but other configurations would be possible...
 Alias /static /Users/bryan/work/bokeh/bokeh/server/static
 <Directory /Users/bryan/work/bokeh/bokeh/server/static>
     # directives to effect the static directory
     Options +Indexes
 </Directory>

Then I ran bokeh server like this:

    bokeh serve --port 5100 --host localhost:8080 sliders.py

With all of this, the initial connection and static resources load fine, but the websocket does not connect. So that is the part to figure out.

Things you will want to change for your actual deploy:

  • the --host should not be localhost:8080, it should be whatever users will actually navigate to, i.e. the host name of the public facing apache server
  • if you want bokeh server to serve the static files instead of copying them too your normal /static location as part of your deploy, you probably want to add a --prefix

I look forward to hearing back about how this works out, and also adding a fully complete Apache example to the User’s Guide when I can devote time to it.

Bryan

On Apr 18, 2016, at 11:04 AM, Bryan Van de Ven [email protected] wrote:

Hi Hexin,

Nginx is definitely not a requirement. It was simply the case that Nginx happened to be the thing we were familiar with, that we could document well in the time constraints we had. It should definitely be possible to use Bokeh behind other front-ends, and in fact I would very much like to document how to do that.

Here’s a few high-level requirements that might help:

  • Bokeh server apps use websockets. Whatever is in front of the bokeh server needs to be configured to forward websocket traffic. In an Nginx config, you’d have something like:
    proxy_pass [http://127.0.0.1:5100](http://127.0.0.1:5100);
    proxy_set_header Upgrade $http_upgrade;
     proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;

Where the ip/port there is the internal ip/port that you have started the bokeh server on. It looks like there is some information about configuring Apache to forward websockets here:

    [http://stackoverflow.com/questions/27526281/websockets-and-apache-proxy-how-to-configure-mod-proxy-wstunnel](http://stackoverflow.com/questions/27526281/websockets-and-apache-proxy-how-to-configure-mod-proxy-wstunnel)
  • Bokeh server needs to receive the “Host” field from the HTML request. Whatever is in front of the bokeh server needs to forward this. In Nginx, it looks like this:
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host:$server_port;

I’m not sure offhand what that looks like for Apache (I have not used Apache, maybe someone else on the list can chime in).

  • The Bokeh server host whitelist needs to have the public-facing host added. So if users are navigating to “foo.com” then the server needs to be started with
    --host "[foo.com](http://foo.com)"

This value is matched up with the “Host” that the proxy forwards on to the bokeh server. They have to match. This is to guard against certain kinds of malicious attacks that involve spoofing Host fields in requests.

  • You can add multiple --host fields. If you also want to be able to connect from localhost (for testing or whatever) then you’d need to add that, explicitly. If you don’t specify any --host at all, then bokeh server adds “localhost” as a default, but if you add any --host then the server only configures the --host values that are explicitly given (no more default “localhost”). But note: adding “localhost” to the --host is probably not something you would want to do “in production”, where all access to the server should go through Nginx, or Apache, or whatever.

  • All of this assumes you are not also using/needing SSL (https), which would require a few additional configurations for the bokeh server, and probably quite alot of additional configuration for Apache.


For completeness, I will say that another possible option is to simply run the server publicly-facing and then embed directly from the server using iframes, but there are a number of disadvantages to this approach (e.g. there’s no way to scale things if necessary).

Thanks,

Bryan

On Apr 18, 2016, at 2:33 AM, Hexin Chen [email protected] wrote:

I’m new to Bokeh and I’m trying to run multiple apps in one directory, like the demo site:

    • [http://demo.bokehplots.com/apps/movies](http://demo.bokehplots.com/apps/movies)
    • [http://demo.bokehplots.com/apps/selection_histogram](http://demo.bokehplots.com/apps/selection_histogram)
    • [http://demo.bokehplots.com/apps/weather](http://demo.bokehplots.com/apps/weather)

First I’ll introduce the enviroment of the server I’m using. I’m running a RedHat 6.4 x86_64 with Apache 2.2.15, MySQL 5.1.73, and Anaconda 2.4 (Python 2.7, Bokeh 0.11.1). I have direct access to the server (it belongs to my department) and it has its own IP address. The web server on port 80 hosts a WordPress blog mainly and serveral static HTML pages, for example, domain.url will direct to domain.url/blog/ and that’s the main WP page, there’re links to domain.url/visualization/processing/ and under processing there’re some Java applets of our visualization projects. These files and index pages are under /var/www/html/visualization/processing.

I’m trying to show bokeh apps in a similar ways. If a vistor goes to domain.url/visualization/bokeh_apps, a page will show up like demo.bokehplots.com, and then the vistor can click to domain.url/visualization/bokeh_apps/proj01, domain.url/visualization/bokeh_apps/proj02, etc. So I assume the Apache server needs to redirect to different bokeh apps on different ports when it recognize the URL path.

The first problem I ran into is the host whitelist. I ran the command:

[[email protected] bokeh_apps]$ bokeh serve --show myapp --port 5100 --host 127.0.0.1:80

A Window popped out and I had to quit the “Elinks”, and the output kept going:

INFO:bokeh.server.tornado:Rejected connection from host ‘localhost:5100’ because it is not in the –

host whitelist

WARNING

:tornado.access:403 GET /myapp (::1) 1.71ms

DEBUG

:bokeh.server.tornado:[pid 834] 0 clients connected

I googled and all I can find is a GitHub issue page. I read it but don’t understand whether there’s a solution in the tornado.py.

The second problem is that I dont’ know how to construct the structure.

I tried

cd /var/www/html/visualization/bokeh_apps/

bokeh serve
–show myapp --port 5100 --host 127.0.0.1:80/visualization/bokeh_apps/

and it returned “invalid port in host value”. When I run locally in Python bokeh serve --show myapp, the address is like “localhost:5006/myapp” and doesn’t show any structure. Is there some trick to do this? I searched but didn’t find anything.

Thanks a lot for your help!

P.S. if Nignx has the solution for these 2 problems, it’s still quite unlikely that my supervisor will agree to swtich from Apache…


You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/0ff064a9-8d71-4a53-a409-05e5c5763fdd%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Hexin,

When you hit the apache front end, do you see any attempted connection in the bokeh server log? If not, then the connection attempt is never even making it to the bokeh server, in which case what do the apache error/access logs report as to why to connection was not forwarded?

If a connection is making it all the way to the bokeh server, then is there any output in the browser JS console? In particular are the static JS and CSS resources getting loaded? I noticed you removed the alias for static, just to be clear, the BokehJS lib expects to be able to load JS and CSS from "/static/js" and "/static/css" URLs. So you either need to copy those static resources to an existing static dir if you have one as part of the deploy, or let bokeh server do the serving of "/static"

Bryan

···

On Apr 20, 2016, at 7:30 AM, Hexin Chen <[email protected]> wrote:

Thank you very much, Bryan!

It's a really detailed walk-through. It took me some time to upgrade Apache from 2.2 to 2.4 and now I've loaded the modules and set the virtual host. However, I got 503 error Service Unavailable. The main site is running fine and the error only occurs when I try to visit the bokeh url

[[email protected] ~]# bokeh serve --log-level=debug --port 5100 --host "pub.domain":80 /var/www/html/bokeh_app/sliders.py
DEBUG:bokeh.server.tornado:Allowed Host headers: ['pub.domain:80']
DEBUG:bokeh.server.tornado:These host origins can connect to the websocket: ['pub.domain:80', 'localhost:5100']
DEBUG:bokeh.server.tornado:Patterns are: [('/sliders/?', <class 'bokeh.server.views.doc_handler.DocHandler'>, {'application_context': <bokeh.server.application_context.ApplicationContext object at 0x7fa1f3f0dad0>, 'bokeh_websocket_path': '/sliders/ws'}), ('/sliders/ws', <class 'bokeh.server.views.ws.WSHandler'>, {'application_context': <bokeh.server.application_context.ApplicationContext object at 0x7fa1f3f0dad0>, 'bokeh_websocket_path': '/sliders/ws'}), ('/sliders/autoload.js', <class 'bokeh.server.views.autoload_js_handler.AutoloadJsHandler'>, {'application_context': <bokeh.server.application_context.ApplicationContext object at 0x7fa1f3f0dad0>, 'bokeh_websocket_path': '/sliders/ws'}), ('/static/(.*)', <class 'bokeh.server.views.static_handler.StaticHandler'>)]
INFO:bokeh.command.subcommands.serve:Starting Bokeh server on port 5100 with applications at paths ['/sliders']
DEBUG:bokeh.server.tornado:[pid 25108] 0 clients connected
DEBUG:bokeh.server.tornado:[pid 25108] /sliders has 0 sessions with 0 unused
DEBUG:bokeh.server.tornado:[pid 25108] 0 clients connected
DEBUG:bokeh.server.tornado:[pid 25108] /sliders has 0 sessions with 0 unused
DEBUG:bokeh.server.tornado:[pid 25108] 0 clients connected
DEBUG:bokeh.server.tornado:[pid 25108] /sliders has 0 sessions with 0 unused

Here's my httpd.conf
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_html_module modules/mod_proxy_html.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so

<VirtualHost *:80>
    ServerName pub.domain

    CustomLog logs/bokeh-access.log combined
    ErrorLog logs/bokeh-error.log

    # for a bokeh server running internally on port 5100
    ProxyPreserveHost On
    ProxyPass /bokeh_app/sliders/ws ws://127.0.0.1:5100/sliders/ws
    ProxyPassReverse /bokeh_app/sliders/ws ws://127.0.0.1:5100/sliders/ws

    ProxyPass /bokeh_app/sliders http://127.0.0.1:5100/sliders/
    ProxyPassReverse /bokeh_app/sliders http://127.0.0.1:5100/sliders/

    <Directory />
        Require all granted
        Options -Indexes
    </Directory>

</VirtualHost>

Then I also tried to open port 5100 withe firewalld to public, I visited the server.ip:5100/sliders and I can see the plotting.

[[email protected] ~]# bokeh serve --log-level=debug --port 5100 --host srv.ip:5100 /var/www/html/bokeh_app/sliders.py
DEBUG:bokeh.server.tornado:Allowed Host headers: ['srv.ip:5100']
DEBUG:bokeh.server.tornado:These host origins can connect to the websocket: ['srv.ip:5100', 'localhost:5100']
DEBUG:bokeh.server.tornado:Patterns are: [('/sliders/?', <class 'bokeh.server.views.doc_handler.DocHandler'>, {'application_context': <bokeh.server.application_context.ApplicationContext object at 0x7f0000524b10>, 'bokeh_websocket_path': '/sliders/ws'}), ('/sliders/ws', <class 'bokeh.server.views.ws.WSHandler'>, {'application_context': <bokeh.server.application_context.ApplicationContext object at 0x7f0000524b10>, 'bokeh_websocket_path': '/sliders/ws'}), ('/sliders/autoload.js', <class 'bokeh.server.views.autoload_js_handler.AutoloadJsHandler'>, {'application_context': <bokeh.server.application_context.ApplicationContext object at 0x7f0000524b10>, 'bokeh_websocket_path': '/sliders/ws'}), ('/static/(.*)', <class 'bokeh.server.views.static_handler.StaticHandler'>)]
INFO:bokeh.command.subcommands.serve:Starting Bokeh server on port 5100 with applications at paths ['/sliders']
DEBUG:bokeh.server.tornado:[pid 29638] 0 clients connected
DEBUG:bokeh.server.tornado:[pid 29638] /sliders has 0 sessions with 0 unused
INFO:tornado.access:200 GET /sliders (browser.ip) 69.91ms
INFO:bokeh.server.views.ws:WebSocket connection opened
DEBUG:bokeh.server.views.ws:Receiver created for Protocol(u'1.0')
DEBUG:bokeh.server.views.ws:ServerHandler created for Protocol(u'1.0')
INFO:bokeh.server.views.ws:ServerConnection created
DEBUG:bokeh.server.session:Sending pull-doc-reply from session 'KBic9cpoZvfKqVaIaZqcnp92nfjX2Yf9ZFEuerk0l7ZY'
DEBUG:bokeh.server.tornado:[pid 29638] 1 clients connected
DEBUG:bokeh.server.tornado:[pid 29638] /sliders has 1 sessions with 0 unused

I don't know why the application is not responding to the requests from Apache, although the settings seems fine to me.

Thanks a lot!

Hexin

On Tuesday, April 19, 2016 at 2:58:27 AM UTC+8, Bryan Van de ven wrote:
Hi Hexin,

OK I did try updating to Apache 2.4 and it works. Here is the configuration I used:

    <VirtualHost *:8080>
        ServerName localhost

        CustomLog "/Users/bryan/Sites/logs/access_log" combined
        ErrorLog "/Users/bryan/Sites/logs/error_log"

        ProxyPreserveHost On
        ProxyPass /sliders/ws ws://127.0.0.1:5100/sliders/ws
        ProxyPassReverse /sliders/ws ws://127.0.0.1:5100/sliders/ws

        ProxyPass /sliders http://127.0.0.1:5100/sliders/
        ProxyPassReverse /sliders http://127.0.0.1:5100/sliders/

        <Directory />
            Require all granted
            Options -Indexes
        </Directory>

        Alias /static /Users/bryan/work/bokeh/bokeh/server/static
        <Directory /Users/bryan/work/bokeh/bokeh/server/static>
            # directives to effect the static directory
            Options +Indexes
        </Directory>

    </VirtualHost>

With this Bokeh server invocation:

        bokeh serve --log-level=debug --port 5100 --host localhost:8080 sliders.py

Again you will need to customize for your particular deployment, but hopefully this points the way. As a final note, you do also need to make sure this Apache module is loaded:

        https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html

In order for the websocket forwarding to work. I also enabled mod_proxy_html but I don't know if that is necessary and I have to switch to other tasks.

Thanks,

Bryan

> On Apr 18, 2016, at 12:26 PM, Bryan Van de Ven <[email protected]> wrote:
>
> Hi Hexin,
>
> Here is some more info that might help you further along. I apologize I can't provide a complete example, I have to prepare some talks this week.
>
> Using the vhost block below, things *almost* work. It is not connecting the websocket. I gather this is because I have Apache 2.2 installed via OSX brew, and I think you need Apache >= 2.4 (or perhaps extra config with earlier versions) to enable websocket forwarding. I will have to leave figuring that out to you or someone else on the mailing list:
>
> <VirtualHost *:8080>
> ServerName localhost
>
> CustomLog "/Users/bryan/Sites/logs/project.dev-access_log" combined
> ErrorLog "/Users/bryan/Sites/logs/project.dev-error_log"
>
> # for a bokeh server running internally on port 5100
> ProxyPreserveHost On
> ProxyPass /app http://127.0.0.1:5100/sliders/
> ProxyPassReverse /app http://127.0.0.1:5100/sliders/
>
> <Directory />
> Order Allow,Deny
> Allow From All
> Options -Indexes
> </Directory>
>
> # better to copy BokehJS static files to your normal /static location like this,
> # but other configurations would be possible...
>
> Alias /static /Users/bryan/work/bokeh/bokeh/server/static
> <Directory /Users/bryan/work/bokeh/bokeh/server/static>
> # directives to effect the static directory
> Options +Indexes
> </Directory>
>
> </VirtualHost>
>
> Then I ran bokeh server like this:
>
> bokeh serve --port 5100 --host localhost:8080 sliders.py
>
> With all of this, the initial connection and static resources load fine, but the websocket does not connect. So that is the part to figure out.
>
> Things you will want to change for your actual deploy:
>
> * the --host should not be localhost:8080, it should be *whatever users will actually navigate to*, i.e. the host name of the public facing apache server
> * if you want bokeh server to serve the static files instead of copying them too your normal /static location as part of your deploy, you probably want to add a --prefix
>
> I look forward to hearing back about how this works out, and also adding a fully complete Apache example to the User's Guide when I can devote time to it.
>
> Bryan
>
>
>
>> On Apr 18, 2016, at 11:04 AM, Bryan Van de Ven <[email protected]> wrote:
>>
>> Hi Hexin,
>>
>> Nginx is definitely not a requirement. It was simply the case that Nginx happened to be the thing we were familiar with, that we could document well in the time constraints we had. It should definitely be possible to use Bokeh behind other front-ends, and in fact I would very much like to document how to do that.
>>
>> Here's a few high-level requirements that might help:
>>
>> * Bokeh server apps use websockets. Whatever is in front of the bokeh server needs to be configured to forward websocket traffic. In an Nginx config, you'd have something like:
>>
>> proxy_pass http://127.0.0.1:5100;
>> proxy_set_header Upgrade $http_upgrade;
>> proxy_set_header Connection "upgrade";
>> proxy_http_version 1.1;
>>
>> Where the ip/port there is the internal ip/port that you have started the bokeh server on. It looks like there is some information about configuring Apache to forward websockets here:
>>
>> http://stackoverflow.com/questions/27526281/websockets-and-apache-proxy-how-to-configure-mod-proxy-wstunnel
>>
>> * Bokeh server needs to receive the "Host" field from the HTML request. Whatever is in front of the bokeh server needs to forward this. In Nginx, it looks like this:
>>
>> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
>> proxy_set_header Host $host:server\_port; &gt;&gt; &gt;&gt; I&#39;m not sure offhand what that looks like for Apache \(I have not used Apache, maybe someone else on the list can chime in\)\. &gt;&gt; &gt;&gt; \* The Bokeh server host whitelist needs to have the \*public\-facing\* host added\. So if users are navigating to &quot;foo\.com&quot; then the server needs to be started with &gt;&gt; &gt;&gt; \-\-host &quot;foo\.com&quot; &gt;&gt; &gt;&gt; This value is matched up with the &quot;Host&quot; that the proxy forwards on to the bokeh server\. They have to match\. This is to guard against certain kinds of malicious attacks that involve spoofing Host fields in requests\. &gt;&gt; &gt;&gt; \* You can add multiple \-\-host fields\. If you also want to be able to connect from localhost \(for testing or whatever\) then you&#39;d need to add that, explicitly\. If you don&#39;t specify any \-\-host at all, then bokeh server adds &quot;localhost&quot; as a default, but if you add \*any\* \-\-host then the server \*only\* configures the \-\-host values that are explicitly given \(no more default &quot;localhost&quot;\)\. But note: adding &quot;localhost&quot; to the \-\-host is probably not something you would want to do &quot;in production&quot;, where all access to the server should go through Nginx, or Apache, or whatever\. &gt;&gt; &gt;&gt; \* All of this assumes you are not also using/needing SSL \(https\), which would require a few additional configurations for the bokeh server, and probably quite alot of additional configuration for Apache\. &gt;&gt; &gt;&gt; \-\-\-\-\-\-\-\-\- &gt;&gt; &gt;&gt; For completeness, I will say that another possible option is to simply run the server publicly\-facing and then embed directly from the server using iframes, but there are a number of disadvantages to this approach \(e\.g\. there&#39;s no way to scale things if necessary\)\. &gt;&gt; &gt;&gt; Thanks, &gt;&gt; &gt;&gt; Bryan &gt;&gt; &gt;&gt; &gt;&gt;&gt; On Apr 18, 2016, at 2:33 AM, Hexin Chen &lt;chenhe\.\.\[email protected]\.com&gt; wrote: &gt;&gt;&gt; &gt;&gt;&gt; I&#39;m new to Bokeh and I&#39;m trying to run multiple apps in one directory, like the demo site: &gt;&gt;&gt; &gt;&gt;&gt; • http://demo.bokehplots.com/apps/movies &gt;&gt;&gt; • http://demo.bokehplots.com/apps/selection_histogram &gt;&gt;&gt; • http://demo.bokehplots.com/apps/weather &gt;&gt;&gt; First I&#39;ll introduce the enviroment of the server I&#39;m using\. I&#39;m running a RedHat 6\.4 x86\_64 with Apache 2\.2\.15, MySQL 5\.1\.73, and Anaconda 2\.4 \(Python 2\.7, Bokeh 0\.11\.1\)\. I have direct access to the server \(it belongs to my department\) and it has its own IP address\. The web server on port 80 hosts a WordPress blog mainly and serveral static HTML pages, for example, domain\.url will direct to domain\.url/blog/ and that&#39;s the main WP page, there&#39;re links to domain\.url/visualization/processing/ and under processing there&#39;re some Java applets of our visualization projects\. These files and index pages are under /var/www/html/visualization/processing\. &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; I&#39;m trying to show bokeh apps in a similar ways\. If a vistor goes to domain\.url/visualization/bokeh\_apps, a page will show up like demo\.bokehplots\.com, and then the vistor can click to domain\.url/visualization/bokeh\_apps/proj01, domain\.url/visualization/bokeh\_apps/proj02, etc\. So I assume the Apache server needs to redirect to different bokeh apps on different ports when it recognize the URL path\. &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; The first problem I ran into is the host whitelist\. I ran the command: &gt;&gt;&gt; &gt;&gt;&gt; \[[email protected] bokeh\_apps\] bokeh serve --show myapp --port 5100 --host 127.0.0.1:80
>>> A Window popped out and I had to quit the "Elinks", and the output kept going:
>>>
>>> INFO:bokeh.server.tornado:Rejected connection from host 'localhost:5100' because it is not in the --
>>> host whitelist
>>> WARNING
>>> :tornado.access:403 GET /myapp (::1) 1.71ms
>>>
>>> DEBUG
>>> :bokeh.server.tornado:[pid 834] 0 clients connected
>>> I googled and all I can find is a GitHub issue page. I read it but don't understand whether there's a solution in the tornado.py.
>>>
>>>
>>>
>>> The second problem is that I dont' know how to construct the structure.
>>>
>>> I tried
>>>
>>> cd /var/www/html/visualization/bokeh_apps/
>>>
>>> bokeh serve
>>> --show myapp --port 5100 --host 127.0.0.1:80/visualization/bokeh_apps/
>>> and it returned "invalid port in host value". When I run locally in Python bokeh serve --show myapp, the address is like "localhost:5006/myapp" and doesn't show any structure. Is there some trick to do this? I searched but didn't find anything.
>>>
>>>
>>>
>>> Thanks a lot for your help!
>>>
>>>
>>>
>>> P.S. if Nignx has the solution for these 2 problems, it's still quite unlikely that my supervisor will agree to swtich from Apache...
>>>
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
>>> To post to this group, send email to [email protected].
>>> To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/0ff064a9-8d71-4a53-a409-05e5c5763fdd%40continuum.io.
>>> For more options, visit https://groups.google.com/a/continuum.io/d/optout.
>>
>

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/151cc948-ff52-405f-b428-528f232add5e%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Thank you, Bryan!

I copied the server files from /root/anaconda2/pkgs/bokeh-0.
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_html_module modules/mod_proxy_html.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so

<VirtualHost *:80>
ServerName domain.url

CustomLog logs/bokeh-access.log combined
ErrorLog logs/bokeh-error.log

# for a bokeh server running internally on port 5100
ProxyPreserveHost On
ProxyPass /bokeh_app/sliders/ws ws://[127.0.0.1:5100/sliders/ws](http://127.0.0.1:5100/sliders/ws)
ProxyPassReverse /bokeh_app/sliders/ws ws://[127.0.0.1:5100/sliders/ws](http://127.0.0.1:5100/sliders/ws)

ProxyPass /bokeh_app/sliders [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)
ProxyPassReverse /bokeh_app/sliders [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)

<Directory />
    Require all granted
    Options -Indexes
</Directory>

# better to copy BokehJS static files to your normal /static location like this,
# but other configurations would be possible...

Alias /static /var/www/html/bokeh_app/static
<Directory /var/www/html/bokeh_app/static>
    # directives to effect the static directory
    Options +Indexes
</Directory>
setsebool -P httpd_can_network_connect 1

browser_ip - - [22/Apr/2016:15:06:44 +0800] “GET /bokeh_app/sliders HTTP/1.1” 200 1421 “-” “M
ozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
browser_ip - - [22/Apr/2016:15:06:44 +0800] “GET /static/css/bokeh.min.css?v=25ce17349a0082e9
eeac845e42a822ec HTTP/1.1” 304 - “http://domain.url/bokeh_app/sliders” “Mozilla/5.0 (Windows N
T 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
browser_ip - - [22/Apr/2016:15:06:44 +0800] “GET /static/css/bokeh-widgets.min.css?v=3b73ec63
df304369ffc9c7e5132463cd HTTP/1.1” 304 - “http://domain.url/bokeh_app/sliders” “Mozilla/5.0 (W
indows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
browser_ip - - [22/Apr/2016:15:06:44 +0800] “GET /static/js/bokeh.min.js?v=50ffae624cbe67773b
5995270f946406 HTTP/1.1” 304 - “http://domain.url/bokeh_app/sliders” “Mozilla/5.0 (Windows NT
6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
browser_ip - - [22/Apr/2016:15:06:44 +0800] “GET /static/js/bokeh-widgets.min.js?v=7cfd458197
bc395bb09e9dc3b8ac7975 HTTP/1.1” 304 - “http://domain.url/bokeh_app/sliders” “Mozilla/5.0 (Win
dows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
browser_ip - - [22/Apr/2016:15:06:44 +0800] “GET /static/js/bokeh-compiler.min.js?v=28af56ac5
027aa8d0ab96086ec1da10b HTTP/1.1” 304 - “http://domain.url/bokeh_app/sliders” “Mozilla/5.0 (Wi
ndows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
browser_ip - - [22/Apr/2016:15:06:45 +0800] “GET /sliders/ws?bokeh-protocol-version=1.0&bokeh
-session-id=XSoe5MvuiIrei4vFFcLlEAze6VNcqc5WF3ADzlFbHuVx HTTP/1.1” 404 208 “-” “Mozilla/5.0 (Wind
ows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
::1 - - [22/Apr/2016:15:18:31 +0800] “OPTIONS * HTTP/1.0” 200 - “-” “Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)”
::1 - - [22/Apr/2016:15:18:31 +0800] “OPTIONS * HTTP/1.0” 200 - “-” “Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)”
::1 - - [22/Apr/2016:15:18:31 +0800] “OPTIONS * HTTP/1.0” 200 - “-” “Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)”
::1 - - [22/Apr/2016:15:18:31 +0800] “OPTIONS * HTTP/1.0” 200 - “-” “Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)”
::1 - - [22/Apr/2016:15:18:31 +0800] “OPTIONS * HTTP/1.0” 200 - “-” “Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)”
::1 - - [22/Apr/2016:15:18:31 +0800] “OPTIONS * HTTP/1.0” 200 - “-” “Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)”
::1 - - [22/Apr/2016:15:18:31 +0800] “OPTIONS * HTTP/1.0” 200 - “-” “Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)”
::1 - - [22/Apr/2016:15:18:31 +0800] “OPTIONS * HTTP/1.0” 200 - “-” “Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)”
::1 - - [22/Apr/2016:15:18:31 +0800] “OPTIONS * HTTP/1.0” 200 - “-” “Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)”
browser_ip - - [22/Apr/2016:15:18:41 +0800] “GET /bokeh_app/sliders HTTP/1.1” 200 1421 “-” “M
ozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
browser_ip - - [22/Apr/2016:15:18:41 +0800] “GET /static/css/bokeh.min.css?v=25ce17349a0082e9
eeac845e42a822ec HTTP/1.1” 304 - “http://domain.url/bokeh_app/sliders” “Mozilla/5.0 (Windows N
T 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
browser_ip - - [22/Apr/2016:15:18:41 +0800] “GET /static/css/bokeh-widgets.min.css?v=3b73ec63
df304369ffc9c7e5132463cd HTTP/1.1” 304 - “http://domain.url/bokeh_app/sliders” “Mozilla/5.0 (W
indows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
browser_ip - - [22/Apr/2016:15:18:41 +0800] “GET /static/js/bokeh.min.js?v=50ffae624cbe67773b
5995270f946406 HTTP/1.1” 304 - “http://domain.url/bokeh_app/sliders” “Mozilla/5.0 (Windows NT
6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
browser_ip - - [22/Apr/2016:15:18:41 +0800] “GET /static/js/bokeh-widgets.min.js?v=7cfd458197
bc395bb09e9dc3b8ac7975 HTTP/1.1” 304 - “http://domain.url/bokeh_app/sliders” “Mozilla/5.0 (Win
dows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
browser_ip - - [22/Apr/2016:15:18:41 +0800] “GET /static/js/bokeh-compiler.min.js?v=28af56ac5
027aa8d0ab96086ec1da10b HTTP/1.1” 304 - “http://domain.url/bokeh_app/sliders” “Mozilla/5.0 (Wi
ndows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
browser_ip - - [22/Apr/2016:15:18:41 +0800] “GET /sliders/ws?bokeh-protocol-version=1.0&bokeh
-session-id=yDtvnCf7PKSFacQEHScfcZpTGLcp00IQ5FW8wYKNqHUF HTTP/1.1” 404 208 “-” “Mozilla/5.0 (Wind
ows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
::1 - - [22/Apr/2016:15:18:46 +0800] “OPTIONS * HTTP/1.0” 200 - “-” “Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)”
::1 - - [22/Apr/2016:15:18:47 +0800] “OPTIONS * HTTP/1.0” 200 - “-” “Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)”
browser_ip - - [22/Apr/2016:15:19:25 +0800] “GET /bokeh_app/sliders HTTP/1.1” 200 1421 “-” “M
ozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
browser_ip - - [22/Apr/2016:15:19:25 +0800] “GET /static/css/bokeh.min.css?v=25ce17349a0082e9
eeac845e42a822ec HTTP/1.1” 304 - “http://domain.url/bokeh_app/sliders” “Mozilla/5.0 (Windows N
T 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
browser_ip - - [22/Apr/2016:15:19:25 +0800] “GET /static/css/bokeh-widgets.min.css?v=3b73ec63
df304369ffc9c7e5132463cd HTTP/1.1” 304 - “http://domain.url/bokeh_app/sliders” “Mozilla/5.0 (W
indows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
browser_ip - - [22/Apr/2016:15:19:25 +0800] “GET /static/js/bokeh.min.js?v=50ffae624cbe67773b
5995270f946406 HTTP/1.1” 304 - “http://domain.url/bokeh_app/sliders” “Mozilla/5.0 (Windows NT
6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
browser_ip - - [22/Apr/2016:15:19:25 +0800] “GET /static/js/bokeh-widgets.min.js?v=7cfd458197
bc395bb09e9dc3b8ac7975 HTTP/1.1” 304 - “http://domain.url/bokeh_app/sliders” “Mozilla/5.0 (Win
dows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
browser_ip - - [22/Apr/2016:15:19:25 +0800] “GET /static/js/bokeh-compiler.min.js?v=28af56ac5
027aa8d0ab96086ec1da10b HTTP/1.1” 304 - “http://domain.url/bokeh_app/sliders” “Mozilla/5.0 (Wi
ndows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”
browser_ip - - [22/Apr/2016:15:19:26 +0800] “GET /sliders/ws?bokeh-protocol-version=1.0&bokeh
-session-id=vNWooEyI9G7p5lfds5u9N2nWSQY55VNIAtrfNcheRuv8 HTTP/1.1” 404 208 “-” “Mozilla/5.0 (Wind
ows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”

11.1-py27_0/lib/python2.7/site-packages/bokeh/server and here’s my httpd.conf:

I also changed the SELinux setting so now I dont’ get 503

But I still can’t see the app, its just a blank page with “Bokeh Application” and a favicon. Here’s the access log:

When
I open port 5100 and visit domain.url:5100/sliders I can see the figure
but behind Apache, I don’t get errors in the bokeh-error.log, the static/JS files are not loaded, I can only see the blank page.

Regards,
Hexin

···

On Thursday, April 21, 2016 at 12:02:09 AM UTC+8, Bryan Van de ven wrote:

Hexin,

When you hit the apache front end, do you see any attempted connection in the bokeh server log? If not, then the connection attempt is never even making it to the bokeh server, in which case what do the apache error/access logs report as to why to connection was not forwarded?

If a connection is making it all the way to the bokeh server, then is there any output in the browser JS console? In particular are the static JS and CSS resources getting loaded? I noticed you removed the alias for static, just to be clear, the BokehJS lib expects to be able to load JS and CSS from “/static/js” and “/static/css” URLs. So you either need to copy those static resources to an existing static dir if you have one as part of the deploy, or let bokeh server do the serving of “/static”

Bryan

On Apr 20, 2016, at 7:30 AM, Hexin Chen [email protected] wrote:

Thank you very much, Bryan!

It’s a really detailed walk-through. It took me some time to upgrade Apache from 2.2 to 2.4 and now I’ve loaded the modules and set the virtual host. However, I got 503 error Service Unavailable. The main site is running fine and the error only occurs when I try to visit the bokeh url

[[email protected] ~]# bokeh serve --log-level=debug --port 5100 --host “pub.domain”:80 /var/www/html/bokeh_app/sliders.py

DEBUG:bokeh.server.tornado:Allowed Host headers: [‘pub.domain:80’]

DEBUG:bokeh.server.tornado:These host origins can connect to the websocket: [‘pub.domain:80’, ‘localhost:5100’]

DEBUG:bokeh.server.tornado:Patterns are: [(’/sliders/?’, <class ‘bokeh.server.views.doc_handler.DocHandler’>, {‘application_context’: <bokeh.server.application_context.ApplicationContext object at 0x7fa1f3f0dad0>, ‘bokeh_websocket_path’: ‘/sliders/ws’}), (’/sliders/ws’, <class ‘bokeh.server.views.ws.WSHandler’>, {‘application_context’: <bokeh.server.application_context.ApplicationContext object at 0x7fa1f3f0dad0>, ‘bokeh_websocket_path’: ‘/sliders/ws’}), (’/sliders/autoload.js’, <class ‘bokeh.server.views.autoload_js_handler.AutoloadJsHandler’>, {‘application_context’: <bokeh.server.application_context.ApplicationContext object at 0x7fa1f3f0dad0>, ‘bokeh_websocket_path’: ‘/sliders/ws’}), (’/static/(.*)’, <class ‘bokeh.server.views.static_handler.StaticHandler’>)]

INFO:bokeh.command.subcommands.serve:Starting Bokeh server on port 5100 with applications at paths [’/sliders’]

DEBUG:bokeh.server.tornado:[pid 25108] 0 clients connected

DEBUG:bokeh.server.tornado:[pid 25108] /sliders has 0 sessions with 0 unused

DEBUG:bokeh.server.tornado:[pid 25108] 0 clients connected

DEBUG:bokeh.server.tornado:[pid 25108] /sliders has 0 sessions with 0 unused

DEBUG:bokeh.server.tornado:[pid 25108] 0 clients connected

DEBUG:bokeh.server.tornado:[pid 25108] /sliders has 0 sessions with 0 unused

Here’s my httpd.conf

LoadModule proxy_module modules/mod_proxy.so

LoadModule proxy_html_module modules/mod_proxy_html.so

LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so

<VirtualHost *:80>

ServerName pub.domain
CustomLog logs/bokeh-access.log combined            
ErrorLog logs/bokeh-error.log
# for a bokeh server running internally on port 5100
ProxyPreserveHost On
ProxyPass /bokeh_app/sliders/ws ws://[127.0.0.1:5100/sliders/ws](http://127.0.0.1:5100/sliders/ws)
ProxyPassReverse /bokeh_app/sliders/ws ws://[127.0.0.1:5100/sliders/ws](http://127.0.0.1:5100/sliders/ws)
ProxyPass /bokeh_app/sliders [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)
ProxyPassReverse /bokeh_app/sliders [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)
<Directory />
    Require all granted
    Options -Indexes
</Directory>

Then I also tried to open port 5100 withe firewalld to public, I visited the server.ip:5100/sliders and I can see the plotting.

[[email protected] ~]# bokeh serve --log-level=debug --port 5100 --host srv.ip:5100 /var/www/html/bokeh_app/sliders.py

DEBUG:bokeh.server.tornado:Allowed Host headers: [‘srv.ip:5100’]

DEBUG:bokeh.server.tornado:These host origins can connect to the websocket: [‘srv.ip:5100’, ‘localhost:5100’]

DEBUG:bokeh.server.tornado:Patterns are: [(’/sliders/?’, <class ‘bokeh.server.views.doc_handler.DocHandler’>, {‘application_context’: <bokeh.server.application_context.ApplicationContext object at 0x7f0000524b10>, ‘bokeh_websocket_path’: ‘/sliders/ws’}), (’/sliders/ws’, <class ‘bokeh.server.views.ws.WSHandler’>, {‘application_context’: <bokeh.server.application_context.ApplicationContext object at 0x7f0000524b10>, ‘bokeh_websocket_path’: ‘/sliders/ws’}), (’/sliders/autoload.js’, <class ‘bokeh.server.views.autoload_js_handler.AutoloadJsHandler’>, {‘application_context’: <bokeh.server.application_context.ApplicationContext object at 0x7f0000524b10>, ‘bokeh_websocket_path’: ‘/sliders/ws’}), (’/static/(.*)’, <class ‘bokeh.server.views.static_handler.StaticHandler’>)]

INFO:bokeh.command.subcommands.serve:Starting Bokeh server on port 5100 with applications at paths [’/sliders’]

DEBUG:bokeh.server.tornado:[pid 29638] 0 clients connected

DEBUG:bokeh.server.tornado:[pid 29638] /sliders has 0 sessions with 0 unused

INFO:tornado.access:200 GET /sliders (browser.ip) 69.91ms

INFO:bokeh.server.views.ws:WebSocket connection opened

DEBUG:bokeh.server.views.ws:Receiver created for Protocol(u’1.0’)

DEBUG:bokeh.server.views.ws:ServerHandler created for Protocol(u’1.0’)

INFO:bokeh.server.views.ws:ServerConnection created

DEBUG:bokeh.server.session:Sending pull-doc-reply from session ‘KBic9cpoZvfKqVaIaZqcnp92nfjX2Yf9ZFEuerk0l7ZY’

DEBUG:bokeh.server.tornado:[pid 29638] 1 clients connected

DEBUG:bokeh.server.tornado:[pid 29638] /sliders has 1 sessions with 0 unused

I don’t know why the application is not responding to the requests from Apache, although the settings seems fine to me.

Thanks a lot!

Hexin

On Tuesday, April 19, 2016 at 2:58:27 AM UTC+8, Bryan Van de ven wrote:

Hi Hexin,

OK I did try updating to Apache 2.4 and it works. Here is the configuration I used:

<VirtualHost *:8080>
    ServerName localhost

    CustomLog "/Users/bryan/Sites/logs/access_log" combined
    ErrorLog "/Users/bryan/Sites/logs/error_log"

    ProxyPreserveHost On
    ProxyPass /sliders/ws ws://[127.0.0.1:5100/sliders/ws](http://127.0.0.1:5100/sliders/ws)
    ProxyPassReverse /sliders/ws ws://[127.0.0.1:5100/sliders/ws](http://127.0.0.1:5100/sliders/ws)
    ProxyPass /sliders [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)
    ProxyPassReverse /sliders [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)
    <Directory />
        Require all granted
        Options -Indexes
    </Directory>

    Alias /static /Users/bryan/work/bokeh/bokeh/server/static
    <Directory /Users/bryan/work/bokeh/bokeh/server/static>
        # directives to effect the static directory
        Options +Indexes
    </Directory>

</VirtualHost>

With this Bokeh server invocation:

    bokeh serve --log-level=debug --port 5100 --host localhost:8080 sliders.py

Again you will need to customize for your particular deployment, but hopefully this points the way. As a final note, you do also need to make sure this Apache module is loaded:

    [https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html](https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html)

In order for the websocket forwarding to work. I also enabled mod_proxy_html but I don’t know if that is necessary and I have to switch to other tasks.

Thanks,

Bryan

On Apr 18, 2016, at 12:26 PM, Bryan Van de Ven [email protected] wrote:

Hi Hexin,

Here is some more info that might help you further along. I apologize I can’t provide a complete example, I have to prepare some talks this week.

Using the vhost block below, things almost work. It is not connecting the websocket. I gather this is because I have Apache 2.2 installed via OSX brew, and I think you need Apache >= 2.4 (or perhaps extra config with earlier versions) to enable websocket forwarding. I will have to leave figuring that out to you or someone else on the mailing list:

<VirtualHost *:8080>
ServerName localhost

 CustomLog "/Users/bryan/Sites/logs/project.dev-access_log" combined
 ErrorLog "/Users/bryan/Sites/logs/project.dev-error_log"

 # for a bokeh server running internally on port 5100
 ProxyPreserveHost On
 ProxyPass /app [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)
 ProxyPassReverse /app [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)
 <Directory />
     Order Allow,Deny
     Allow From All
     Options -Indexes
 </Directory>

 # better to copy BokehJS static files to your normal /static location like this,
 # but other configurations would be possible...

 Alias /static /Users/bryan/work/bokeh/bokeh/server/static
 <Directory /Users/bryan/work/bokeh/bokeh/server/static>
     # directives to effect the static directory
     Options +Indexes
 </Directory>

Then I ran bokeh server like this:

    bokeh serve --port 5100 --host localhost:8080 sliders.py

With all of this, the initial connection and static resources load fine, but the websocket does not connect. So that is the part to figure out.

Things you will want to change for your actual deploy:

  • the --host should not be localhost:8080, it should be whatever users will actually navigate to, i.e. the host name of the public facing apache server
  • if you want bokeh server to serve the static files instead of copying them too your normal /static location as part of your deploy, you probably want to add a --prefix

I look forward to hearing back about how this works out, and also adding a fully complete Apache example to the User’s Guide when I can devote time to it.

Bryan

On Apr 18, 2016, at 11:04 AM, Bryan Van de Ven [email protected] wrote:

Hi Hexin,

Nginx is definitely not a requirement. It was simply the case that Nginx happened to be the thing we were familiar with, that we could document well in the time constraints we had. It should definitely be possible to use Bokeh behind other front-ends, and in fact I would very much like to document how to do that.

Here’s a few high-level requirements that might help:

  • Bokeh server apps use websockets. Whatever is in front of the bokeh server needs to be configured to forward websocket traffic. In an Nginx config, you’d have something like:

      proxy_pass [http://127.0.0.1:5100](http://127.0.0.1:5100);
      proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "upgrade";
      proxy_http_version 1.1;
    

Where the ip/port there is the internal ip/port that you have started the bokeh server on. It looks like there is some information about configuring Apache to forward websockets here:

    [http://stackoverflow.com/questions/27526281/websockets-and-apache-proxy-how-to-configure-mod-proxy-wstunnel](http://stackoverflow.com/questions/27526281/websockets-and-apache-proxy-how-to-configure-mod-proxy-wstunnel)
  • Bokeh server needs to receive the “Host” field from the HTML request. Whatever is in front of the bokeh server needs to forward this. In Nginx, it looks like this:

      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $host:$server_port;
    

I’m not sure offhand what that looks like for Apache (I have not used Apache, maybe someone else on the list can chime in).

  • The Bokeh server host whitelist needs to have the public-facing host added. So if users are navigating to “foo.com” then the server needs to be started with

      --host "[foo.com](http://foo.com)"
    

This value is matched up with the “Host” that the proxy forwards on to the bokeh server. They have to match. This is to guard against certain kinds of malicious attacks that involve spoofing Host fields in requests.

  • You can add multiple --host fields. If you also want to be able to connect from localhost (for testing or whatever) then you’d need to add that, explicitly. If you don’t specify any --host at all, then bokeh server adds “localhost” as a default, but if you add any --host then the server only configures the --host values that are explicitly given (no more default “localhost”). But note: adding “localhost” to the --host is probably not something you would want to do “in production”, where all access to the server should go through Nginx, or Apache, or whatever.

  • All of this assumes you are not also using/needing SSL (https), which would require a few additional configurations for the bokeh server, and probably quite alot of additional configuration for Apache.


For completeness, I will say that another possible option is to simply run the server publicly-facing and then embed directly from the server using iframes, but there are a number of disadvantages to this approach (e.g. there’s no way to scale things if necessary).

Thanks,

Bryan

On Apr 18, 2016, at 2:33 AM, Hexin Chen [email protected] wrote:

I’m new to Bokeh and I’m trying to run multiple apps in one directory, like the demo site:

    • [http://demo.bokehplots.com/apps/movies](http://demo.bokehplots.com/apps/movies)
    • [http://demo.bokehplots.com/apps/selection_histogram](http://demo.bokehplots.com/apps/selection_histogram)
    • [http://demo.bokehplots.com/apps/weather](http://demo.bokehplots.com/apps/weather)

First I’ll introduce the enviroment of the server I’m using. I’m running a RedHat 6.4 x86_64 with Apache 2.2.15, MySQL 5.1.73, and Anaconda 2.4 (Python 2.7, Bokeh 0.11.1). I have direct access to the server (it belongs to my department) and it has its own IP address. The web server on port 80 hosts a WordPress blog mainly and serveral static HTML pages, for example, domain.url will direct to domain.url/blog/ and that’s the main WP page, there’re links to domain.url/visualization/processing/ and under processing there’re some Java applets of our visualization projects. These files and index pages are under /var/www/html/visualization/processing.

I’m trying to show bokeh apps in a similar ways. If a vistor goes to domain.url/visualization/bokeh_apps, a page will show up like demo.bokehplots.com, and then the vistor can click to domain.url/visualization/bokeh_apps/proj01, domain.url/visualization/bokeh_apps/proj02, etc. So I assume the Apache server needs to redirect to different bokeh apps on different ports when it recognize the URL path.

The first problem I ran into is the host whitelist. I ran the command:

[[email protected] bokeh_apps]$ bokeh serve --show myapp --port 5100 --host 127.0.0.1:80

A Window popped out and I had to quit the “Elinks”, and the output kept going:

INFO:bokeh.server.tornado:Rejected connection from host ‘localhost:5100’ because it is not in the –
host whitelist
WARNING
:tornado.access:403 GET /myapp (::1) 1.71ms

DEBUG
:bokeh.server.tornado:[pid 834] 0 clients connected
I googled and all I can find is a GitHub issue page. I read it but don’t understand whether there’s a solution in the tornado.py.

The second problem is that I dont’ know how to construct the structure.

I tried

cd /var/www/html/visualization/bokeh_apps/

bokeh serve
–show myapp --port 5100 --host 127.0.0.1:80/visualization/bokeh_apps/

and it returned “invalid port in host value”. When I run locally in Python bokeh serve --show myapp, the address is like “localhost:5006/myapp” and doesn’t show any structure. Is there some trick to do this? I searched but didn’t find anything.

Thanks a lot for your help!

P.S. if Nignx has the solution for these 2 problems, it’s still quite unlikely that my supervisor will agree to swtich from Apache…


You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/0ff064a9-8d71-4a53-a409-05e5c5763fdd%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.


You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/151cc948-ff52-405f-b428-528f232add5e%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Can you clarify this:

  I don't get errors in the bokeh-error.log, the static/JS files are not loaded, I can only see the blank page.

Do you mean you see the error messages in the JS console reporting 404 for the static assets? If there are no JS console messages about 404, then I think that means the static files *are* loaded. But if there are errors, and the static JS and CSS files are not loading into the browser, that would explain the blank screen. But then I am afraid I am at the limit of my knowledge, it seems like a web-server/OS configuration issue at this point. Your setup below looks fine to me, but you do mention SELinux. I know SELinux is more restrictive with access controls, but I have never used it so I can't really offer any advice.

Bryan

···

On Apr 22, 2016, at 3:16 AM, Hexin Chen <[email protected]> wrote:

Thank you, Bryan!

I copied the server files from /root/anaconda2/pkgs/bokeh-0.
11.1-py27_0/lib/python2.7/site-packages/bokeh/server and here's my httpd.conf:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_html_module modules/mod_proxy_html.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so

<VirtualHost *:80>
    ServerName domain.url

    CustomLog logs/bokeh-access.log combined
    ErrorLog logs/bokeh-error.log

    # for a bokeh server running internally on port 5100
    ProxyPreserveHost On
    ProxyPass /bokeh_app/sliders/ws ws://127.0.0.1:5100/sliders/ws
    ProxyPassReverse /bokeh_app/sliders/ws ws://127.0.0.1:5100/sliders/ws

    ProxyPass /bokeh_app/sliders http://127.0.0.1:5100/sliders/
    ProxyPassReverse /bokeh_app/sliders http://127.0.0.1:5100/sliders/

    <Directory />
        Require all granted
        Options -Indexes
    </Directory>

    # better to copy BokehJS static files to your normal /static location like this,
    # but other configurations would be possible...

    Alias /static /var/www/html/bokeh_app/static
    <Directory /var/www/html/bokeh_app/static>
        # directives to effect the static directory
        Options +Indexes
    </Directory>

</VirtualHost>

I also changed the SELinux setting so now I dont' get 503

setsebool -P httpd_can_network_connect 1

But I still can't see the app, its just a blank page with "Bokeh Application" and a favicon. Here's the access log:

browser_ip - - [22/Apr/2016:15:06:44 +0800] "GET /bokeh_app/sliders HTTP/1.1" 200 1421 "-" "M
ozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
browser_ip - - [22/Apr/2016:15:06:44 +0800] "GET /static/css/bokeh.min.css?v=25ce17349a0082e9
eeac845e42a822ec HTTP/1.1" 304 - "http://domain.url/bokeh_app/sliders" "Mozilla/5.0 (Windows N
T 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
browser_ip - - [22/Apr/2016:15:06:44 +0800] "GET /static/css/bokeh-widgets.min.css?v=3b73ec63
df304369ffc9c7e5132463cd HTTP/1.1" 304 - "http://domain.url/bokeh_app/sliders" "Mozilla/5.0 (W
indows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
browser_ip - - [22/Apr/2016:15:06:44 +0800] "GET /static/js/bokeh.min.js?v=50ffae624cbe67773b
5995270f946406 HTTP/1.1" 304 - "http://domain.url/bokeh_app/sliders" "Mozilla/5.0 (Windows NT
6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
browser_ip - - [22/Apr/2016:15:06:44 +0800] "GET /static/js/bokeh-widgets.min.js?v=7cfd458197
bc395bb09e9dc3b8ac7975 HTTP/1.1" 304 - "http://domain.url/bokeh_app/sliders" "Mozilla/5.0 (Win
dows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
browser_ip - - [22/Apr/2016:15:06:44 +0800] "GET /static/js/bokeh-compiler.min.js?v=28af56ac5
027aa8d0ab96086ec1da10b HTTP/1.1" 304 - "http://domain.url/bokeh_app/sliders" "Mozilla/5.0 (Wi
ndows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
browser_ip - - [22/Apr/2016:15:06:45 +0800] "GET /sliders/ws?bokeh-protocol-version=1.0&bokeh
-session-id=XSoe5MvuiIrei4vFFcLlEAze6VNcqc5WF3ADzlFbHuVx HTTP/1.1" 404 208 "-" "Mozilla/5.0 (Wind
ows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
::1 - - [22/Apr/2016:15:18:31 +0800] "OPTIONS * HTTP/1.0" 200 - "-" "Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"
::1 - - [22/Apr/2016:15:18:31 +0800] "OPTIONS * HTTP/1.0" 200 - "-" "Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"
::1 - - [22/Apr/2016:15:18:31 +0800] "OPTIONS * HTTP/1.0" 200 - "-" "Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"
::1 - - [22/Apr/2016:15:18:31 +0800] "OPTIONS * HTTP/1.0" 200 - "-" "Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"
::1 - - [22/Apr/2016:15:18:31 +0800] "OPTIONS * HTTP/1.0" 200 - "-" "Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"
::1 - - [22/Apr/2016:15:18:31 +0800] "OPTIONS * HTTP/1.0" 200 - "-" "Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"
::1 - - [22/Apr/2016:15:18:31 +0800] "OPTIONS * HTTP/1.0" 200 - "-" "Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"
::1 - - [22/Apr/2016:15:18:31 +0800] "OPTIONS * HTTP/1.0" 200 - "-" "Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"
::1 - - [22/Apr/2016:15:18:31 +0800] "OPTIONS * HTTP/1.0" 200 - "-" "Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"
browser_ip - - [22/Apr/2016:15:18:41 +0800] "GET /bokeh_app/sliders HTTP/1.1" 200 1421 "-" "M
ozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
browser_ip - - [22/Apr/2016:15:18:41 +0800] "GET /static/css/bokeh.min.css?v=25ce17349a0082e9
eeac845e42a822ec HTTP/1.1" 304 - "http://domain.url/bokeh_app/sliders" "Mozilla/5.0 (Windows N
T 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
browser_ip - - [22/Apr/2016:15:18:41 +0800] "GET /static/css/bokeh-widgets.min.css?v=3b73ec63
df304369ffc9c7e5132463cd HTTP/1.1" 304 - "http://domain.url/bokeh_app/sliders" "Mozilla/5.0 (W
indows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
browser_ip - - [22/Apr/2016:15:18:41 +0800] "GET /static/js/bokeh.min.js?v=50ffae624cbe67773b
5995270f946406 HTTP/1.1" 304 - "http://domain.url/bokeh_app/sliders" "Mozilla/5.0 (Windows NT
6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
browser_ip - - [22/Apr/2016:15:18:41 +0800] "GET /static/js/bokeh-widgets.min.js?v=7cfd458197
bc395bb09e9dc3b8ac7975 HTTP/1.1" 304 - "http://domain.url/bokeh_app/sliders" "Mozilla/5.0 (Win
dows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
browser_ip - - [22/Apr/2016:15:18:41 +0800] "GET /static/js/bokeh-compiler.min.js?v=28af56ac5
027aa8d0ab96086ec1da10b HTTP/1.1" 304 - "http://domain.url/bokeh_app/sliders" "Mozilla/5.0 (Wi
ndows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
browser_ip - - [22/Apr/2016:15:18:41 +0800] "GET /sliders/ws?bokeh-protocol-version=1.0&bokeh
-session-id=yDtvnCf7PKSFacQEHScfcZpTGLcp00IQ5FW8wYKNqHUF HTTP/1.1" 404 208 "-" "Mozilla/5.0 (Wind
ows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
::1 - - [22/Apr/2016:15:18:46 +0800] "OPTIONS * HTTP/1.0" 200 - "-" "Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"
::1 - - [22/Apr/2016:15:18:47 +0800] "OPTIONS * HTTP/1.0" 200 - "-" "Apache/2.4.6 (CentOS) OpenSS
L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"
browser_ip - - [22/Apr/2016:15:19:25 +0800] "GET /bokeh_app/sliders HTTP/1.1" 200 1421 "-" "M
ozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
browser_ip - - [22/Apr/2016:15:19:25 +0800] "GET /static/css/bokeh.min.css?v=25ce17349a0082e9
eeac845e42a822ec HTTP/1.1" 304 - "http://domain.url/bokeh_app/sliders" "Mozilla/5.0 (Windows N
T 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
browser_ip - - [22/Apr/2016:15:19:25 +0800] "GET /static/css/bokeh-widgets.min.css?v=3b73ec63
df304369ffc9c7e5132463cd HTTP/1.1" 304 - "http://domain.url/bokeh_app/sliders" "Mozilla/5.0 (W
indows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
browser_ip - - [22/Apr/2016:15:19:25 +0800] "GET /static/js/bokeh.min.js?v=50ffae624cbe67773b
5995270f946406 HTTP/1.1" 304 - "http://domain.url/bokeh_app/sliders" "Mozilla/5.0 (Windows NT
6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
browser_ip - - [22/Apr/2016:15:19:25 +0800] "GET /static/js/bokeh-widgets.min.js?v=7cfd458197
bc395bb09e9dc3b8ac7975 HTTP/1.1" 304 - "http://domain.url/bokeh_app/sliders" "Mozilla/5.0 (Win
dows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
browser_ip - - [22/Apr/2016:15:19:25 +0800] "GET /static/js/bokeh-compiler.min.js?v=28af56ac5
027aa8d0ab96086ec1da10b HTTP/1.1" 304 - "http://domain.url/bokeh_app/sliders" "Mozilla/5.0 (Wi
ndows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
browser_ip - - [22/Apr/2016:15:19:26 +0800] "GET /sliders/ws?bokeh-protocol-version=1.0&bokeh
-session-id=vNWooEyI9G7p5lfds5u9N2nWSQY55VNIAtrfNcheRuv8 HTTP/1.1" 404 208 "-" "Mozilla/5.0 (Wind
ows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

When I open port 5100 and visit domain.url:5100/sliders I can see the figure but behind Apache, I don't get errors in the bokeh-error.log, the static/JS files are not loaded, I can only see the blank page.

Regards,
Hexin

On Thursday, April 21, 2016 at 12:02:09 AM UTC+8, Bryan Van de ven wrote:
Hexin,

When you hit the apache front end, do you see any attempted connection in the bokeh server log? If not, then the connection attempt is never even making it to the bokeh server, in which case what do the apache error/access logs report as to why to connection was not forwarded?

If a connection is making it all the way to the bokeh server, then is there any output in the browser JS console? In particular are the static JS and CSS resources getting loaded? I noticed you removed the alias for static, just to be clear, the BokehJS lib expects to be able to load JS and CSS from "/static/js" and "/static/css" URLs. So you either need to copy those static resources to an existing static dir if you have one as part of the deploy, or let bokeh server do the serving of "/static"

Bryan

> On Apr 20, 2016, at 7:30 AM, Hexin Chen <[email protected]> wrote:
>
> Thank you very much, Bryan!
>
> It's a really detailed walk-through. It took me some time to upgrade Apache from 2.2 to 2.4 and now I've loaded the modules and set the virtual host. However, I got 503 error Service Unavailable. The main site is running fine and the error only occurs when I try to visit the bokeh url
>
> [[email protected] ~]# bokeh serve --log-level=debug --port 5100 --host "pub.domain":80 /var/www/html/bokeh_app/sliders.py
> DEBUG:bokeh.server.tornado:Allowed Host headers: ['pub.domain:80']
> DEBUG:bokeh.server.tornado:These host origins can connect to the websocket: ['pub.domain:80', 'localhost:5100']
> DEBUG:bokeh.server.tornado:Patterns are: [('/sliders/?', <class 'bokeh.server.views.doc_handler.DocHandler'>, {'application_context': <bokeh.server.application_context.ApplicationContext object at 0x7fa1f3f0dad0>, 'bokeh_websocket_path': '/sliders/ws'}), ('/sliders/ws', <class 'bokeh.server.views.ws.WSHandler'>, {'application_context': <bokeh.server.application_context.ApplicationContext object at 0x7fa1f3f0dad0>, 'bokeh_websocket_path': '/sliders/ws'}), ('/sliders/autoload.js', <class 'bokeh.server.views.autoload_js_handler.AutoloadJsHandler'>, {'application_context': <bokeh.server.application_context.ApplicationContext object at 0x7fa1f3f0dad0>, 'bokeh_websocket_path': '/sliders/ws'}), ('/static/(.*)', <class 'bokeh.server.views.static_handler.StaticHandler'>)]
> INFO:bokeh.command.subcommands.serve:Starting Bokeh server on port 5100 with applications at paths ['/sliders']
> DEBUG:bokeh.server.tornado:[pid 25108] 0 clients connected
> DEBUG:bokeh.server.tornado:[pid 25108] /sliders has 0 sessions with 0 unused
> DEBUG:bokeh.server.tornado:[pid 25108] 0 clients connected
> DEBUG:bokeh.server.tornado:[pid 25108] /sliders has 0 sessions with 0 unused
> DEBUG:bokeh.server.tornado:[pid 25108] 0 clients connected
> DEBUG:bokeh.server.tornado:[pid 25108] /sliders has 0 sessions with 0 unused
>
> Here's my httpd.conf
> LoadModule proxy_module modules/mod_proxy.so
> LoadModule proxy_html_module modules/mod_proxy_html.so
> LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
>
> <VirtualHost *:80>
> ServerName pub.domain
>
> CustomLog logs/bokeh-access.log combined
> ErrorLog logs/bokeh-error.log
>
> # for a bokeh server running internally on port 5100
> ProxyPreserveHost On
> ProxyPass /bokeh_app/sliders/ws ws://127.0.0.1:5100/sliders/ws
> ProxyPassReverse /bokeh_app/sliders/ws ws://127.0.0.1:5100/sliders/ws
>
> ProxyPass /bokeh_app/sliders http://127.0.0.1:5100/sliders/
> ProxyPassReverse /bokeh_app/sliders http://127.0.0.1:5100/sliders/
>
> <Directory />
> Require all granted
> Options -Indexes
> </Directory>
>
> </VirtualHost>
>
> Then I also tried to open port 5100 withe firewalld to public, I visited the server.ip:5100/sliders and I can see the plotting.
>
> [[email protected] ~]# bokeh serve --log-level=debug --port 5100 --host srv.ip:5100 /var/www/html/bokeh_app/sliders.py
> DEBUG:bokeh.server.tornado:Allowed Host headers: ['srv.ip:5100']
> DEBUG:bokeh.server.tornado:These host origins can connect to the websocket: ['srv.ip:5100', 'localhost:5100']
> DEBUG:bokeh.server.tornado:Patterns are: [('/sliders/?', <class 'bokeh.server.views.doc_handler.DocHandler'>, {'application_context': <bokeh.server.application_context.ApplicationContext object at 0x7f0000524b10>, 'bokeh_websocket_path': '/sliders/ws'}), ('/sliders/ws', <class 'bokeh.server.views.ws.WSHandler'>, {'application_context': <bokeh.server.application_context.ApplicationContext object at 0x7f0000524b10>, 'bokeh_websocket_path': '/sliders/ws'}), ('/sliders/autoload.js', <class 'bokeh.server.views.autoload_js_handler.AutoloadJsHandler'>, {'application_context': <bokeh.server.application_context.ApplicationContext object at 0x7f0000524b10>, 'bokeh_websocket_path': '/sliders/ws'}), ('/static/(.*)', <class 'bokeh.server.views.static_handler.StaticHandler'>)]
> INFO:bokeh.command.subcommands.serve:Starting Bokeh server on port 5100 with applications at paths ['/sliders']
> DEBUG:bokeh.server.tornado:[pid 29638] 0 clients connected
> DEBUG:bokeh.server.tornado:[pid 29638] /sliders has 0 sessions with 0 unused
> INFO:tornado.access:200 GET /sliders (browser.ip) 69.91ms
> INFO:bokeh.server.views.ws:WebSocket connection opened
> DEBUG:bokeh.server.views.ws:Receiver created for Protocol(u'1.0')
> DEBUG:bokeh.server.views.ws:ServerHandler created for Protocol(u'1.0')
> INFO:bokeh.server.views.ws:ServerConnection created
> DEBUG:bokeh.server.session:Sending pull-doc-reply from session 'KBic9cpoZvfKqVaIaZqcnp92nfjX2Yf9ZFEuerk0l7ZY'
> DEBUG:bokeh.server.tornado:[pid 29638] 1 clients connected
> DEBUG:bokeh.server.tornado:[pid 29638] /sliders has 1 sessions with 0 unused
>
> I don't know why the application is not responding to the requests from Apache, although the settings seems fine to me.
>
> Thanks a lot!
>
> Hexin
>
>
> On Tuesday, April 19, 2016 at 2:58:27 AM UTC+8, Bryan Van de ven wrote:
> Hi Hexin,
>
> OK I did try updating to Apache 2.4 and it works. Here is the configuration I used:
>
>
> <VirtualHost *:8080>
> ServerName localhost
>
> CustomLog "/Users/bryan/Sites/logs/access_log" combined
> ErrorLog "/Users/bryan/Sites/logs/error_log"
>
> ProxyPreserveHost On
> ProxyPass /sliders/ws ws://127.0.0.1:5100/sliders/ws
> ProxyPassReverse /sliders/ws ws://127.0.0.1:5100/sliders/ws
>
> ProxyPass /sliders http://127.0.0.1:5100/sliders/
> ProxyPassReverse /sliders http://127.0.0.1:5100/sliders/
>
>
> <Directory />
> Require all granted
> Options -Indexes
> </Directory>
>
> Alias /static /Users/bryan/work/bokeh/bokeh/server/static
> <Directory /Users/bryan/work/bokeh/bokeh/server/static>
> # directives to effect the static directory
> Options +Indexes
> </Directory>
>
> </VirtualHost>
>
> With this Bokeh server invocation:
>
> bokeh serve --log-level=debug --port 5100 --host localhost:8080 sliders.py
>
> Again you will need to customize for your particular deployment, but hopefully this points the way. As a final note, you do also need to make sure this Apache module is loaded:
>
> https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html
>
> In order for the websocket forwarding to work. I also enabled mod_proxy_html but I don't know if that is necessary and I have to switch to other tasks.
>
> Thanks,
>
> Bryan
>
>
>
>
> > On Apr 18, 2016, at 12:26 PM, Bryan Van de Ven <[email protected]> wrote:
> >
> > Hi Hexin,
> >
> > Here is some more info that might help you further along. I apologize I can't provide a complete example, I have to prepare some talks this week.
> >
> > Using the vhost block below, things *almost* work. It is not connecting the websocket. I gather this is because I have Apache 2.2 installed via OSX brew, and I think you need Apache >= 2.4 (or perhaps extra config with earlier versions) to enable websocket forwarding. I will have to leave figuring that out to you or someone else on the mailing list:
> >
> > <VirtualHost *:8080>
> > ServerName localhost
> >
> > CustomLog "/Users/bryan/Sites/logs/project.dev-access_log" combined
> > ErrorLog "/Users/bryan/Sites/logs/project.dev-error_log"
> >
> > # for a bokeh server running internally on port 5100
> > ProxyPreserveHost On
> > ProxyPass /app http://127.0.0.1:5100/sliders/
> > ProxyPassReverse /app http://127.0.0.1:5100/sliders/
> >
> > <Directory />
> > Order Allow,Deny
> > Allow From All
> > Options -Indexes
> > </Directory>
> >
> > # better to copy BokehJS static files to your normal /static location like this,
> > # but other configurations would be possible...
> >
> > Alias /static /Users/bryan/work/bokeh/bokeh/server/static
> > <Directory /Users/bryan/work/bokeh/bokeh/server/static>
> > # directives to effect the static directory
> > Options +Indexes
> > </Directory>
> >
> > </VirtualHost>
> >
> > Then I ran bokeh server like this:
> >
> > bokeh serve --port 5100 --host localhost:8080 sliders.py
> >
> > With all of this, the initial connection and static resources load fine, but the websocket does not connect. So that is the part to figure out.
> >
> > Things you will want to change for your actual deploy:
> >
> > * the --host should not be localhost:8080, it should be *whatever users will actually navigate to*, i.e. the host name of the public facing apache server
> > * if you want bokeh server to serve the static files instead of copying them too your normal /static location as part of your deploy, you probably want to add a --prefix
> >
> > I look forward to hearing back about how this works out, and also adding a fully complete Apache example to the User's Guide when I can devote time to it.
> >
> > Bryan
> >
> >
> >
> >> On Apr 18, 2016, at 11:04 AM, Bryan Van de Ven <[email protected]> wrote:
> >>
> >> Hi Hexin,
> >>
> >> Nginx is definitely not a requirement. It was simply the case that Nginx happened to be the thing we were familiar with, that we could document well in the time constraints we had. It should definitely be possible to use Bokeh behind other front-ends, and in fact I would very much like to document how to do that.
> >>
> >> Here's a few high-level requirements that might help:
> >>
> >> * Bokeh server apps use websockets. Whatever is in front of the bokeh server needs to be configured to forward websocket traffic. In an Nginx config, you'd have something like:
> >>
> >> proxy_pass http://127.0.0.1:5100;
> >> proxy_set_header Upgrade $http_upgrade;
> >> proxy_set_header Connection "upgrade";
> >> proxy_http_version 1.1;
> >>
> >> Where the ip/port there is the internal ip/port that you have started the bokeh server on. It looks like there is some information about configuring Apache to forward websockets here:
> >>
> >> http://stackoverflow.com/questions/27526281/websockets-and-apache-proxy-how-to-configure-mod-proxy-wstunnel
> >>
> >> * Bokeh server needs to receive the "Host" field from the HTML request. Whatever is in front of the bokeh server needs to forward this. In Nginx, it looks like this:
> >>
> >> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
> >> proxy_set_header Host $host:server\_port; &gt; &gt;&gt; &gt; &gt;&gt; I&#39;m not sure offhand what that looks like for Apache \(I have not used Apache, maybe someone else on the list can chime in\)\. &gt; &gt;&gt; &gt; &gt;&gt; \* The Bokeh server host whitelist needs to have the \*public\-facing\* host added\. So if users are navigating to &quot;foo\.com&quot; then the server needs to be started with &gt; &gt;&gt; &gt; &gt;&gt; \-\-host &quot;foo\.com&quot; &gt; &gt;&gt; &gt; &gt;&gt; This value is matched up with the &quot;Host&quot; that the proxy forwards on to the bokeh server\. They have to match\. This is to guard against certain kinds of malicious attacks that involve spoofing Host fields in requests\. &gt; &gt;&gt; &gt; &gt;&gt; \* You can add multiple \-\-host fields\. If you also want to be able to connect from localhost \(for testing or whatever\) then you&#39;d need to add that, explicitly\. If you don&#39;t specify any \-\-host at all, then bokeh server adds &quot;localhost&quot; as a default, but if you add \*any\* \-\-host then the server \*only\* configures the \-\-host values that are explicitly given \(no more default &quot;localhost&quot;\)\. But note: adding &quot;localhost&quot; to the \-\-host is probably not something you would want to do &quot;in production&quot;, where all access to the server should go through Nginx, or Apache, or whatever\. &gt; &gt;&gt; &gt; &gt;&gt; \* All of this assumes you are not also using/needing SSL \(https\), which would require a few additional configurations for the bokeh server, and probably quite alot of additional configuration for Apache\. &gt; &gt;&gt; &gt; &gt;&gt; \-\-\-\-\-\-\-\-\- &gt; &gt;&gt; &gt; &gt;&gt; For completeness, I will say that another possible option is to simply run the server publicly\-facing and then embed directly from the server using iframes, but there are a number of disadvantages to this approach \(e\.g\. there&#39;s no way to scale things if necessary\)\. &gt; &gt;&gt; &gt; &gt;&gt; Thanks, &gt; &gt;&gt; &gt; &gt;&gt; Bryan &gt; &gt;&gt; &gt; &gt;&gt; &gt; &gt;&gt;&gt; On Apr 18, 2016, at 2:33 AM, Hexin Chen &lt;chenhe\.\.\[email protected]\.com&gt; wrote: &gt; &gt;&gt;&gt; &gt; &gt;&gt;&gt; I&#39;m new to Bokeh and I&#39;m trying to run multiple apps in one directory, like the demo site: &gt; &gt;&gt;&gt; &gt; &gt;&gt;&gt; • http://demo.bokehplots.com/apps/movies &gt; &gt;&gt;&gt; • http://demo.bokehplots.com/apps/selection_histogram &gt; &gt;&gt;&gt; • http://demo.bokehplots.com/apps/weather &gt; &gt;&gt;&gt; First I&#39;ll introduce the enviroment of the server I&#39;m using\. I&#39;m running a RedHat 6\.4 x86\_64 with Apache 2\.2\.15, MySQL 5\.1\.73, and Anaconda 2\.4 \(Python 2\.7, Bokeh 0\.11\.1\)\. I have direct access to the server \(it belongs to my department\) and it has its own IP address\. The web server on port 80 hosts a WordPress blog mainly and serveral static HTML pages, for example, domain\.url will direct to domain\.url/blog/ and that&#39;s the main WP page, there&#39;re links to domain\.url/visualization/processing/ and under processing there&#39;re some Java applets of our visualization projects\. These files and index pages are under /var/www/html/visualization/processing\. &gt; &gt;&gt;&gt; &gt; &gt;&gt;&gt; &gt; &gt;&gt;&gt; &gt; &gt;&gt;&gt; I&#39;m trying to show bokeh apps in a similar ways\. If a vistor goes to domain\.url/visualization/bokeh\_apps, a page will show up like demo\.bokehplots\.com, and then the vistor can click to domain\.url/visualization/bokeh\_apps/proj01, domain\.url/visualization/bokeh\_apps/proj02, etc\. So I assume the Apache server needs to redirect to different bokeh apps on different ports when it recognize the URL path\. &gt; &gt;&gt;&gt; &gt; &gt;&gt;&gt; &gt; &gt;&gt;&gt; &gt; &gt;&gt;&gt; The first problem I ran into is the host whitelist\. I ran the command: &gt; &gt;&gt;&gt; &gt; &gt;&gt;&gt; \[[email protected] bokeh\_apps\] bokeh serve --show myapp --port 5100 --host 127.0.0.1:80
> >>> A Window popped out and I had to quit the "Elinks", and the output kept going:
> >>>
> >>> INFO:bokeh.server.tornado:Rejected connection from host 'localhost:5100' because it is not in the --
> >>> host whitelist
> >>> WARNING
> >>> :tornado.access:403 GET /myapp (::1) 1.71ms
> >>>
> >>> DEBUG
> >>> :bokeh.server.tornado:[pid 834] 0 clients connected
> >>> I googled and all I can find is a GitHub issue page. I read it but don't understand whether there's a solution in the tornado.py.
> >>>
> >>>
> >>>
> >>> The second problem is that I dont' know how to construct the structure.
> >>>
> >>> I tried
> >>>
> >>> cd /var/www/html/visualization/bokeh_apps/
> >>>
> >>> bokeh serve
> >>> --show myapp --port 5100 --host 127.0.0.1:80/visualization/bokeh_apps/
> >>> and it returned "invalid port in host value". When I run locally in Python bokeh serve --show myapp, the address is like "localhost:5006/myapp" and doesn't show any structure. Is there some trick to do this? I searched but didn't find anything.
> >>>
> >>>
> >>>
> >>> Thanks a lot for your help!
> >>>
> >>>
> >>>
> >>> P.S. if Nignx has the solution for these 2 problems, it's still quite unlikely that my supervisor will agree to swtich from Apache...
> >>>
> >>>
> >>> --
> >>> You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
> >>> To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
> >>> To post to this group, send email to [email protected].
> >>> To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/0ff064a9-8d71-4a53-a409-05e5c5763fdd%40continuum.io.
> >>> For more options, visit https://groups.google.com/a/continuum.io/d/optout.
> >>
> >
>
>
> --
> You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
> To post to this group, send email to [email protected].
> To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/151cc948-ff52-405f-b428-528f232add5e%40continuum.io.
> For more options, visit https://groups.google.com/a/continuum.io/d/optout.

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]nuum.io.
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/515f587c-1906-47ad-8eba-a0f16006ee57%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Thanks a lot for the help you offered, Bryan!

I don’t see 404 errors in the console. I also tried to put the static files (/css /js) in the Apache default directory /var/www/html/static. The “Hail Mary” trial didn’t work either.

I searched for a while but can’t get any answers. Probably I’ll just use the port number in the URL, instead behind Apache.

It would be nice if bokeh can generate a package (a JS file/library to load, an HTML file to run the data inside). Then the package can be run offline or online, with or without Python/bokeh environment, and aslo work well inside a web server (without a process thread or port).

Thansk again!

···

On Friday, April 22, 2016 at 10:30:09 PM UTC+8, Bryan Van de ven wrote:

Can you clarify this:

    I don't get errors in the bokeh-error.log, the static/JS files are not loaded, I can only see the blank page.

Do you mean you see the error messages in the JS console reporting 404 for the static assets? If there are no JS console messages about 404, then I think that means the static files are loaded. But if there are errors, and the static JS and CSS files are not loading into the browser, that would explain the blank screen. But then I am afraid I am at the limit of my knowledge, it seems like a web-server/OS configuration issue at this point. Your setup below looks fine to me, but you do mention SELinux. I know SELinux is more restrictive with access controls, but I have never used it so I can’t really offer any advice.

Bryan

On Apr 22, 2016, at 3:16 AM, Hexin Chen [email protected] wrote:

Thank you, Bryan!

I copied the server files from /root/anaconda2/pkgs/bokeh-0.

11.1-py27_0/lib/python2.7/site-packages/bokeh/server and here’s my httpd.conf:

LoadModule proxy_module modules/mod_proxy.so

LoadModule proxy_html_module modules/mod_proxy_html.so

LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so

<VirtualHost *:80>

ServerName domain.url
CustomLog logs/bokeh-access.log combined
ErrorLog logs/bokeh-error.log
# for a bokeh server running internally on port 5100
ProxyPreserveHost On
ProxyPass /bokeh_app/sliders/ws ws://[127.0.0.1:5100/sliders/ws](http://127.0.0.1:5100/sliders/ws)
ProxyPassReverse /bokeh_app/sliders/ws ws://[127.0.0.1:5100/sliders/ws](http://127.0.0.1:5100/sliders/ws)
ProxyPass /bokeh_app/sliders [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)
ProxyPassReverse /bokeh_app/sliders [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)
<Directory />
    Require all granted
    Options -Indexes
</Directory>
# better to copy BokehJS static files to your normal /static location like this,
# but other configurations would be possible...
Alias /static /var/www/html/bokeh_app/static
<Directory /var/www/html/bokeh_app/static>
    # directives to effect the static directory
    Options +Indexes
</Directory>

I also changed the SELinux setting so now I dont’ get 503

setsebool -P httpd_can_network_connect 1

But I still can’t see the app, its just a blank page with “Bokeh Application” and a favicon. Here’s the access log:

browser_ip - - [22/Apr/2016:15:06:44 +0800] “GET /bokeh_app/sliders HTTP/1.1” 200 1421 “-” "M

ozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

browser_ip - - [22/Apr/2016:15:06:44 +0800] "GET /static/css/bokeh.min.css?v=25ce17349a0082e9

eeac845e42a822ec HTTP/1.1" 304 - “http://domain.url/bokeh_app/sliders” "Mozilla/5.0 (Windows N

T 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

browser_ip - - [22/Apr/2016:15:06:44 +0800] "GET /static/css/bokeh-widgets.min.css?v=3b73ec63

df304369ffc9c7e5132463cd HTTP/1.1" 304 - “http://domain.url/bokeh_app/sliders” "Mozilla/5.0 (W

indows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

browser_ip - - [22/Apr/2016:15:06:44 +0800] "GET /static/js/bokeh.min.js?v=50ffae624cbe67773b

5995270f946406 HTTP/1.1" 304 - “http://domain.url/bokeh_app/sliders” "Mozilla/5.0 (Windows NT

6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

browser_ip - - [22/Apr/2016:15:06:44 +0800] "GET /static/js/bokeh-widgets.min.js?v=7cfd458197

bc395bb09e9dc3b8ac7975 HTTP/1.1" 304 - “http://domain.url/bokeh_app/sliders” "Mozilla/5.0 (Win

dows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

browser_ip - - [22/Apr/2016:15:06:44 +0800] "GET /static/js/bokeh-compiler.min.js?v=28af56ac5

027aa8d0ab96086ec1da10b HTTP/1.1" 304 - “http://domain.url/bokeh_app/sliders” "Mozilla/5.0 (Wi

ndows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

browser_ip - - [22/Apr/2016:15:06:45 +0800] "GET /sliders/ws?bokeh-protocol-version=1.0&bokeh

-session-id=XSoe5MvuiIrei4vFFcLlEAze6VNcqc5WF3ADzlFbHuVx HTTP/1.1" 404 208 “-” "Mozilla/5.0 (Wind

ows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

::1 - - [22/Apr/2016:15:18:31 +0800] “OPTIONS * HTTP/1.0” 200 - “-” "Apache/2.4.6 (CentOS) OpenSS

L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"

::1 - - [22/Apr/2016:15:18:31 +0800] “OPTIONS * HTTP/1.0” 200 - “-” "Apache/2.4.6 (CentOS) OpenSS

L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"

::1 - - [22/Apr/2016:15:18:31 +0800] “OPTIONS * HTTP/1.0” 200 - “-” "Apache/2.4.6 (CentOS) OpenSS

L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"

::1 - - [22/Apr/2016:15:18:31 +0800] “OPTIONS * HTTP/1.0” 200 - “-” "Apache/2.4.6 (CentOS) OpenSS

L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"

::1 - - [22/Apr/2016:15:18:31 +0800] “OPTIONS * HTTP/1.0” 200 - “-” "Apache/2.4.6 (CentOS) OpenSS

L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"

::1 - - [22/Apr/2016:15:18:31 +0800] “OPTIONS * HTTP/1.0” 200 - “-” "Apache/2.4.6 (CentOS) OpenSS

L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"

::1 - - [22/Apr/2016:15:18:31 +0800] “OPTIONS * HTTP/1.0” 200 - “-” "Apache/2.4.6 (CentOS) OpenSS

L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"

::1 - - [22/Apr/2016:15:18:31 +0800] “OPTIONS * HTTP/1.0” 200 - “-” "Apache/2.4.6 (CentOS) OpenSS

L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"

::1 - - [22/Apr/2016:15:18:31 +0800] “OPTIONS * HTTP/1.0” 200 - “-” "Apache/2.4.6 (CentOS) OpenSS

L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"

browser_ip - - [22/Apr/2016:15:18:41 +0800] “GET /bokeh_app/sliders HTTP/1.1” 200 1421 “-” "M

ozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

browser_ip - - [22/Apr/2016:15:18:41 +0800] "GET /static/css/bokeh.min.css?v=25ce17349a0082e9

eeac845e42a822ec HTTP/1.1" 304 - “http://domain.url/bokeh_app/sliders” "Mozilla/5.0 (Windows N

T 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

browser_ip - - [22/Apr/2016:15:18:41 +0800] "GET /static/css/bokeh-widgets.min.css?v=3b73ec63

df304369ffc9c7e5132463cd HTTP/1.1" 304 - “http://domain.url/bokeh_app/sliders” "Mozilla/5.0 (W

indows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

browser_ip - - [22/Apr/2016:15:18:41 +0800] "GET /static/js/bokeh.min.js?v=50ffae624cbe67773b

5995270f946406 HTTP/1.1" 304 - “http://domain.url/bokeh_app/sliders” "Mozilla/5.0 (Windows NT

6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

browser_ip - - [22/Apr/2016:15:18:41 +0800] "GET /static/js/bokeh-widgets.min.js?v=7cfd458197

bc395bb09e9dc3b8ac7975 HTTP/1.1" 304 - “http://domain.url/bokeh_app/sliders” "Mozilla/5.0 (Win

dows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

browser_ip - - [22/Apr/2016:15:18:41 +0800] "GET /static/js/bokeh-compiler.min.js?v=28af56ac5

027aa8d0ab96086ec1da10b HTTP/1.1" 304 - “http://domain.url/bokeh_app/sliders” "Mozilla/5.0 (Wi

ndows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

browser_ip - - [22/Apr/2016:15:18:41 +0800] "GET /sliders/ws?bokeh-protocol-version=1.0&bokeh

-session-id=yDtvnCf7PKSFacQEHScfcZpTGLcp00IQ5FW8wYKNqHUF HTTP/1.1" 404 208 “-” "Mozilla/5.0 (Wind

ows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

::1 - - [22/Apr/2016:15:18:46 +0800] “OPTIONS * HTTP/1.0” 200 - “-” "Apache/2.4.6 (CentOS) OpenSS

L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"

::1 - - [22/Apr/2016:15:18:47 +0800] “OPTIONS * HTTP/1.0” 200 - “-” "Apache/2.4.6 (CentOS) OpenSS

L/1.0.1e-fips mod_fcgid/2.3.9 PHP/5.4.16 mod_wsgi/3.4 Python/2.7.5 (internal dummy connection)"

browser_ip - - [22/Apr/2016:15:19:25 +0800] “GET /bokeh_app/sliders HTTP/1.1” 200 1421 “-” "M

ozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

browser_ip - - [22/Apr/2016:15:19:25 +0800] "GET /static/css/bokeh.min.css?v=25ce17349a0082e9

eeac845e42a822ec HTTP/1.1" 304 - “http://domain.url/bokeh_app/sliders” "Mozilla/5.0 (Windows N

T 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

browser_ip - - [22/Apr/2016:15:19:25 +0800] "GET /static/css/bokeh-widgets.min.css?v=3b73ec63

df304369ffc9c7e5132463cd HTTP/1.1" 304 - “http://domain.url/bokeh_app/sliders” "Mozilla/5.0 (W

indows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

browser_ip - - [22/Apr/2016:15:19:25 +0800] "GET /static/js/bokeh.min.js?v=50ffae624cbe67773b

5995270f946406 HTTP/1.1" 304 - “http://domain.url/bokeh_app/sliders” “Mozilla/5.0 (Windows NT
6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0”

browser_ip - - [22/Apr/2016:15:19:25 +0800] "GET /static/js/bokeh-widgets.min.js?v=7cfd458197

bc395bb09e9dc3b8ac7975 HTTP/1.1" 304 - “http://domain.url/bokeh_app/sliders” "Mozilla/5.0 (Win

dows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

browser_ip - - [22/Apr/2016:15:19:25 +0800] "GET /static/js/bokeh-compiler.min.js?v=28af56ac5

027aa8d0ab96086ec1da10b HTTP/1.1" 304 - “http://domain.url/bokeh_app/sliders” "Mozilla/5.0 (Wi

ndows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

browser_ip - - [22/Apr/2016:15:19:26 +0800] "GET /sliders/ws?bokeh-protocol-version=1.0&bokeh

-session-id=vNWooEyI9G7p5lfds5u9N2nWSQY55VNIAtrfNcheRuv8 HTTP/1.1" 404 208 “-” "Mozilla/5.0 (Wind

ows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

When I open port 5100 and visit domain.url:5100/sliders I can see the figure but behind Apache, I don’t get errors in the bokeh-error.log, the static/JS files are not loaded, I can only see the blank page.

Regards,

Hexin

On Thursday, April 21, 2016 at 12:02:09 AM UTC+8, Bryan Van de ven wrote:

Hexin,

When you hit the apache front end, do you see any attempted connection in the bokeh server log? If not, then the connection attempt is never even making it to the bokeh server, in which case what do the apache error/access logs report as to why to connection was not forwarded?

If a connection is making it all the way to the bokeh server, then is there any output in the browser JS console? In particular are the static JS and CSS resources getting loaded? I noticed you removed the alias for static, just to be clear, the BokehJS lib expects to be able to load JS and CSS from “/static/js” and “/static/css” URLs. So you either need to copy those static resources to an existing static dir if you have one as part of the deploy, or let bokeh server do the serving of “/static”

Bryan

On Apr 20, 2016, at 7:30 AM, Hexin Chen [email protected] wrote:

Thank you very much, Bryan!

It’s a really detailed walk-through. It took me some time to upgrade Apache from 2.2 to 2.4 and now I’ve loaded the modules and set the virtual host. However, I got 503 error Service Unavailable. The main site is running fine and the error only occurs when I try to visit the bokeh url

[[email protected] ~]# bokeh serve --log-level=debug --port 5100 --host “pub.domain”:80 /var/www/html/bokeh_app/sliders.py
DEBUG:bokeh.server.tornado:Allowed Host headers: [‘pub.domain:80’]
DEBUG:bokeh.server.tornado:These host origins can connect to the websocket: [‘pub.domain:80’, ‘localhost:5100’]
DEBUG:bokeh.server.tornado:Patterns are: [(’/sliders/?’, <class ‘bokeh.server.views.doc_handler.DocHandler’>, {‘application_context’: <bokeh.server.application_context.ApplicationContext object at 0x7fa1f3f0dad0>, ‘bokeh_websocket_path’: ‘/sliders/ws’}), (’/sliders/ws’, <class ‘bokeh.server.views.ws.WSHandler’>, {‘application_context’: <bokeh.server.application_context.ApplicationContext object at 0x7fa1f3f0dad0>, ‘bokeh_websocket_path’: ‘/sliders/ws’}), (’/sliders/autoload.js’, <class ‘bokeh.server.views.autoload_js_handler.AutoloadJsHandler’>, {‘application_context’: <bokeh.server.application_context.ApplicationContext object at 0x7fa1f3f0dad0>, ‘bokeh_websocket_path’: ‘/sliders/ws’}), (’/static/(.*)’, <class ‘bokeh.server.views.static_handler.StaticHandler’>)]
INFO:bokeh.command.subcommands.serve:Starting Bokeh server on port 5100 with applications at paths [’/sliders’]
DEBUG:bokeh.server.tornado:[pid 25108] 0 clients connected
DEBUG:bokeh.server.tornado:[pid 25108] /sliders has 0 sessions with 0 unused
DEBUG:bokeh.server.tornado:[pid 25108] 0 clients connected
DEBUG:bokeh.server.tornado:[pid 25108] /sliders has 0 sessions with 0 unused
DEBUG:bokeh.server.tornado:[pid 25108] 0 clients connected
DEBUG:bokeh.server.tornado:[pid 25108] /sliders has 0 sessions with 0 unused

Here’s my httpd.conf
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_html_module modules/mod_proxy_html.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so

<VirtualHost *:80>
ServerName pub.domain

CustomLog logs/bokeh-access.log combined            
ErrorLog logs/bokeh-error.log

# for a bokeh server running internally on port 5100
ProxyPreserveHost On
ProxyPass /bokeh_app/sliders/ws ws://[127.0.0.1:5100/sliders/ws](http://127.0.0.1:5100/sliders/ws)
ProxyPassReverse /bokeh_app/sliders/ws ws://[127.0.0.1:5100/sliders/ws](http://127.0.0.1:5100/sliders/ws)
ProxyPass /bokeh_app/sliders [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)
ProxyPassReverse /bokeh_app/sliders [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)
<Directory />
    Require all granted
    Options -Indexes
</Directory>

Then I also tried to open port 5100 withe firewalld to public, I visited the server.ip:5100/sliders and I can see the plotting.

[[email protected] ~]# bokeh serve --log-level=debug --port 5100 --host srv.ip:5100 /var/www/html/bokeh_app/sliders.py
DEBUG:bokeh.server.tornado:Allowed Host headers: [‘srv.ip:5100’]
DEBUG:bokeh.server.tornado:These host origins can connect to the websocket: [‘srv.ip:5100’, ‘localhost:5100’]
DEBUG:bokeh.server.tornado:Patterns are: [(’/sliders/?’, <class ‘bokeh.server.views.doc_handler.DocHandler’>, {‘application_context’: <bokeh.server.application_context.ApplicationContext object at 0x7f0000524b10>, ‘bokeh_websocket_path’: ‘/sliders/ws’}), (’/sliders/ws’, <class ‘bokeh.server.views.ws.WSHandler’>, {‘application_context’: <bokeh.server.application_context.ApplicationContext object at 0x7f0000524b10>, ‘bokeh_websocket_path’: ‘/sliders/ws’}), (’/sliders/autoload.js’, <class ‘bokeh.server.views.autoload_js_handler.AutoloadJsHandler’>, {‘application_context’: <bokeh.server.application_context.ApplicationContext object at 0x7f0000524b10>, ‘bokeh_websocket_path’: ‘/sliders/ws’}), (’/static/(.*)’, <class ‘bokeh.server.views.static_handler.StaticHandler’>)]
INFO:bokeh.command.subcommands.serve:Starting Bokeh server on port 5100 with applications at paths [’/sliders’]
DEBUG:bokeh.server.tornado:[pid 29638] 0 clients connected
DEBUG:bokeh.server.tornado:[pid 29638] /sliders has 0 sessions with 0 unused
INFO:tornado.access:200 GET /sliders (browser.ip) 69.91ms
INFO:bokeh.server.views.ws:WebSocket connection opened
DEBUG:bokeh.server.views.ws:Receiver created for Protocol(u’1.0’)
DEBUG:bokeh.server.views.ws:ServerHandler created for Protocol(u’1.0’)
INFO:bokeh.server.views.ws:ServerConnection created
DEBUG:bokeh.server.session:Sending pull-doc-reply from session ‘KBic9cpoZvfKqVaIaZqcnp92nfjX2Yf9ZFEuerk0l7ZY’
DEBUG:bokeh.server.tornado:[pid 29638] 1 clients connected
DEBUG:bokeh.server.tornado:[pid 29638] /sliders has 1 sessions with 0 unused

I don’t know why the application is not responding to the requests from Apache, although the settings seems fine to me.

Thanks a lot!

Hexin

On Tuesday, April 19, 2016 at 2:58:27 AM UTC+8, Bryan Van de ven wrote:
Hi Hexin,

OK I did try updating to Apache 2.4 and it works. Here is the configuration I used:

<VirtualHost *:8080>
    ServerName localhost

    CustomLog "/Users/bryan/Sites/logs/access_log" combined
    ErrorLog "/Users/bryan/Sites/logs/error_log"

    ProxyPreserveHost On
    ProxyPass /sliders/ws ws://[127.0.0.1:5100/sliders/ws](http://127.0.0.1:5100/sliders/ws)
    ProxyPassReverse /sliders/ws ws://[127.0.0.1:5100/sliders/ws](http://127.0.0.1:5100/sliders/ws)
    ProxyPass /sliders [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)
    ProxyPassReverse /sliders [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)
    <Directory />
        Require all granted
        Options -Indexes
    </Directory>

    Alias /static /Users/bryan/work/bokeh/bokeh/server/static
    <Directory /Users/bryan/work/bokeh/bokeh/server/static>
        # directives to effect the static directory
        Options +Indexes
    </Directory>

</VirtualHost>

With this Bokeh server invocation:

    bokeh serve --log-level=debug --port 5100 --host localhost:8080 sliders.py

Again you will need to customize for your particular deployment, but hopefully this points the way. As a final note, you do also need to make sure this Apache module is loaded:

    [https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html](https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html)

In order for the websocket forwarding to work. I also enabled mod_proxy_html but I don’t know if that is necessary and I have to switch to other tasks.

Thanks,

Bryan

On Apr 18, 2016, at 12:26 PM, Bryan Van de Ven [email protected] wrote:

Hi Hexin,

Here is some more info that might help you further along. I apologize I can’t provide a complete example, I have to prepare some talks this week.

Using the vhost block below, things almost work. It is not connecting the websocket. I gather this is because I have Apache 2.2 installed via OSX brew, and I think you need Apache >= 2.4 (or perhaps extra config with earlier versions) to enable websocket forwarding. I will have to leave figuring that out to you or someone else on the mailing list:

<VirtualHost *:8080>
ServerName localhost

 CustomLog "/Users/bryan/Sites/logs/project.dev-access_log" combined
 ErrorLog "/Users/bryan/Sites/logs/project.dev-error_log"

 # for a bokeh server running internally on port 5100
 ProxyPreserveHost On
 ProxyPass /app [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)
 ProxyPassReverse /app [http://127.0.0.1:5100/sliders/](http://127.0.0.1:5100/sliders/)
 <Directory />
     Order Allow,Deny
     Allow From All
     Options -Indexes
 </Directory>

 # better to copy BokehJS static files to your normal /static location like this,
 # but other configurations would be possible...

 Alias /static /Users/bryan/work/bokeh/bokeh/server/static
 <Directory /Users/bryan/work/bokeh/bokeh/server/static>
     # directives to effect the static directory
     Options +Indexes
 </Directory>

Then I ran bokeh server like this:

    bokeh serve --port 5100 --host localhost:8080 sliders.py

With all of this, the initial connection and static resources load fine, but the websocket does not connect. So that is the part to figure out.

Things you will want to change for your actual deploy:

  • the --host should not be localhost:8080, it should be whatever users will actually navigate to, i.e. the host name of the public facing apache server
  • if you want bokeh server to serve the static files instead of copying them too your normal /static location as part of your deploy, you probably want to add a --prefix

I look forward to hearing back about how this works out, and also adding a fully complete Apache example to the User’s Guide when I can devote time to it.

Bryan

On Apr 18, 2016, at 11:04 AM, Bryan Van de Ven [email protected] wrote:

Hi Hexin,

Nginx is definitely not a requirement. It was simply the case that Nginx happened to be the thing we were familiar with, that we could document well in the time constraints we had. It should definitely be possible to use Bokeh behind other front-ends, and in fact I would very much like to document how to do that.

Here’s a few high-level requirements that might help:

  • Bokeh server apps use websockets. Whatever is in front of the bokeh server needs to be configured to forward websocket traffic. In an Nginx config, you’d have something like:

      proxy_pass [http://127.0.0.1:5100](http://127.0.0.1:5100);
      proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "upgrade";
      proxy_http_version 1.1;
    

Where the ip/port there is the internal ip/port that you have started the bokeh server on. It looks like there is some information about configuring Apache to forward websockets here:

    [http://stackoverflow.com/questions/27526281/websockets-and-apache-proxy-how-to-configure-mod-proxy-wstunnel](http://stackoverflow.com/questions/27526281/websockets-and-apache-proxy-how-to-configure-mod-proxy-wstunnel)
  • Bokeh server needs to receive the “Host” field from the HTML request. Whatever is in front of the bokeh server needs to forward this. In Nginx, it looks like this:

      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $host:$server_port;
    

I’m not sure offhand what that looks like for Apache (I have not used Apache, maybe someone else on the list can chime in).

  • The Bokeh server host whitelist needs to have the public-facing host added. So if users are navigating to “foo.com” then the server needs to be started with

      --host "[foo.com](http://foo.com)"
    

This value is matched up with the “Host” that the proxy forwards on to the bokeh server. They have to match. This is to guard against certain kinds of malicious attacks that involve spoofing Host fields in requests.

  • You can add multiple --host fields. If you also want to be able to connect from localhost (for testing or whatever) then you’d need to add that, explicitly. If you don’t specify any --host at all, then bokeh server adds “localhost” as a default, but if you add any --host then the server only configures the --host values that are explicitly given (no more default “localhost”). But note: adding “localhost” to the --host is probably not something you would want to do “in production”, where all access to the server should go through Nginx, or Apache, or whatever.

  • All of this assumes you are not also using/needing SSL (https), which would require a few additional configurations for the bokeh server, and probably quite alot of additional configuration for Apache.


For completeness, I will say that another possible option is to simply run the server publicly-facing and then embed directly from the server using iframes, but there are a number of disadvantages to this approach (e.g. there’s no way to scale things if necessary).

Thanks,

Bryan

On Apr 18, 2016, at 2:33 AM, Hexin Chen [email protected] wrote:

I’m new to Bokeh and I’m trying to run multiple apps in one directory, like the demo site:

    • [http://demo.bokehplots.com/apps/movies](http://demo.bokehplots.com/apps/movies)
    • [http://demo.bokehplots.com/apps/selection_histogram](http://demo.bokehplots.com/apps/selection_histogram)
    • [http://demo.bokehplots.com/apps/weather](http://demo.bokehplots.com/apps/weather)

First I’ll introduce the enviroment of the server I’m using. I’m running a RedHat 6.4 x86_64 with Apache 2.2.15, MySQL 5.1.73, and Anaconda 2.4 (Python 2.7, Bokeh 0.11.1). I have direct access to the server (it belongs to my department) and it has its own IP address. The web server on port 80 hosts a WordPress blog mainly and serveral static HTML pages, for example, domain.url will direct to domain.url/blog/ and that’s the main WP page, there’re links to domain.url/visualization/processing/ and under processing there’re some Java applets of our visualization projects. These files and index pages are under /var/www/html/visualization/processing.

I’m trying to show bokeh apps in a similar ways. If a vistor goes to domain.url/visualization/bokeh_apps, a page will show up like demo.bokehplots.com, and then the vistor can click to domain.url/visualization/bokeh_apps/proj01, domain.url/visualization/bokeh_apps/proj02, etc. So I assume the Apache server needs to redirect to different bokeh apps on different ports when it recognize the URL path.

The first problem I ran into is the host whitelist. I ran the command:

[[email protected] bokeh_apps]$ bokeh serve --show myapp --port 5100 --host 127.0.0.1:80

A Window popped out and I had to quit the “Elinks”, and the output kept going:

INFO:bokeh.server.tornado:Rejected connection from host ‘localhost:5100’ because it is not in the –
host whitelist
WARNING
:tornado.access:403 GET /myapp (::1) 1.71ms

DEBUG
:bokeh.server.tornado:[pid 834] 0 clients connected
I googled and all I can find is a GitHub issue page. I read it but don’t understand whether there’s a solution in the tornado.py.

The second problem is that I dont’ know how to construct the structure.

I tried

cd /var/www/html/visualization/bokeh_apps/

bokeh serve
–show myapp --port 5100 --host 127.0.0.1:80/visualization/bokeh_apps/

and it returned “invalid port in host value”. When I run locally in Python bokeh serve --show myapp, the address is like “localhost:5006/myapp” and doesn’t show any structure. Is there some trick to do this? I searched but didn’t find anything.

Thanks a lot for your help!

P.S. if Nignx has the solution for these 2 problems, it’s still quite unlikely that my supervisor will agree to swtich from Apache…


You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/0ff064a9-8d71-4a53-a409-05e5c5763fdd%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.


You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/151cc948-ff52-405f-b428-528f232add5e%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.


You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/515f587c-1906-47ad-8eba-a0f16006ee57%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.