I am trying serve a (python3.8.2) dash application using an Apache2 server and mod_wsgi, but the application stops on the "Loading..." screen. The server returns 404s for each of dash's .js scripts. I've had no problems when using dash's built in local server... but I'm not trying to serve this locally.
I'd love some advice on where I'm going wrong, and how to get this particular app up and running.
Symptoms
I am able to serve both a simple python "hello world" and a simple flask app, using my setup. However, when creating a simple 'dash' app...
[Error] Failed to load resource: the server responded with a status of 404 (Not Found) ([email protected]_6_0m1598005008.8.7.min.js, line 0)
... followed by 12 more similar error messages...
[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (dash_renderer.v1_6_0m1598005008.min.js, line 0)
[Error] ReferenceError: Can't find variable: DashRenderer
Global Code (hazcurves:28:103)
my apache access log shows a series of GET requests that got 404's (here's one example):
... "GET /_dash-component-suites/dash_renderer/dash_renderer.v1_6_0m1598005008.min.js HTTP/1.1" 404 495 "http://efehr-dev.ethz.ch/hazcurves/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Safari/605.1.15"
Additional observations
When I compared my served html to the html from a correctly functioning Dash app, I notice a difference in the .js names. It looks like mine are being mangled somehow.
Functioning version, from https://dash-gallery.plotly.host/dash-wind-streaming/
# Excerpt from functioning app's "footer" section
<footer>
<script id="_dash-config" type="application/json">{"url_base_pathname": null, "requests_pathname_prefix": "/dash-wind-streaming/", "ui": false, "props_check": false, "show_undo_redo": false}</script>
# [CGR] then there are several components here that are variations of the following
<script src="/dash-wind-streaming/_dash-component-suites/dash_renderer/dash_renderer.min.js?v=1.0.0&m=1583853516"></script>
<script id="_dash-renderer" type="application/javascript">
var renderer = new DashRenderer();
</script>
My app's Footer makes the request look scrambled, with query parameters absorbed into the filename.
<footer>
<script id="_dash-config" type="application/json">{"url_base_pathname": null, "requests_pathname_prefix": "/", "ui": false, "props_check": false, "show_undo_redo": false, "suppress_callback_exceptions": false, "update_title": "Updating..."}</script>
# [CGR] then there are several components here that are variations of the following
<script src="/_dash-component-suites/dash_html_components/dash_html_components.v1_0_3m1598005008.min.js"></script>
<script src="/_dash-component-suites/dash_renderer/dash_renderer.v1_6_0m1598005008.min.js"></script>
<script id="_dash-renderer" type="application/javascript">var renderer = new DashRenderer();</script>
</footer>
Now, these .js files [the unscrambled versions] DO exist, and _dash-component-suites would seem to map to my .local/lib/python3.8/site-packages folder.
So, from what I've shown above, I have .../dash_renderer/dash_renderer.min.js and .../dash_html_components.min.js
My system:
A clean system with Ubuntu 20.04.1 LTS , Apache 2.4 with mod_wsgi installed.
Python 3.8.2 has the following relevant packages installed [using sudo pip3] :
dash==1.14.0
dash-core-components==1.10.2
dash-html-components==1.0.3
dash-renderer==1.6.0
dash-table==4.9.0
Flask==1.1.2
Flask-Compres=1.5.0
Here is my app.wsgi:
from flask import Flask
server = Flask(__name__)
import dash
import dash_core_components as dcc
import dash_html_components as html
app = dash.Dash(server=server)
app.css.config.serve_locally = True
app.scripts.config.serve_locally = True
app.layout = html.Div(children=["hello"])
application = app.server
I have been able to run this using the built-in server, serving it on a local server.
My site configuration file:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /home/username/public_html
WSGIDaemonProcess /home/username/public_html/myapp.wsgi processes=2 threads=15 display-name=%{GROUP}
WSGIScriptAlias /hazcurves /home/username/public_html/myapp.wsgi
<Directory /home/username/public_html>
AllowOverride all
Options Indexes FollowSymLinks
<Limit GET POST OPTIONS>
Require all granted
</Limit>
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Some of the things I'll admit to trying
- Hello world in flask : works OK
- Hello world in Dash : fails
- Making alias in server config
alias _dash-component-suites/ .local/lib/python3.8/site-packages - changing request_pathnames_prefix : seems to have no effect, nor be displayed in the html output. That gave me 403's instead of 404's. But Then I noticed the inconsistencies of the names, too.
- app.css.config.serve_locally = True # also tried False : no obvious effect
- app.scripts.config.serve_locally = True #also tried False : no obvious effect
After attempting to shoehorn advice from websites that are tangentially relevant towards this question, I'm starting to feel like a monkey banging on keys --- which feels, um wrong (and insecure)
final caveat: this is my first foray into managing an app on the server side of the world.