(nginx+gunicorn+flask+dash) dash Firewall problem

I set up a website with flask and dash. I configured gunicorn and nginx, and deployed the app on a virtual server. I registered the domain, and all was working fine, with the website accessible from the Internet.

Then, our network administrator updated the firewall, and now flask works, but not dash.
All still works correctly if I access the website from 127.0.0.1 from a locally running browser.

If I access the website from the Internet, I get an empty page instead of the app, when accessing its routes_pathname_prefix, and on the console of the browser I get the following error:

dash_renderer.v2_10_2m1730126951.min.js:2 Error: Minified Redux error #14; visit https://redux.js.org/Errors?code=14 for the full message or use the non-minified dev environment for full errors. 
    at dash_renderer.v2_10_2m1730126951.min.js:2:106040
    at dash_renderer.v2_10_2m1730126951.min.js:2:194804
    at dash_renderer.v2_10_2m1730126951.min.js:2:194659
    at p (dash_renderer.v2_10_2m1730126951.min.js:2:67849)
    at dash_renderer.v2_10_2m1730126951.min.js:2:69045
    at Ds (dash_renderer.v2_10_2m1730126951.min.js:2:231090)
    at commitHookEffectListMount (react-dom@16.v2_10_2m1730126952.14.0.js:19866:28)
    at commitPassiveHookEffects (react-dom@16.v2_10_2m1730126952.14.0.js:19904:13)
    at HTMLUnknownElement.callCallback (react-dom@16.v2_10_2m1730126952.14.0.js:182:16)
    at Object.invokeGuardedCallbackDev (react-dom@16.v2_10_2m1730126952.14.0.js:231:18)

My question is: how shall the firewall be configured to let the website work as before?

Our admin would prefer that all the requests are routed via 443, as it is now the case to access locally port 5000 via nginx, where flask is serving its content via gunicorn, but I am not sure if this is possible with dash.

Thank you for your suggestions!

Hello @Blast,

Welcome to the community!

Did you try importing your flask app to your dash app as the server and then running your dash app server from gunicorn?

I am not sure if I did already how you are suggesting. This is how I did:
https://hackersandslackers.com/plotly-dash-with-flask/

All this made my head spin a bit, but it worked quite nicely, until the firewall configuration was changed.

Thank you!

Do you have the flask app as a separate app?

Here is my understanding of the configuration:
Gunicorn serves the app, which is run as a flask app:

app = Flask(__name__, static_url_path='/static')

The Flask app (listening on port 5000) is then passed to the init_app function, as a server for Dash:

with app.app_context():
            # Import parts of our core Flask app
            from . import routes
            from .assets import compile_static_assets
    
            # Import Dash application
            from .dashboard import init_dashboard
            app = init_dashboard(app,"/dashapp/")

And here the Flask server is associated to the Dash app:

def init_dashboard(server,url):
    """Create a Plotly Dash dashboard."""
    dash_app = dash.Dash(
        server=server,
        serve_locally=True,
        routes_pathname_prefix=url,
        external_stylesheets=[
            "/static/dist/css/styles.css",
            "https://fonts.googleapis.com/css?family=Lato",
        ]
    )
    
    # Both app context and a request context to use url_for() in the Jinja2 templates are needed
    with server.app_context(), server.test_request_context():
        html_body = render_template_string(html_layout, dash='yes')
        comments_to_replace = ("metas", "title", "favicon", "css", "app_entry", "config", "scripts", "renderer")
        for comment in comments_to_replace:
            html_body = html_body.replace(f"<!-- {comment} -->", "{%" + comment + "%}")
        dash_app.index_string = html_body

    # Create Layout
    dash_app.layout = serve_layout
    init_callbacks(dash_app)
    return dash_app.server

So my understanding is that Flask calls dash when the routes_pathname_prefix is called by a Flask route, generating the corresponding URL and triggering the serve_layout function (not shown)

Flask generates a page with jinja2, that is also used in Dash (code not shown) to embed the app into the HTML/Javascript code (again, according to my understanding).

I hope this answers to your question, and is useful to troubleshoot the Firewall problem.

Thank you!

Gunicorn will listen by default on port :8000.

The interesting thing was your statement of flask working but Dash not… Anyways, that demo doesnt show how to actually run the gunicorn command.

What does your gunicorn command look like? What is your nginx routing file?

2 Likes

This is my flask.service:

[Unit]
Description=Gunicorn instance to serve Flask
After=network.target
[Service]
User=root
Group=www-data
WorkingDirectory=/home/XXXXXX/plotly_flask_app
Environment="PATH=/home/XXXXXX/plotly_flask_app/venv/bin"
ExecStart=/home/XXXXXX/plotly_flask_app/venv/bin/gunicorn --bind 127.0.0.1:5000 run:app
[Install]
WantedBy=multi-user.target

And here is the nginx configuration:

server {
    listen 443 ssl;
    server_name 192.X.X.X

    root /var/www/html;

    # Add index.php to the list if you are using PHP
    index index.html index.htm index.nginx-debian.html;

    ssl_certificate /etc/ssl/certs/XXXXX.cer;
    ssl_certificate_key /etc/ssl/private/XXXXX.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://127.0.0.1:5000;  # Assuming Flask runs on port 5000
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

# Redirect HTTP traffic to HTTPS
server {
    listen 80;
    server_name your_domain_or_ip;

    location / {
        return 301 https://$host$request_uri;
    }
}

And then the app starts with run.py:

from plotly_flask_app import init_app

app = init_app()

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0")

So in this case, since the server is Flask, gunicorn listen on port :5000
Flask works, as I implemented a user authentication which is accessible and OK. But as I Invoke a route toward the Dash app, I get the above error in the browser, and a blank section of the page, instead of getting served the layout. I can directly use the layout URL as I can see it in the Flask debug toolbar, and I get the HTML code back, but it is as if Dash was not processing it.

All works from 127.0.0.1 and of course from 127.0.0.1:5000. It used to work also when the server was called from the internet, but not anymore after a Firewall upgrade. So my question is “how can the Firewall be configured to get things back up to work”?

Let me know if any other technical information can be useful.

Thank you!

Can you post your plotly_flask_app?

It seems that you arent loading your Dash app onto the server with the code that you are running.

I use Flask, Dash, Gunicorn and Nginx btw.

1 Like

Here is the Flask part of the app:

from flask import Flask, request,render_template
from flask_restful import Resource, Api
from flask_sqlalchemy import SQLAlchemy
from flask_debugtoolbar import DebugToolbarExtension
from flask_bcrypt import Bcrypt
from flask_login.login_manager import LoginManager
import sys

from flask_assets import Environment
import flask_login


def init_app():
    app = Flask(__name__,  static_url_path='/static')
    app.config.from_object("config.Config")
    
    assets = Environment()
    assets.init_app(app)
    
    with app.app_context():
            # Import parts of our core Flask app
            from . import routes
            from .assets import compile_static_assets
    
            # Import Dash application
            from .dashboard import init_dashboard
            app = init_dashboard(app,"/dashapp/")
    
            # Compile static assets
            compile_static_assets(assets)
    
    app.debug = False
    #api = Api(app)
    port = 5000
    # set a 'SECRET_KEY' to enable the Flask session cookies
    app.config['SECRET_KEY'] = "XXXXXXXX"
    
    toolbar = DebugToolbarExtension(app)
    
    if sys.argv.__len__() > 1:
        port = sys.argv[1]
    print("Api running on port : {} ".format(port))
   
    return(app)

And here is the Dash part (init_dashboard):


def init_dashboard(server,url):
    """Create a Plotly Dash dashboard."""
    dash_app = dash.Dash(
        server=server,
        serve_locally=True,
        routes_pathname_prefix=url,
        external_stylesheets=[
            "/static/dist/css/styles.css",
            "https://fonts.googleapis.com/css?family=Lato",
        ]
    )
    
    # Enable development tools
    dash_app.enable_dev_tools(
        dev_tools_ui=False,
        dev_tools_serve_dev_bundles=False,
    )

    # Both app context and a request context to use url_for() in the Jinja2 templates are needed
    with server.app_context(), server.test_request_context():
        html_body = render_template_string(html_layout, dash='yes')

        comments_to_replace = ("metas", "title", "favicon", "css", "app_entry", "config", "scripts", "renderer")
        for comment in comments_to_replace:
            html_body = html_body.replace(f"<!-- {comment} -->", "{%" + comment + "%}")

        dash_app.index_string = html_body

    # Create Layout
    dash_app.layout = serve_layout
    init_callbacks(dash_app)
    return dash_app.server

So in the end I am too using Flask, Dash, Gunicorn and Nginx. It is just that I do not know which ports are needed by Dash, as something is definitely being blocked at firewall level.

You need to be doing this:

from plotly_flask_app import init_app
from plotly_dash_app import init_dashboard

server = init_app()
app = init_dashboard(server, url)

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0")

And your ports should be fine. You were never taking the app and attaching dash to it.

Sorry for the delay in the reply, I had to work on another project.

I revived the code, and I have the impression I am already doing what you suggested.

When my code does:

from plotly_flask_app import init_app

app = init_app()

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0")

It calls init_app from Flask. So it runs this code:

def init_app():
    app = Flask(__name__,  static_url_path='/static')
    app.config.from_object("config.Config")
    
    assets = Environment()
    assets.init_app(app)
    
    with app.app_context():
            # Import parts of our core Flask app
            from . import routes
            from .assets import compile_static_assets
    
            # Import Dash application
            from .dashboard import init_dashboard ### USING initi_dashboard fro Dash
            app_dash = init_dashboard(app,"/dashapp/") ### taking the app and attaching dash ot it (?)
    
            # Compile static assets
            compile_static_assets(assets)
    
    app_dash.debug = False
    port = 5000
    # set a 'SECRET_KEY' to enable the Flask session cookies
    app_dash.config['SECRET_KEY'] = "XXXXXXXX"
    
    toolbar = DebugToolbarExtension(app)
    
    if sys.argv.__len__() > 1:
        port = sys.argv[1]
    print("Api running on port : {} ".format(port))
   
    return(app_dash)

The flask app is passed as server to the function init_dashboard imported from the Dash dashboard, and the result of this execution is assigned back to the app_dash variable, and this is returned to the initial call, and .run is called on this new app that is the result of both init_app and init_dashboard.

def init_dashboard(server,url):
    """Create a Plotly Dash dashboard."""
    dash_app = dash.Dash(
        server=server,
        #serve_locally=False,
        routes_pathname_prefix=url,
        external_stylesheets=[
            "/static/dist/css/styles.css",
            "https://fonts.googleapis.com/css?family=Lato",
        ]
    )
    
    # Enable development tools
    dash_app.enable_dev_tools(
        dev_tools_ui=False,
        dev_tools_serve_dev_bundles=False,
    )

    # Both app context and a request context to use url_for() in the Jinja2 templates are needed
    with server.app_context(), server.test_request_context():
        html_body = render_template_string(html_layout, dash='yes')

        comments_to_replace = ("metas", "title", "favicon", "css", "app_entry", "config", "scripts", "renderer")
        for comment in comments_to_replace:
            html_body = html_body.replace(f"<!-- {comment} -->", "{%" + comment + "%}")

        dash_app.index_string = html_body

    # Create Layout
    dash_app.layout = serve_layout
    init_callbacks(dash_app)
    return dash_app.server

I would be keen to think things are not too wrong, as the website works well when called from 127.0.0.1, while only the flask part works when I call it from outside the firewall, leading me to think that the problem lies to some port not being correctly configured.

Do you think I am still doing something wrong in attaching dash to the app, or would you suggest look into some port, and if yes, which one and how?

Thank you!

Ok, I see what you are doing now.

You can access the flask portion of the site without issue.

I’d say that you need to use this instead of the routes_prefix: url_base_pathname

Sorry, I am a bit lost.
Shall I remove the line

routes_pathname_prefix=url,

And set instead url_base_pathname ?

Or do you mean I shall change the value of routes_pathname_prefix, and if yes, to which location?

Thank you and sorry if I do not grasp your answer straigh away.

Yes. Replace it with that.

Replace routes prefix and put it as the base url instead.

Done, now the code looks like this:

def init_dashboard(server,url):
    """Create a Plotly Dash dashboard."""
    dash_app = dash.Dash(
        server=server,
        #serve_locally=True,
        #routes_pathname_prefix=url,
        external_stylesheets=[
            "/static/dist/css/styles.css",
            "https://fonts.googleapis.com/css?family=Lato",
        ],
        url_base_pathname=url,
    )
...

I am still experiencing the same problem: the website works well if served to 127.0.0.1 to a locally running browser, but when accessed from the web, only flask is working, and the dash app shows a brief “loading” and then nothing else, leaving the DIV empty (the layout is not served).

I tried to set serve_locally to either False or True, but nothing changed, so I commented it out.

I do not have any nginx error in the log.

Please note that the website used to work also from external machines, until our corporate firewall has been updated.

Thank you!

The thing that your original post stated, is that flask works but dash does not.

Is this still the case? Can external users access your site via the internal IP address?

Yes, it is still the case: flask works in all cases, internally or behind the firewall. Dash does not.

The Dash div is served only if the request comes from the same machine.

Dash is not working for any other machine, but this is due to the configuration of the firewall, I guess.

It used to work for some times, until the firewall was updated, so I am convicted that the current software is overall correct.

So I think it would be simpler to understand what Dash needs, in terms of ports and configuration,
firewall-wise, then to try to configure nginx and gunicorn in some complex way to try to pass through the firewall.

Any idea or comment?

Thank you!

There should be no difference between dash and flask.

Dash is just taking the flask server and adding its routes to it and then running. Dash doesn’t need anything extra because it is run on the same port.

Try running a basic Dash app on the server and see if it is still not accessible. Just something basic, like a hello world inside a div.

I tried a basic Dash app:

def init_dashboard(server,url):
    """Create a Plotly Dash dashboard."""
    dash_app = dash.Dash(
        server=server,
        serve_locally=True,
        requests_pathname_prefix=url,
        routes_pathname_prefix=url,
        assets_url_path='assets', 
    )
    
    dash_app.enable_dev_tools(debug=True, dev_tools_ui=True, dev_tools_hot_reload=False, dev_tools_serve_dev_bundles=True)
    
     # Create Layout
    dash_app.layout = html.Div("Hello World")
    
return dash_app.server

As before, it works at 127.0.0.1 (it displays “Hello World”), but it does not from behind the firewall. I checked in the Firefox network console, and I get an error:

Uncaught TypeError: obj is undefined
    _dispatchable _dispatchable.js:31
    f2 _curry2.js:28
    computeGraphs dependencies.js:607
    storeEffect React
    commitHookEffectListMount react-dom@16.v2_10_2m1730126952.14.0.js:19866
    commitPassiveHookEffects react-dom@16.v2_10_2m1730126952.14.0.js:19904
    callCallback react-dom@16.v2_10_2m1730126952.14.0.js:182
    invokeGuardedCallbackDev react-dom@16.v2_10_2m1730126952.14.0.js:231
    invokeGuardedCallback react-dom@16.v2_10_2m1730126952.14.0.js:286
    flushPassiveEffectsImpl react-dom@16.v2_10_2m1730126952.14.0.js:22988
    unstable_runWithPriority react@16.v2_10_2m1730126952.14.0.js:2685
    runWithPriority$1 react-dom@16.v2_10_2m1730126952.14.0.js:11174
    flushPassiveEffects react-dom@16.v2_10_2m1730126952.14.0.js:22955
    commitBeforeMutationEffects react-dom@16.v2_10_2m1730126952.14.0.js:22834
    workLoop react@16.v2_10_2m1730126952.14.0.js:2629
    flushWork react@16.v2_10_2m1730126952.14.0.js:2584
    performWorkUntilDeadline react@16.v2_10_2m1730126952.14.0.js:2196
    EventHandlerNonNull* react@16.v2_10_2m1730126952.14.0.js:2219
    <anonymous> react@16.v2_10_2m1730126952.14.0.js:15
    <anonymous> react@16.v2_10_2m1730126952.14.0.js:16
_dispatchable.js:31:12
    _dispatchable _dispatchable.js:31
    f2 _curry2.js:28
    computeGraphs dependencies.js:607
    storeEffect React
    commitHookEffectListMount react-dom@16.v2_10_2m1730126952.14.0.js:19866
    commitPassiveHookEffects react-dom@16.v2_10_2m1730126952.14.0.js:19904
    callCallback react-dom@16.v2_10_2m1730126952.14.0.js:182
    invokeGuardedCallbackDev react-dom@16.v2_10_2m1730126952.14.0.js:231
    invokeGuardedCallback react-dom@16.v2_10_2m1730126952.14.0.js:286
    flushPassiveEffectsImpl react-dom@16.v2_10_2m1730126952.14.0.js:22988
    unstable_runWithPriority react@16.v2_10_2m1730126952.14.0.js:2685
    runWithPriority$1 react-dom@16.v2_10_2m1730126952.14.0.js:11174
    flushPassiveEffects react-dom@16.v2_10_2m1730126952.14.0.js:22955
    commitBeforeMutationEffects react-dom@16.v2_10_2m1730126952.14.0.js:22834
    workLoop react@16.v2_10_2m1730126952.14.0.js:2629
    flushWork react@16.v2_10_2m1730126952.14.0.js:2584
    performWorkUntilDeadline react@16.v2_10_2m1730126952.14.0.js:2196
    (Async: EventHandlerNonNull)
    <anonymous> react@16.v2_10_2m1730126952.14.0.js:2219
    <anonymous> react@16.v2_10_2m1730126952.14.0.js:15
    <anonymous> react@16.v2_10_2m1730126952.14.0.js:16
The above error occurred in the <UnconnectedContainer> component:
    in UnconnectedContainer (created by Connect(UnconnectedContainer))
    in Connect(UnconnectedContainer) (created by UnconnectedAppContainer)
    in UnconnectedAppContainer (created by Connect(UnconnectedAppContainer))
    in Connect(UnconnectedAppContainer) (created by AppProvider)
    in Provider (created by AppProvider)
    in AppProvider

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://fb.me/react-error-boundaries to learn more about error boundaries. react-dom@16.v2_10_2m1730126952.14.0.js:19662:15
    logCapturedError https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:19662
    logError https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:19699
    callback https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:20843
    callCallback https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:12625
    commitUpdateQueue https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:12646
    commitLifeCycles https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:20018
    commitLayoutEffects https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:22938
    callCallback https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:182
    invokeGuardedCallbackDev https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:231
    invokeGuardedCallback https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:286
    commitRootImpl https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:22676
    unstable_runWithPriority https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react@16.v2_10_2m1730126952.14.0.js:2685
    runWithPriority$1 https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:11174
    commitRoot https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:22516
    finishSyncRender https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:21942
    performSyncWorkOnRoot https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:21928
    flushSyncCallbackQueueImpl https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:11224
    unstable_runWithPriority https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react@16.v2_10_2m1730126952.14.0.js:2685
    runWithPriority$1 https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:11174
    flushSyncCallbackQueueImpl https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:11219
    flushSyncCallbackQueue https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:11207
    flushPassiveEffectsImpl https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:23018
    unstable_runWithPriority https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react@16.v2_10_2m1730126952.14.0.js:2685
    runWithPriority$1 https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:11174
    flushPassiveEffects https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:22955
    commitBeforeMutationEffects https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react-dom@16.v2_10_2m1730126952.14.0.js:22834
    workLoop https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react@16.v2_10_2m1730126952.14.0.js:2629
    flushWork https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react@16.v2_10_2m1730126952.14.0.js:2584
    performWorkUntilDeadline https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react@16.v2_10_2m1730126952.14.0.js:2196
    (Async: EventHandlerNonNull)
    <anonymous> https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react@16.v2_10_2m1730126952.14.0.js:2219
    <anonymous> https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react@16.v2_10_2m1730126952.14.0.js:15
    <anonymous> https://xxxxxxx.xxx/dashapp/_dash-component-suites/dash/deps/react@16.v2_10_2m1730126952.14.0.js:16
Uncaught TypeError: obj is undefined
    _dispatchable _dispatchable.js:31
    f2 _curry2.js:28
    computeGraphs dependencies.js:607
    storeEffect React
    commitHookEffectListMount react-dom@16.v2_10_2m1730126952.14.0.js:19866
    commitPassiveHookEffects react-dom@16.v2_10_2m1730126952.14.0.js:19904
    callCallback react-dom@16.v2_10_2m1730126952.14.0.js:182
    invokeGuardedCallbackDev react-dom@16.v2_10_2m1730126952.14.0.js:231
    invokeGuardedCallback react-dom@16.v2_10_2m1730126952.14.0.js:286
    flushPassiveEffectsImpl react-dom@16.v2_10_2m1730126952.14.0.js:22988
    unstable_runWithPriority react@16.v2_10_2m1730126952.14.0.js:2685
    runWithPriority$1 react-dom@16.v2_10_2m1730126952.14.0.js:11174
    flushPassiveEffects react-dom@16.v2_10_2m1730126952.14.0.js:22955
    commitBeforeMutationEffects react-dom@16.v2_10_2m1730126952.14.0.js:22834
    workLoop react@16.v2_10_2m1730126952.14.0.js:2629
    flushWork react@16.v2_10_2m1730126952.14.0.js:2584
    performWorkUntilDeadline react@16.v2_10_2m1730126952.14.0.js:2196
    EventHandlerNonNull* react@16.v2_10_2m1730126952.14.0.js:2219
    <anonymous> react@16.v2_10_2m1730126952.14.0.js:15
    <anonymous> react@16.v2_10_2m1730126952.14.0.js:16
_dispatchable.js:31:12
    _dispatchable _dispatchable.js:31
    f2 _curry2.js:28
    computeGraphs dependencies.js:607
    storeEffect React
    commitHookEffectListMount react-dom@16.v2_10_2m1730126952.14.0.js:19866
    commitPassiveHookEffects react-dom@16.v2_10_2m1730126952.14.0.js:19904
    callCallback react-dom@16.v2_10_2m1730126952.14.0.js:182
    invokeGuardedCallbackDev react-dom@16.v2_10_2m1730126952.14.0.js:231
    invokeGuardedCallback react-dom@16.v2_10_2m1730126952.14.0.js:286
    flushPassiveEffectsImpl react-dom@16.v2_10_2m1730126952.14.0.js:22988
    unstable_runWithPriority react@16.v2_10_2m1730126952.14.0.js:2685
    runWithPriority$1 react-dom@16.v2_10_2m1730126952.14.0.js:11174
    flushPassiveEffects react-dom@16.v2_10_2m1730126952.14.0.js:22955
    commitBeforeMutationEffects react-dom@16.v2_10_2m1730126952.14.0.js:22834
    workLoop react@16.v2_10_2m1730126952.14.0.js:2629
    flushWork react@16.v2_10_2m1730126952.14.0.js:2584
    performWorkUntilDeadline react@16.v2_10_2m1730126952.14.0.js:2196
    (Async: EventHandlerNonNull)
    <anonymous> react@16.v2_10_2m1730126952.14.0.js:2219
    <anonymous> react@16.v2_10_2m1730126952.14.0.js:15
    <anonymous> react@16.v2_10_2m1730126952.14.0.js:16

I tried to change an minimize the nginx configuration, but I always get the same error.

And again, this does not happen when the website is accessed from 127.0.0.1, leading me to think that something is being blocked by the firewall, but at this point I do not know how to troubleshoot the problem.

No, I want you to run a basic app, without all of the other stuff.

import dash

dashApp = dash.Dash(__name__)

app = dashApp.server

dashApp.layout = dash.html.Div("Hello world")

And then just run the app from this file.