Cerin
Cerin

Reputation: 64880

Static files not rendering in Django 2.2 when debug disabled

In Django 2.2, when I have DEBUG=True, all my static files render fine. But when I set DEBUG=False to test my production settings, all static file URLs suddenly return 404 errors.

I have a project structure like:

myproject/
    myproject/
        settings.py
        urls.py
    manage.py
static/
    thumbnails/
         image.png

My relevant static settings in settings.py:

 STATIC_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'static'))

 INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]

STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
ROOT_URLCONF = 'myproject.urls'
STATIC_URL = '/static/'
DEBUG = False

And my urls.py looks like:

import os

from django.contrib import admin
from django.conf.urls.static import static
from django.conf import settings

urlpatterns = [
    path('admin/', admin.site.urls),
]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

Why does a url like http://localhost:8000/static/thumbnails/image.png work fine when debug is on, but return a 404 when debug is off?

Upvotes: 0

Views: 1265

Answers (2)

Abhyudai
Abhyudai

Reputation: 949

Django was never meant to replace web servers. From the Django docs:

Django doesn’t serve files itself; it leaves that job to whichever Web server you choose.

This method is grossly inefficient and probably insecure, so it is unsuitable for production. On localhost with DEBUG = TRUE it deploys the static file. While on production, you should use your web server(Apache, 'Nginx' etc) to deploy static files. Just list the static directory in the configuration file of your web server. More detailed instructions regarding deployment can be found here

Upvotes: 2

Nico Griffioen
Nico Griffioen

Reputation: 5415

In production, you should run python manage.py collectstatic, and actually serve your static files from somewhere.

If you look at the docs for static files, you'll see

Serving the files

In addition to these configuration steps, you’ll also need to actually serve the static files.

During development, if you use django.contrib.staticfiles, this will be done automatically by runserver when DEBUG is set to True (see django.contrib.staticfiles.views.serve()).

This method is grossly inefficient and probably insecure, so it is unsuitable for production.

See Deploying static files for proper strategies to serve static files in production environments.

You should set the STATIC_ROOT in you production settings to a folder on you web server, and configure your webserver to point your STATIC_URL to that folder. See here.

In your case, it's seems you have taken all these steps, except actually serving your static files. You can do this by pointing your web server to the correct folder, or serving you static files from a CDN or other solution. Here's how to do it using apache

Upvotes: 3

Related Questions