What is the most common way to configure static files when debugging and releasing Django

When developing a Django application in debug mode, I serve static files using the following code:

if settings.DEBUG: urlpatterns += patterns('', (r'^m/(?P<path>.*)$', serve, { 'document_root' : os.path.join(os.path.dirname(__file__), "media") }) ) 

I use nginx as the front-end for my static file server in production mode using the following nginx configuration:

  location m/ { root /path/to/folder/media/; } 

Which seems suboptimal because I need to create a folder β€œm” in the media directory. I am wondering what all the other Django / nginx configuration files look like. In particular, can you cut the sections nginx.confg and urls.py (settings.DEBUG == True)

Thanks.

+4
source share
2 answers

Using Django 1.3 django.contrib.staticfiles will take care of serving everything for you during development. You do not need to do anything in urls.py. I wrote a little guide for myself after updating Django 1.3, which describes the settings used:

 # idiom to get path of project import os PROJECT_PATH = os.path.dirname(os.path.abspath(__file__)) # url prefix for user uploaded files, stuff that django has to serve directly MEDIA_URL = '/media/' # url prefix for static files like css, js, images STATIC_URL = '/static/' # url prefix for *static* /admin media ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/' # path to django-served media MEDIA_ROOT = os.path.join(PROJECT_PATH, 'media') # path used for collectstatic, *where the webserver not django will expect to find files* STATIC_ROOT = '/home/user/public_html/static' # path to directories containing static files for django project, apps, etc, css/js STATICFILES_DIRS = ( os.path.join(PROJECT_PATH, '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', ) # Required for all the magic INSTALLED_APPS = ( 'django.contrib.staticfiles', ) 

See the docs for more details: http://docs.djangoproject.com/en/1.3/howto/static-files/ .

I use nginx and uwsgi to serve django applications in production (I use a server for development). I will contact my /static and /media folders (from my django project) in /var/www/vhosts/domain.com/html to search for nginx. You can also use the collectstatic command instead of a symlink. If it cannot find the static file, it returns to uwsgi (which launches the django application).

Instead of uwsgi, you can use fast-cgi, or proxy_pass, or whatever you want. I prefer uwsgi because it has an incredible amount of features and excellent performance. I run uwsgi as a daemon using uwsgi --emperor '/srv/*/*.ini' . This is a fairly new option, it tells uwsgi to scan the given path for the configuration files. When the emur uwsgi daemon finds a configuration file, it starts a new uwsgi instance using the found configuration. If you change the configuration, the emus uwsgi daemon will notice and restart your application for you. You can also touch the configuration file to reboot, for example, using mod_wsgi, and it is very easy to configure new applications as soon as you configure everything from the very beginning.

The following path conventions are listed below:

 /srv/venv/ - virtualenv for project /srv/venv/app.ini - configuration for uwsgi /srv/venv/app.sock - uwsgi sock for django /srv/venv/app.wsgi - wsgi file for uwsgi /srv/venv/proj - django project /srv/venv/proj/settings.py - project settings file /srv/venv/proj/static - static files dir, linked into var/www/vhosts/domain.com/html /srv/venv/proj/static/admin - admin static files, linked as well /srv/venv/proj/media - media files dir /var/www/vhosts/domain.com/html - base directory for nginx to serve static resources from 

This is my nginx.conf:

 location / { root /var/www/vhosts/domain.com/html; index index.html index.html; error_page 404 403 = @uwsgi; log_not_found off; } location @uwsgi { internal; include /etc/nginx/uwsgi_params; uwsgi_pass unix:/srv/venv/app.sock; } 

My uwsgi ini file (you can also use xml / yaml / etc):

 [uwsgi] home = /srv/%n pp = /srv/%n wsgi-file = /srv/%n/%n.wsgi socket = /srv/%n/%n.sock single-intepreter = true master = true processes = 2 logto = /srv/%n/%n.log 

You should also check gunicorn , it has really good django integration and good performance.

+10
source

I put this here if someone wants an example of how to do this for Apache and WSGI. The title of the question is worded so that it does not just cover nginx.

Apache / WSGI Daemon

In my deployment, I decided to save the database connection information from the settings.py file. Instead, I have a /etc/django path that contains the database configuration files. This is discussed in detail in the answer to another question . However, as a side effect, I can check for the presence of these files, and the project is on a certain path to determine whether this is performed as a deployment, and in settings.py I define the settings IS_DEV , IS_BETA , and IS_PROD as True or False . Searching for a project directory from settings.py fair:

 # Find where we live. import os BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) 

Anything that requires a path to the project uses BASE_DIR . So, in urls.py , I have at the end:

 # Only serve static media if in development (runserver) mode. if settings.IS_DEV: urlpatterns += patterns('', url(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}), ) 

(I also have another url that I use to test the user interface and don't want beta or production.)

This covers the development server case. For production, I just have to set up an Apache configuration to serve static stuff. (This is an intranet application with low to medium load, so I don’t have a lightweight web server like lighttpd to serve static stuff, unlike the dango dango recommendation). Since I use Fedora Core, I add the django.conf file to /etc/httpd/conf.d , which reads similarly:

 WSGIDaemonProcess djangoproject threads=15 WSGISocketPrefix /var/run/wsgi/wsgi Alias /django/static/ /var/www/djangoproject/static/ Alias /django/admin/media/ /usr/lib/python2.6/site-packages/django/contrib/admin/media/ WSGIScriptAlias /django /var/www/djangoproject/django.wsgi WSGIProcessGroup djangoproject <Directory /var/www/djangoproject> Order deny,allow Allow from all </Directory> <Directory /usr/lib/python2.6/site-packages/django/contrib/admin/media> Order deny,allow Allow from all </Directory> 

IIRC, the key is placing Alias lines in front of your WSGIScriptAlias line. Also make sure that the user cannot load your code; I did this by putting static things in a static directory that is not part of my Django project. Therefore, BASE_DIR provides a directory containing the directory for the Django project.

You can omit the WSGISocketPrefix line. I have this because the administrator wants the sockets to be off by default.

My WSGI file is located in /var/www/djangoproject/django.wsgi (i.e. /django.wsgi in the Mercurial repository) and contains something like:

 import os import sys os.environ['DJANGO_SETTINGS_MODULE'] = 'djangoproject.settings' os.environ['DB_CONFIG'] = '/etc/django/db_regular.py' thisDir = os.path.dirname(__file__) sys.path.append(thisDir) sys.path.append(os.path.join(thisDir, 'djangoproject')) sys.path.append(os.path.join(thisDir, 'lib')) import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler() 

The good thing about WSGI daemons is that you just need to touch django.wsgi restart the Django WSGI daemon; You do not need to restart or restart the Apache server. This makes the administrator happy.

Finally, since my /var/www/djangoproject is just a Mercurial repo, there is the following in /var/www/djangoproject/.hg/hgrc :

 [hooks] changegroup.1=find . -name \*.py[co] -exec rm -f {} \; changegroup.2=hg update changegroup.3=chgrp -Rf djangoproject . || true changegroup.4=chmod -Rf g+w,o-rwx . || true changegroup.5=find . -type d -exec chmod -f g+xs {} \; changegroup.6=touch django.wsgi # Reloads the app 

This clears the Python bytecode, updates the working copy, fixes all perms, and restarts the daemon whenever the developer clicks on the deployment, so anyone in the djangoproject group can click on it, not just the last one that added the file. Of course, be careful with who you put in the djangoproject group.


zeekay sets STATIC_URL , STATIC_ROOT , STATICFILES_DIRS , STATICFILES_FINDERS and uses "django.contrib.staticfiles" and "django.core.context_processors.static" in its settings. I don’t have one since my code goes back to Django 1.1 and does not use {{ STATIC_ROOT }} .

Hope this helps.

+2
source

All Articles