What do I get 404 errors with my static content using Django / nginx?

advertisements

None of my media or static content shows up and I see 404 errors for all of them everytime I load a page.

snippet from my nginx/sites-enabled (these locations below are ideally where I want my static and media content to be)

location /media {
alias /home/django/django/proj/proj/media;
}

location /static {
alias /home/django/django/proj/proj/static;
}

snippet of everything 'static' related in my settings.py

MEDIA_ROOT = os.path.join(PACKAGE_ROOT, "media")

MEDIA_URL = "/media/"

STATIC_ROOT = os.path.join(PACKAGE_ROOT, "static")

STATIC_URL = "/static/"

# Additional locations of static files
STATICFILES_DIRS = [
    os.path.join(PACKAGE_ROOT, "static"),
]

# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = [
    "django.contrib.staticfiles.finders.FileSystemFinder",
    "django.contrib.staticfiles.finders.AppDirectoriesFinder",


Your nginx aliases have to match your STATIC_ROOT and MEDIA_ROOT settings, or nginx won't know where to find these files.

location /media {
    alias /home/django/django/proj/proj/site_media/media;
}

location /static {
    alias /home/django/django/proj/proj/site_media/static;
}

If that doesn't work, check where nginx tries to find the file in your error logs.

Serving media files is quite simple: you only need to tell nginx that requests made to MEDIA_URL + '<filename>' should serve a file named MEDIA_ROOT + '<filename>'. Those are your location and alias settings in nginx.

Static files are a bit more complicated. The way Django works with static files, is that manage.py collectstatic uses your STATICFILES_FINDERS to find all static files. This includes all files in your STATICFILES_DIRS directories. A symbolic link is made in your STATIC_ROOT directory with the same relative name.

As you can't create a symbolic link with the exact same full path+name as the file is links to, your STATIC_ROOT needs to be different from your STATICFILES_DIRS. If all your static files reside in your app-specific static folders, you can omit the STATICFILES_DIRS. The STATIC_ROOT setting is required, though, as Django needs a folder for all the symbolic links in order to collect the files.

These symbolic links are a way to allow third-party apps (that are not in your project root) to still provide static files. Even though your static files can be all over the place, e.g. in your folder with python packages, you only ever need to configure nginx for one specific location of static files. This greatly simplifies your server configuration.

Those symbolic links are also why you always need to run collectstatic after you've made a change in your static files. Otherwise, nginx won't find a link that tells where the actual file is located, and can't serve that file.