tzur
tzur

Reputation: 43

Why staticfiles aren't found when DEBUG=False (in production)?

DJANGO_DEBUG=True 

(in the enviroment veriables on DigitalOcean) all the static files are found by the server and my app works fine. BUT when I set

DJANGO_DEBUG=False,

then everything goes wrong:

  1. I get 500 error code
  2. When I checkout the "Runtime logs" there is the same error message:
**ValueError: Missing staticfiles manifest entry for 'images/favicons/favicon.ico'**
[gumroad-clone] [2023-04-04 09:20:11] 
[gumroad-clone] [2023-04-04 09:20:11] During handling of the above exception, another exception occurred:
[gumroad-clone] [2023-04-04 09:20:11] 
[gumroad-clone] [2023-04-04 09:20:11] Traceback (most recent call last):
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/core/handlers/exception.py", line 56, in inner
[gumroad-clone] [2023-04-04 09:20:11]     response = get_response(request)
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/utils/deprecation.py", line 134, in __call__
[gumroad-clone] [2023-04-04 09:20:11]     response = response or self.get_response(request)
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/core/handlers/exception.py", line 58, in inner
[gumroad-clone] [2023-04-04 09:20:11]     response = response_for_exception(request, exc)
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/core/handlers/exception.py", line 140, in response_for_exception
[gumroad-clone] [2023-04-04 09:20:11]     response = handle_uncaught_exception(
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/core/handlers/exception.py", line 185, in handle_uncaught_exception
[gumroad-clone] [2023-04-04 09:20:11]     return callback(request)
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/utils/decorators.py", line 134, in _wrapped_view
[gumroad-clone] [2023-04-04 09:20:11]     response = view_func(request, *args, **kwargs)
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/views/defaults.py", line 102, in server_error
[gumroad-clone] [2023-04-04 09:20:11]     return HttpResponseServerError(template.render())
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/template/backends/django.py", line 61, in render
[gumroad-clone] [2023-04-04 09:20:11]     return self.template.render(context)
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/template/base.py", line 175, in render
[gumroad-clone] [2023-04-04 09:20:11]     return self._render(context)
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/template/base.py", line 167, in _render
[gumroad-clone] [2023-04-04 09:20:11]     return self.nodelist.render(context)
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/template/base.py", line 1000, in render
[gumroad-clone] [2023-04-04 09:20:11]     return SafeString("".join([node.render_annotated(context) for node in self]))
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/template/base.py", line 1000, in <listcomp>
[gumroad-clone] [2023-04-04 09:20:11]     return SafeString("".join([node.render_annotated(context) for node in self]))
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/template/base.py", line 958, in render_annotated
[gumroad-clone] [2023-04-04 09:20:11]     return self.render(context)
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/template/loader_tags.py", line 157, in render
[gumroad-clone] [2023-04-04 09:20:11]     return compiled_parent._render(context)
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/template/base.py", line 167, in _render
[gumroad-clone] [2023-04-04 09:20:11]     return self.nodelist.render(context)
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/template/base.py", line 1000, in render
[gumroad-clone] [2023-04-04 09:20:11]     return SafeString("".join([node.render_annotated(context) for node in self]))
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/template/base.py", line 1000, in <listcomp>
[gumroad-clone] [2023-04-04 09:20:11]     return SafeString("".join([node.render_annotated(context) for node in self]))
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/template/base.py", line 958, in render_annotated
[gumroad-clone] [2023-04-04 09:20:11]     return self.render(context)
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/templatetags/static.py", line 116, in render
[gumroad-clone] [2023-04-04 09:20:11]     url = self.url(context)
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/templatetags/static.py", line 113, in url
[gumroad-clone] [2023-04-04 09:20:11]     return self.handle_simple(path)
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/templatetags/static.py", line 129, in handle_simple
[gumroad-clone] [2023-04-04 09:20:11]     return staticfiles_storage.url(path)
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/contrib/staticfiles/storage.py", line 166, in url
[gumroad-clone] [2023-04-04 09:20:11]     return self._url(self.stored_name, name, force)
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/contrib/staticfiles/storage.py", line 145, in _url
[gumroad-clone] [2023-04-04 09:20:11]     hashed_name = hashed_name_func(*args)
[gumroad-clone] [2023-04-04 09:20:11]   File "/workspace/.heroku/python/lib/python3.10/site-packages/django/contrib/staticfiles/storage.py", line 465, in stored_name
[gumroad-clone] [2023-04-04 09:20:11]     raise ValueError(
[gumroad-clone] [2023-04-04 09:20:11] ValueError: Missing staticfiles manifest entry for 'images/favicons/favicon.ico'

I am using those dependencies:

**whitenoise==6.4.0**
**django==4.0.10**  # pyup: < 4.1 
pytz==2022.7.1  
python-slugify==8.0.1  
Pillow==9.4.0  
argon2-cffi==21.3.0 
redis==4.5.2 
hiredis==2.2.2 
stripe==5.3.0

django-environ==0.10.0  
django-model-utils==4.3.1  
django-allauth==0.53.1  
django-crispy-forms==2.0  
crispy-bootstrap5==0.7  
django-redis==5.2.0  

djangorestframework==3.14.0  
django-cors-headers==3.14.0  

drf-spectacular==0.26.1

gunicorn==20.1.0  
psycopg2==2.9.5  

In settings.py:

DJANGO_APPS = [
    **'whitenoise.runserver_nostatic',**
    **"django.contrib.staticfiles",**
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.sites",
    "django.contrib.messages",
    # "django.contrib.humanize", # Handy template tags
    "django.contrib.admin",
    "django.forms",
]
THIRD_PARTY_APPS = [
    "crispy_forms",
    "crispy_bootstrap5",
    "allauth",
    "allauth.account",
    "allauth.socialaccount",
    "rest_framework",
    "rest_framework.authtoken",
    "corsheaders",
    "drf_spectacular",
]

LOCAL_APPS = [
    "djgumroad.users",
    "djgumroad.products.apps.ProductsConfig",
]
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS


MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "corsheaders.middleware.CorsMiddleware",
    "**whitenoise.middleware.WhiteNoiseMiddleware**",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.locale.LocaleMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]



STATIC_ROOT = str(BASE_DIR / "staticfiles")
STATIC_URL = "/static/"
STATICFILES_DIRS = [str(APPS_DIR / "static")]
STATICFILES_FINDERS = [
    "django.contrib.staticfiles.finders.FileSystemFinder",
    "django.contrib.staticfiles.finders.AppDirectoriesFinder",
]
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"

  1. First I tried to check if there is a folder named "staticfiles" in my project root ( I supose DigitalOcean should run
python manage.py collectstatic 

for every deployment and all the static files should be duplicated and gather to one single folder staticfiles/

But when I check the deployed server , I couldn't found any folder named "staticfiles" in the root ( Maybe this is the reason why my server can't find any static file when DEBUG=False - there is no staticfiles/ folder at all !!!!)

  1. In the console when I run
python manage.py collectstatic

I get this error message:

**Post-processing 'assets/js/plugins/gmaps.min.js' failed!**
Traceback (most recent call last):
File "/workspace/manage.py", line 31, in <module> execute_from_command_line(sys.argv)
File "/workspace/.heroku/python/lib/python3.10/site-packages/django/core/management/__init__.py", line 446, in execute_from_comm and_line
utility.execute()
File "/workspace/.heroku/python/lib/python3.10/site-packages/django/core/management/__init__.py", line 440, in execute self.fetch_command(subcommand).run_from_argv (self.argv)
File "/workspace/.heroku/python/lib/python3.10/site-packages/django/core/management/base.py", line 414, in run_from_argv
self.execute(*args, **cmd_options)
File "/workspace/.heroku/python/lib/python3.10/site-packages/django/core/management/base.py", line 460, in execute output self.handle(*args, **options)
File "/workspace/.heroku/python/lib/python3.10/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", 1 ine 209, in handle
collected = self.collect()
File "/workspace/.heroku/python/lib/python3.10/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", l ine 154, in collect
raise processed
**whitenoise.storage.MissingFileError: The file 'assets/js/plugins/gmaps.min.js.map' could not be found with <whitenoise.storage.Com pressedManifestStaticFiles Storage object at 0x7f6b915bc190>.

The JS file 'assets/js/plugins/gmaps.min.js' references a file which could not be found:
assets/js/plugins/gmaps.min.js.map
Please check the URL references in this JS file, particularly any
relative paths which might be pointing to the wrong location.**

So to sum up:

  1. My app can't find the static files when DEBUG=False
  2. There should be staticfiels/ folder in the root of my project but there isn't.
  3. I guess I need someone to explain me what it did wrong about WhiteNoise configuration

Any idea ?

Upvotes: 0

Views: 249

Answers (1)

Brian K
Brian K

Reputation: 567

Update:

I found this question because I'm having the same issue. I finally found and solved the problem:

First, you need to have a static site, as described in my first response, #2. See https://docs.digitalocean.com/tutorials/app-deploy-django-app/#step-5-deploying-your-static-files for how-to.

The real crux of the issue, however, is that your whitenoise settings are set to both compress and cache static files. The caching process involves hashing file names so that they can be cached forever: https://whitenoise.readthedocs.io/en/latest/django.html#add-compression-and-caching-support. Doing so gives each static file a unique URL & that URL seems to be the problem on Digital Ocean app platform.

Two options to solve:

  1. Remove whitenoise from your project & allow the digital ocean static site handle static assets. This is done by simply removing all references to whitenoise from your settings.py file. NOTE: Doing this may break images on your local instance if, for example, you're running your local test site through PyCharm as I am.
  2. Change the whitenoise storage engine by changing this line in settings.py:

STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"

to

STATICFILES_STORAGE = "whitenoise.storage.CompressedStaticFilesStorage"

... which will compress your static files, but won't cache or hash their names.

Option 2 will allow your static files to be seen on both the local site and on App-Platform, but I don't know if it is "correct," as it seems to be doing double-duty.

For my app, I added logic to settings.py so that whitenoise is in use only when DEBUG=True (which is the case on my local instance, but not on my Digital Ocean app platform)


Initial reply:

This is an old question, but I notice two things:

  1. STATIC_ROOT = str(BASE_DIR / "staticfiles") should be STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles") (same goes for STATICFILES_DIRS)
  2. Digital ocean doesn't want your app-platform instance to serve static files in production, so when DEBUG is False (when app-platform assumes you're no longer debugging), you won't get any static files. You have to deploy a static site (which is free) to serve your static files in production: https://docs.digitalocean.com/tutorials/app-deploy-django-app/#step-5-deploying-your-static-files

Upvotes: 0

Related Questions