title: Wagtail {{document.url}} is returning a 404 for user-uploaded files, in production
body: <p>I've inherited a Wagtail CMS project but have been unable to solve an issue relating to document uploads.</p>
  <p>Having uploaded a file through the CMS, it arrives in the documents directory <code>/var/www/example.com/wagtail/media/documents/test_pdf.pdf</code> which maps to the <code>/usr/src/app/media/documents/test_pdf.pdf</code> directory inside the docker container.</p>
  <p>In the front end (and within the Wagtail dashboard) the document.url resolves to <code>https://example.com/documents/9/test_pdf.pdf/</code> which returns a 404. Obviously the model number segment is missing from the file path above, but I read <a href="https://groups.google.com/g/wagtail/c/g90DyrxAX9w" rel="nofollow noreferrer">on a forum</a> that</p>
  <blockquote>
  <p>In Wagtail, documents are always served through a Django view (wagtail.wagtaildocs.views.serve.serve) so that we can perform additional processing on document downloads</p>
  </blockquote>
  <p>so perhaps this, in itself, is not an issue.</p>
  <p>There are a couple of lines in <code>urls.py</code> file which look correct:</p>
  <pre><code>urlpatterns = [
      url(r'^django-admin/', admin.site.urls),
  
      url(r'^admin/', include(wagtailadmin_urls)),
      url(r'^documents/', include(wagtaildocs_urls)),
  
      url(r'^search/$', search_views.search, name='search'),
      url(r'^sitemap\.xml$', sitemap),
  
      url(r'', include(wagtail_urls)),
  
      #    url(r'^pages/', include(wagtail_urls)),
  ]
  
  if settings.DEBUG:
      ...
      urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
  </code></pre>
  <p>and in <code>base.py</code></p>
  <pre><code>MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
  MEDIA_URL = '/media/
  </code></pre>
  <p>So, my hunch is one of either:</p>
  <ol>
  <li><p>Uploads being stored incorrectly, in a single folder rather than in subdirectories by model</p>
  </li>
  <li><p>The routing to this “virtual” directory is broken, so it’s breaking at the &quot;check permissions&quot; stage (but I couldn't figure out how routing works in Django) and returning the 404</p>
  </li>
  <li><p>The web server is incorrectly configured, so whilst the “virtual” URL is fine it’s actually the file URL which is broken and THIS causes the 404 (my nginx contains a /media/ location but not a /documents/ location, as I would have expected)</p>
  </li>
  <li><p>Something else entirely (my next step is to pull a copy down to my own machine and see if the issue still occurs)</p>
  </li>
  </ol>
  <p>I appreciate there isn't much to go on here but I'm hoping that someone might be able to give me some pointers as to what else I should check, as I've been banging my head against this for most of the day.</p>
  <p>My background is with Ruby on Rails so, as with that framework, I've a feeling that there is a lot of &quot;magic&quot; happening behind-the-scenes that is making it very tricky to figure out what's going on.</p>
  <p>Thanks!</p>