title: Dash app deployed on an Apache2 system never lets user past 'Loading...' because it cannot seem to find its dash .js files
body: <p>I am trying serve a (python3.8.2) <code>dash</code> application using an Apache2 server and <code>mod_wsgi</code>, but the application stops on the &quot;Loading...&quot; 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.</p>
  <p>I'd love some advice on where I'm going wrong, and how to get this particular app up and running.</p>
  <h3>Symptoms</h3>
  <p>I am able to serve both a simple python &quot;hello world&quot; and a simple flask app, using my setup. However, when creating a simple 'dash' app...</p>
  <pre><code>[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (polyfill@7.v1_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)
  </code></pre>
  <p>my apache access log shows a series of GET requests that got 404's (here's one example):</p>
  <pre><code>... &quot;GET /_dash-component-suites/dash_renderer/dash_renderer.v1_6_0m1598005008.min.js HTTP/1.1&quot; 404 495 &quot;http://efehr-dev.ethz.ch/hazcurves/&quot; &quot;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&quot;
  </code></pre>
  <h3>Additional observations</h3>
  <p>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.</p>
  <p>Functioning version, from <a href="https://dash-gallery.plotly.host/dash-wind-streaming/" rel="nofollow noreferrer">https://dash-gallery.plotly.host/dash-wind-streaming/</a></p>
  <pre class="lang-html prettyprint-override"><code># Excerpt from functioning app's &quot;footer&quot; section
  &lt;footer&gt;
    &lt;script id=&quot;_dash-config&quot; type=&quot;application/json&quot;&gt;{&quot;url_base_pathname&quot;: null, &quot;requests_pathname_prefix&quot;: &quot;/dash-wind-streaming/&quot;, &quot;ui&quot;: false, &quot;props_check&quot;: false, &quot;show_undo_redo&quot;: false}&lt;/script&gt;
  
    # [CGR] then there are  several components here that are variations of the following
    &lt;script src=&quot;/dash-wind-streaming/_dash-component-suites/dash_renderer/dash_renderer.min.js?v=1.0.0&amp;m=1583853516&quot;&gt;&lt;/script&gt;
  
    &lt;script id=&quot;_dash-renderer&quot; type=&quot;application/javascript&quot;&gt;
          var renderer = new DashRenderer();
          &lt;/script&gt;
  </code></pre>
  <p>My app's Footer makes the request look scrambled, with query parameters absorbed into the filename.</p>
  <pre class="lang-html prettyprint-override"><code>&lt;footer&gt;
    &lt;script id=&quot;_dash-config&quot; type=&quot;application/json&quot;&gt;{&quot;url_base_pathname&quot;: null, &quot;requests_pathname_prefix&quot;: &quot;/&quot;, &quot;ui&quot;: false, &quot;props_check&quot;: false, &quot;show_undo_redo&quot;: false, &quot;suppress_callback_exceptions&quot;: false, &quot;update_title&quot;: &quot;Updating...&quot;}&lt;/script&gt;
     
    # [CGR] then there are  several components here that are variations of the following
    &lt;script src=&quot;/_dash-component-suites/dash_html_components/dash_html_components.v1_0_3m1598005008.min.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;/_dash-component-suites/dash_renderer/dash_renderer.v1_6_0m1598005008.min.js&quot;&gt;&lt;/script&gt;
    &lt;script id=&quot;_dash-renderer&quot; type=&quot;application/javascript&quot;&gt;var renderer = new DashRenderer();&lt;/script&gt;
          &lt;/footer&gt;
  </code></pre>
  <p>Now, these .js files [the unscrambled versions] DO exist, and <code>_dash-component-suites</code> would seem to map to my <code>.local/lib/python3.8/site-packages</code> folder.</p>
  <p>So, from what I've shown above, I have <code>.../dash_renderer/dash_renderer.min.js</code> and <code>.../dash_html_components.min.js</code></p>
  <h3>My system:</h3>
  <p>A clean system with Ubuntu 20.04.1 LTS , Apache 2.4 with mod_wsgi installed.<br />
  Python 3.8.2 has the following relevant packages installed [using sudo pip3] :</p>
  <pre><code>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
  </code></pre>
  <p>Here is my app.wsgi:</p>
  <pre class="lang-py prettyprint-override"><code>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=[&quot;hello&quot;])
  application = app.server
  </code></pre>
  <p>I have been able to run this using the built-in server, serving it on a local server.</p>
  <h3>My site configuration file:</h3>
  <pre class="lang-xml prettyprint-override"><code>&lt;VirtualHost *:80&gt;
          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
  
          &lt;Directory /home/username/public_html&gt;
                  AllowOverride all
                  Options Indexes FollowSymLinks
                  &lt;Limit GET POST OPTIONS&gt;
                          Require all granted
                  &lt;/Limit&gt;
          &lt;/Directory&gt;
  
  
          ErrorLog ${APACHE_LOG_DIR}/error.log
          CustomLog ${APACHE_LOG_DIR}/access.log combined
  &lt;/VirtualHost&gt;
  </code></pre>
  <h3>Some of the things I'll admit to trying</h3>
  <ul>
  <li>Hello world in flask : works OK</li>
  <li>Hello world in Dash : fails</li>
  <li>Making alias in server config
  <code>alias _dash-component-suites/ .local/lib/python3.8/site-packages</code></li>
  <li>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.</li>
  <li>app.css.config.serve_locally = True  # also tried False : no obvious effect</li>
  <li>app.scripts.config.serve_locally = True #also tried False : no obvious effect</li>
  </ul>
  <p>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 <em>wrong</em> (and insecure)</p>
  <p><em>final caveat</em>: this is my first foray into managing an app on the server side of the world.</p>