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
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.