Django, uwsgi static files not being served even after collectstatic
<p>I'm having trouble with the deployment of a Django application on a Debian 8 VPS. Python version 2.7, Django 1.10.2.</p>

<p>My problem is that it will not serve static files in production mode (DEBUG = False) even after having run 'collectstatic' and assigning a STATIC_ROOT directory.</p>

<p>I've followed every instruction regarding this deployment (nginx, uwsgi, python) but still get 404's for all my static files. When collectstatic is run, it does put all the files into a /static/ directory at the top of the application. When I run uwsgi or the development server, the HTML and python functions fine, but all my static CSS,JS,IMG are not accessible.</p>

<p>When I switch back to DEBUG=True and run the dev server, my static files are present again.</p>

<p>Can someone have a look and see what I could be doing wrong? If you need any more context of files please let me know.</p>

<p>My settings.py reads as follows:</p>

<pre><code>"""
Django settings for mysite project.

Generated by 'django-admin startproject' using Django 1.10.2.

For more information on this file, see
https://docs.djangoproject.com/en/1.10/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.10/ref/settings/
"""

import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'removedforstackoverflow'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False

ALLOWED_HOSTS = ['removedforstackoverflow']


# Application definition

INSTALLED_APPS = [
    'main',
    'instant',
    'opengig',
    'widget_tweaks',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'mysite.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'mysite.wsgi.application'


# Database
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# Password validation
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
</code></pre>

<p>Here's the header.html file where I call my static files. If it was just bootstrap I'd use the CDN, but I have a few images that I use and i'd rather not set up a server just to host my static files when this application is so small.</p>

<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
    &lt;title&gt;Instant Backoffice&lt;/title&gt;
    &lt;meta charset="utf-8" /&gt;
    {% load staticfiles %}
    &lt;link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}" type = "text/css"/&gt;
    &lt;meta name="viewport" content = "width=device-width, initial-scale=1.0"&gt;
&lt;/head&gt;
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="{% static 'js/bootstrap.min.js' %}"&gt;&lt;/script&gt;
&lt;body&gt;
    &lt;nav class="navbar navbar-default"&gt;
        &lt;div class="container-fluid"&gt;
            &lt;div class="navbar-header"&gt;
                &lt;a class="navbar-brand" href="/"&gt;
                    &lt;img alt="Brand" src="{% static 'img/logo.svg' %}" height="25"&gt;
                &lt;/a&gt;
            &lt;/div&gt;
            &lt;ul class="nav navbar-nav navbar-right"&gt;
                &lt;ul class="nav nav-pills"&gt;
                    &lt;li&gt;&lt;a href="/instant/allorders"&gt;List of Orders&lt;/a&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;a href="/instant/payment"&gt;Change Payment Status&lt;/a&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;a href="/instant/review"&gt;Add a Review&lt;/a&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;a href="/instant/cancel"&gt;Cancel an Order&lt;/a&gt;&lt;/li&gt;
                    &lt;li&gt;&lt;a href="/logout/"&gt;Logout&lt;/a&gt;&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/li&gt;
        &lt;/ul&gt;
    &lt;/div&gt;
&lt;/nav&gt;
&lt;div class="row"&gt;
    &lt;div class='container-fluid'&gt;
        &lt;div class="col-sm-12"&gt;
            {% block content %}
            {% endblock %}
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>

<p>Error list from the development server:</p>

<pre><code>[06/Oct/2016 23:40:43] "GET /static/css/bootstrap.min.css HTTP/1.1" 404 102
[06/Oct/2016 23:40:43] "GET /static/js/bootstrap.min.js HTTP/1.1" 404 100
[06/Oct/2016 23:40:44] "GET /static/img/logo.svg HTTP/1.1" 404 93
[06/Oct/2016 23:40:44] "GET /static/js/bootstrap.min.js HTTP/1.1" 404 100
[06/Oct/2016 23:40:44] "GET /static/img/logo.svg HTTP/1.1" 404 93
[06/Oct/2016 23:40:44] "GET /static/img/bg.jpg HTTP/1.1" 404 91
</code></pre>

<p>And from uWSGI:</p>

<pre><code>spawned uWSGI worker 1 (and the only) (pid: 21574, cores: 1)
[pid: 21574|app: 0|req: 1/1] 82.47.105.96 () {42 vars in 795 bytes} [Thu Oct  6 23:41:47 2016] GET / =&gt; generated 1515 bytes in 36 msecs (HTTP/1.1 200) 3 headers in 102 bytes (1 switches on core 0)
[pid: 21574|app: 0|req: 2/2] 82.47.105.96 () {40 vars in 780 bytes} [Thu Oct  6 23:41:47 2016] GET /static/css/bootstrap.min.css =&gt; generated 102 bytes in 3 msecs (HTTP/1.1 404) 2 headers in 80 bytes (1 switches on core 0)
[pid: 21574|app: 0|req: 3/3] 82.47.105.96 () {40 vars in 761 bytes} [Thu Oct  6 23:41:47 2016] GET /static/js/bootstrap.min.js =&gt; generated 100 bytes in 1 msecs (HTTP/1.1 404) 2 headers in 80 bytes (1 switches on core 0)
[pid: 21574|app: 0|req: 4/4] 82.47.105.96 () {40 vars in 772 bytes} [Thu Oct  6 23:41:47 2016] GET /static/img/logo.svg =&gt; generated 93 bytes in 2 msecs (HTTP/1.1 404) 2 headers in 80 bytes (1 switches on core 0)
[pid: 21574|app: 0|req: 5/5] 82.47.105.96 () {40 vars in 761 bytes} [Thu Oct  6 23:41:48 2016] GET /static/js/bootstrap.min.js =&gt; generated 100 bytes in 2 msecs (HTTP/1.1 404) 2 headers in 80 bytes (1 switches on core 0)
[pid: 21574|app: 0|req: 6/6] 82.47.105.96 () {40 vars in 772 bytes} [Thu Oct  6 23:41:48 2016] GET /static/img/logo.svg =&gt; generated 93 bytes in 2 msecs (HTTP/1.1 404) 2 headers in 80 bytes (1 switches on core 0)
[pid: 21574|app: 0|req: 7/7] 82.47.105.96 () {40 vars in 768 bytes} [Thu Oct  6 23:41:48 2016] GET /static/img/bg.jpg =&gt; generated 91 bytes in 2 msecs (HTTP/1.1 404) 2 headers in 80 bytes (1 switches on core 0)
</code></pre>

<p>As I said, I'm just getting 404's and I don't understand why. Any help would be great.</p>

<p>You need to make sure, <code>urls.py</code> file of your project is updated to serve the static file from production.</p>

<p>Update the urls.py file of your project with the following code as shown below.</p>

<pre><code>from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... the rest of your URLconf goes here ...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
</code></pre>

<p>Another thing, I don't see any STATICFILES_DIRS directories in your settings.py file as well. You need to update that too, so that when you run <code>./manage.py collectstatic</code> command all the static assets from static dirs will get collected to your root <code>static</code> directory, that is the best practice in Django, even though directly putting the static files on <code>STATIC_ROOT</code> directory works for production.</p>

python django django-staticfiles