✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🐇 Announcing Dash VTK for 3d simulation graphics. Check out the March webinar.

Serving dash app from a subdirectory using nginx

My dash app is running on port 7000
I’ve configured it to be proxied by Nginx as follows

  location /godash {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_set_header X-Script-Name /godash;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_max_temp_file_size 0;
        rewrite /godash/(.*) /godash/$1  break;
        proxy_pass http://localhost:7000;
        proxy_redirect off;
        proxy_read_timeout 240s;
    }

Even with all of this, it seems dash is trying to server everything from the root ‘/’
I get errors like this

Refused to execute script from 'https://mysite.example.com/_dash-component-suites/dash_renderer/polyfill@7.v1_3_0m1586525360.8.7.min.js'

I would expect everything to be served from
https://mysite.example.com/godash yet assets and _dash-components are being served from the root instead.

Is there a way to tell dash to serve everything from a specific path instead of the root ‘/’?

1 Like

I’m making some progress.
In my .py file I know hardcode the requests_pathname_prefix and routes_pathname_prefix.

app = dash.Dash(
name, routes_pathname_prefix=’/godash/’, requests_pathname_prefix=’/godash/’, meta_tags=[{“name”: “viewport”, “content”: “width=device-width”}]
)

It still isn’t working but I’m seeing fewer errors in the console.
Now I get the following in the console:

VM3879:1 POST https://godata.moh.gov.jm/godash/_dash-update-component 500
react_devtools_backend.js:6 
{message: "Callback error updating live-update-data.children", html: "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final/…ded or there is an error in the application.</p>↵"}
html: "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">↵<title>500 Internal Server Error</title>↵<h1>Internal Server Error</h1>↵<p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>↵"
message: "Callback error updating live-update-data.children"
__proto__: Object

Thankfully the Callback error above was unrelated to the issue.
My code was dependent on a csv file with some data which was not shipped with the production repository.

In the end I made use of url_base_pathname.

app = dash.Dash(
    __name__, url_base_pathname='/godash/']

I plan to iterate on this solution a bit, below are two options for how that might look:

Plan A - see if I can read headers from nginx to set the path

Need to research this. It would involve detecting a special header that I might make up like X-Base-Path, then reading that header from my python file see below:

  location /godash {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_set_header X-Base-Path /godash/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_max_temp_file_size 0;
        rewrite /godash/(.*) /godash/$1  break;
        proxy_pass http://localhost:7000;
        proxy_redirect off;
        proxy_read_timeout 240s;
    }

Plan B - set the path with an environment variable

The code might look like this in my python file.

import os
BASE_PATH = os.getenv("DASH_BASE_PATHNAME","/")
app = dash.Dash(
    __name__, url_base_pathname=BASE_PATH
)

This would mean the path would default to “/” but allow me to customise using enviroment variables.

export DASH_BASE_PATHNAME=/godash/

I haven’t fully researched Plan A so I’m sticking with Plan B for now.