Problems with deploying dash on a virtual server behind a fire wall

Hi, dash deployment newbie here.

I am trying to deploy a dash app on a virtual LINUX server

PRETTY_NAME=“Debian GNU/Linux 12 (bookworm)”
with dash status

dash                      2.17.1
dash-bootstrap-components 1.6.0
dash-core-components      2.0.0
dash-html-components      2.0.0
dash-table                5.0.0

The virtual server (10.20.0.30) has been assigned an external IP address (say A.B.C.D) but no domain name. External requests to port 8050 are open to the virtual server (as is port 80).
I have a NGINX configuration (as below) that does a proxy_pass from port 80 to port 8050 for http requests coming to A.B.C.D. I have no (or very little) control over firewall policy, or server setup (except NGINX configuration)

server {
        listen 80;
        server_name A.B.C.D;
        location / {
                include proxy_params;
                proxy_buffering off;
                proxy_pass http://10.20.0.30:8050;
        }
}

So there are three ways to get to my app:
on the local network browse to 10.20.0.30:8050
on the internet browse to A.B.C.D:8050
on the internet browse to A.B.C.D (relying on NGINX)

I have a minimal HelloWorld Flask app:

from flask import Flask
app = Flask(__name__)
@app.route("/")
def helloworld():
    print('Inside hello world - all ip adr')
    return "Hello World Minimal 0.0.0.0:8050!"

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=8050)

All three ways to access the minimal Flask app work as expected

I have a minimal dash app

from dash import Dash, html
app = Dash()
app.layout = html.Div([html.Div(children='Hello World: Minimal dash 8050')])

if __name__ == '__main__':
    print('Running minimal dash app on 8050')
    app.run(debug=False, port=8050, host='0.0.0.0')
# end if

Of the three ways to get to my app, only the local 10.20.0.30:8050 works as expected.
The other two ways (A.B.C.D and A.B.C.D:8050) just hang (I can see the HTTP request turn up). But if I try to retrieve to JSON layout by A.B.C.D/_dash-layout or A.B.C.D:8050/_dash-layout, the I get back the expected layout .

{“props”:{“children”:[{“props”:{“children”:“Hello World: Minimal dash 8050”},“type”:“Div”,“namespace”:“dash_html_components”}]},“type”:“Div”,“namespace”:“dash_html_components”}

So the network configuration seems OK. Data can flow between my app and the external internet.

I have held off using a WSGI server until I get the simplest setup working.

My setup seems to be unusual in that I have only a raw IP address A.B.C.D, and not a domain name. Can anybody suggest how to instrument / debug dash, to identify why a Flask app works as expected but Dash apps don’t. I don’t think NGINX is at fault, because a direct internet request using the 8050 port fails too (should be independent of NGINX) I’m guessing it might be because when I start the Dash app, it doesn’t know what external IP address (A.B.C.D) it is supposed to be serving as?

Thanks in advance

Hi

Problem was in setup of the virtual server.

Quote from sysadmin below:

Evidently, the Dash app doesn’t play well with the transmission units/data packets threshold currently set on the Debian server, unlike the Flask app. Something in the way it transmits/sends over data and elements overwhelming the connection. That said, I’ve now adjusted the server to a lower transmission max limit to make it so that the data would be sent in smaller chunks instead—allowing it to pass through the entire network path with no hiccups. As a result, the Dash app now fully loads

As indeed it does. The minimal dash app sends back about 3800 bytes in its first response to a http request.

Hello @donrcameron,

Welcome to the forums.

That is an interesting issue for sure. Were you able to get it resolved by the sysadmin making that adjustment?

Hi jinnyzor

Yep, the app worked just fine after the networking changes. It was amusing that I developed a vast range of theories that were all wrong (e.g. maybe it’s because I only have a IP address, not a DNS name; or maybe it’s because there are some unicode escaped characters in the dash initial packet cause the payload length calculations to be wrong somewhere; or maybe in the app<->nginx<->virtual server<->real server> chain, the Connection: KeepAlive vs Connection: Close was causing problems).

Getting a hanging small example flask app with a route that executed the dash initialization

zz = Dash().index()
return zz

was helpful in showing the only initial payload was related to the problem, as was a simple python client to do a single HTTP GET. Using a browser to debug is troublesome, as browsers do pre-fetch on hover, and they always want a icon file, and they retry at unexpected times, which makes matching up debug print statements with client activity a bit harder. Using Dash, there is a flurry of HTTP activity after the initial HTTP GET, that can be hard to follow.

I don’t know how Debian was re-configured, but other stuff (like github pushes) started working too

Cheers
Don Cameron

1 Like