Django 1.6 Nginx with static files outside project folder

522 views
Skip to first unread message

Florian Auer

unread,
Sep 18, 2014, 9:42:02 AM9/18/14
to django...@googlegroups.com
Hello.

It seems im stuck in the try to deploy my django project, consisting of multiple apps, to the production server at the point of serving the static files from the preferred directory.

system details:
- CentOS 6.5
- Django 1.6.4
- green Unicorn python server
- Nginx webserver
- python 3.3.5

pyvenv layout:
|-webapps
| |-sonar
| | |-bin
| | |-include
| | |-lib       #site-packages folder insite
| | |-logs      #server logfiles
| | |-run       #sock files
|
| |-static    #collected static files
| | |-myproject
|
| | |-[app folders]
| | | |-requirements.txt
| | | |-static  #central static location for development
| | | |-[...]
| | | |-myproject
| | | | |-settings.py
| | | | |-[...]

settings.py (shortend)
# -*- coding: utf-8 -*-
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
DEBUG = True
TEMPLATE_DEBUG = True
ALLOWED_HOSTS = ['127.0.0.1']

TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
    'django.template.loaders.eggs.Loader',
)

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.contrib.auth.context_processors.auth',
    'django.core.context_processors.debug',
    'django.core.context_processors.i18n',
    'django.core.context_processors.media',
    'django.core.context_processors.static',
    'django.core.context_processors.request',
    'django.contrib.messages.context_processors.messages'
)

STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)

# Application definition

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

MIDDLEWARE_CLASSES = (
    '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',
)

#START addition or userauth app
INSTALLED_APPS += (
    'userauth',
)
LOGIN_URL = '/benutzer/anmelden/'
LOGOUT_URL = '/benutzer/abmelden/'
LOGIN_REDIRECT_URL = '/'
#END addition or userauth app

#START Mobile Detection -> based on mobileESP
MIDDLEWARE_CLASSES += (
    'mobileesp.middleware.MobileDetectionMiddleware',
)
#END Mobile Detection
INSTALLED_APPS += (
    'south',
)
#fix for mysqlConector: http://www.robberphex.com/2014/02/317
SOUTH_DATABASE_ADAPTERS = {
    'default': 'south.db.mysql'
}
#END addition for south DB Migration Tool

#START addition for dajax (0.6)
INSTALLED_APPS += (
    'dajaxice',
    'dajax'
)
STATICFILES_FINDERS += (
    'dajaxice.finders.DajaxiceFinder',
)
ROOT_URLCONF = 'myproject.urls'
WSGI_APPLICATION = 'myproject.wsgi.application'

DATABASES = {
    'default': {
        'ENGINE': 'mysql.connector.django',
        'NAME': 'myproject',
        'USER': 'root',
        'PASSWORD': 'tekkoadmin',
        'HOST': '127.0.0.1',
        'PORT': '3306'
    }
}
LANGUAGE_CODE = 'de'
TIME_ZONE = 'Europe/Berlin'
USE_I18N = True
USE_L10N = True
USE_TZ = True

# Static files (CSS, JavaScript, Images)
STATIC_ROOT = '/webapps/sonar3/static/' #production
STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "static"),
    #'/webapps/sonar3/static/', #not jet used
)

TEMPLATE_DIRS = (
    os.path.join(BASE_DIR, 'templates'),
    os.path.join(BASE_DIR, 'templates/desktop'),
    os.path.join(BASE_DIR, 'templates/tablet'),
    os.path.join(BASE_DIR, 'templates/mobile'),
)

# define if services should use multithreading
SERVICES_USE_THREADS = False

nginx.conf
    upstream sonar_app_server {
        # fail_timeout=0 means we always retry an upstream even if it failed
        # to return a good HTTP response (in case the Unicorn master nukes a
        # single worker for timing out).         
        server unix:/webapps/sonar3/run/gunicorn.sock fail_timeout=0;
    }
     
    server {
        listen 8001;
        server_name myproject.de;
         
        client_max_body_size 4G;
         
        access_log /webapps/sonar3/logs/nginx-access.log;
        error_log /webapps/sonar3/logs/nginx-error.log;
        location /static {
            alias /webapps/sonar3/static;
        }
        location /media {
            alias /webapps/sonar3/media;
        }
         
        location / {
            # an HTTP header important enough to have its own Wikipedia entry:
            # http://en.wikipedia.org/wiki/X-Forwarded-For
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
             
            # enable this if and only if you use HTTPS, this helps Rack
            # set the proper protocol for doing redirects:
            # proxy_set_header X-Forwarded-Proto https;
             
            # pass the Host: header from the client right along so redirects
            # can be set properly within the Rack application
            proxy_set_header Host $http_host;
             
            # we don't want nginx trying to do something clever with
            # redirects, we set the Host: header above already.
            proxy_redirect off;
             
            # set "proxy_buffering off" *only* for Rainbows! when doing
            # Comet/long-poll stuff. It's also safe to set if you're
            # using only serving fast clients with Unicorn + nginx.
            # Otherwise you _want_ nginx to buffer responses to slow
            # clients, really.
            # proxy_buffering off;
             
            # Try to serve static files from nginx, no point in making an
            # *application* server like Unicorn/Rainbows! serve static files.
            if (!-f $request_filename) {
                proxy_pass http://sonar_app_server;
                break;
            }
        }
         
        # Error pages
        error_page 500 502 503 504 /500.html;
        location = /500.html {
        root /webapps/sonar3/static/;
        }
    }

I used the collectstatic command to gather all static files together in the folder "static" outside the project (webapps/sonar3/static)

But when visit the site in the browser, the static files refer to the static folder within the project (webapps/sonar3/myproject/static).
This leads to the fault, that not all static files can be found.

Has anyone a hint what i made wrong in the configuration so that the static files are not taken from the desired directory?

Collin Anderson

unread,
Sep 19, 2014, 6:55:40 PM9/19/14
to django...@googlegroups.com
so if you go to http://myproject.de:8001/static/some-file-in-myproject.css it works fine, but if you go to http://myproject.de:8001/static/admin/js/jquery.js you get a 404 Not Found?

Are the files you're looking for actually in webapps/sonar3/static?

Florian Auer

unread,
Sep 22, 2014, 11:27:34 AM9/22/14
to django...@googlegroups.com
Hi
Yes thats correct, but i checked the static directory in /webapps/sonar3/static and the files for the admin page and the plugin specific files also are present here.
But the system tries to load them from /webapps/sonar3/myproject/static.

Collin Anderson

unread,
Sep 22, 2014, 12:08:59 PM9/22/14
to django...@googlegroups.com
This looks right to me. Did you reload nginx?

location /static {
   
alias /webapps/sonar3/static;
}

Maybe this is messing it up?
if (!-f $request_filename)

If you turn off gunicorn, do you still get the static files?
Reply all
Reply to author
Forward
0 new messages