Basic deployment on nginx

I am trying to deploy a panel app under nginx, but the app doesn’t seem to want to use a CDN
Example output on the browser console:

GET
	http://(myhost)/static/extensions/panel/bundled/datatabulator/tabulator-tables@5.4.4/dist/css/tabulator_bootstrap4.min.css
Status
404
Not Found
VersionHTTP/1.1
Transferred183 B (22 B size)
Referrer Policystrict-origin-when-cross-origin
DNS ResolutionSystem

What I’ve tried so far


import panel as pn
pn.config.inline = False
pn.config.npm_cdn = 'https://unpkg.com'

import bokeh
bokeh.settings.resources = 'cdn'

Is there another setting I’m missing somewhere?

OK, so I’ve done some more problem investigation and found the “static_url” argument to pn.serve

By setting that, I got nginx to send most of the requests down to the right application to get the javascript out of the panel-app’s virtual environment, but there seem to be a few places where the panel app is requesting javascript without honoring the static_url setting:

A whole bunch of bokeh requests: /static/js/bokeh-XXX files plus one panel javascript file:
http://(my-host)/static/extensions/panel/panel.min.js?v=20d2cb096d1ab41a4140246d12f07bf6b8cb743fd48122b72532c03d44c5c14a

Why do you want to force it to use a cdn?

So, I have an nginx server that serves as the proxy-server for all the web-apps for my team. It currently hosts a flask app, a FastAPI app, and now this new panel app.

My original thought was that if the javascript data comes from a cdn, then my nginx server doesn’t have to keep track of different versions of everything for each app: All three apps are on different versions of bokeh, for example. The general plan is for Panel to become more of a team standard, and I’d want each app to get the right versions of everything as all the apps get updated at different rates and maybe want different versions of things.

It turns out that the second message I posted where I thought static_url was helping is not true: I actually had forced the nginx server to temporarily serve /static/panel stuff out of the panel app’s virtual environment (which was safe because this is the only panel app at the moment, even if that’s not true in the future).

I don’t know how to make a “minimum reproducible test case” when there’s an nginx server involved. But, if I can make the panel app get it’s static data from an URL that I can put in a “location” block in nginx (so /this-particular-app/static" rather than just “/static”, I think that would work rather than getting via CDN.

OK, so for anyone else that is trying to deploy a panel app on nginx, this worked:

in nginx config, define the URL where you want to host the app, and the address/port where the app will live

server {
  ... lots of other stuff omitted ....

  location /the-app-base-url {
      proxy_pass http://the-app-base-url;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_http_version 1.1;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_buffering off;
    }
}

upstream the-app-base-url {
  server 127.0.0.1:12345;
}

When calling panel serve,
set the following args:

  • port to match port in the upstream
  • address to match the address in the upstream
  • websocket_origin to match your nginx host
  • prefix to /the-app-base-url

The part of the app that goes to / when serving in a dev environment now goes to /the-app-base-url/the-app-base-url under nginx and it should all work

Trying to have just one /the-app-base-url did not work!

1 Like

Hi @j-carson

Glad you made it. Welcome to the community and thanks so much for sharing your solution. It helps build the community knowledge base.