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 am using nginx as a front end to server my static files in production mode using the following nginx config:
location m/
{
root /path/to/folder/media/;
}
Which seems sub-optimal because I have to create a "m" folder in the media directory. I am wondering what everyone else's Django/nginx config files look like. Specifically, can you please cut-and-paste sections of nginx.confg and urls.py (settings.DEBUG == True)
Thanks.
Using Django 1.3
django.contrib.staticfiles
will take care of serving everything for you during development. You don't need to do anything particular in the urls.py. I wrote a little guide for myself after the Django 1.3 update that covers the settings to use:Refer to the docs for details: http://docs.djangoproject.com/en/1.3/howto/static-files/.
I use nginx and uwsgi for serving django apps in production (I use runserver for development). I symlink my
/static
and/media
folders (from my django project) into/var/www/vhosts/domain.com/html
for nginx to find. You could also use thecollectstatic
command instead of symlinking. If it can't find a static file it falls back to uwsgi (which is running the django app).Instead of uwsgi you could use fast-cgi, or proxy_pass or whatever you want. I prefer uwsgi because it has an incredible number of features and great performance. I run uwsgi as a daemon with:
uwsgi --emperor '/srv/*/*.ini'
. This is a fairly new option, it tells uwsgi to scan a given path for configuration files. When the emperor uwsgi daemon finds a configuration file it launches a new instance of uwsgi using the configuration found. If you change your configuration the emperor uwsgi daemon will notice and restart your app for you. You can also touch the config file to reload like with mod_wsgi, and it's really easy to setup new apps once you have everything configured initially.The path conventions I follow are:
This is my nginx.conf:
My uwsgi ini file (you can also use xml/yaml/etc):
You should also check out gunicorn, it has really nice django integration and good performance.
I'm putting this here in case someone wants an example of how to do this for Apache and WSGI. The question title is worded such that it's not just covering nginx.
Apache/WSGI Daemon
In my deployment, I decided to keep the database connection info out of the
settings.py
file. Instead I have a path/etc/django
which contains the files with the database configuration. This is covered in some detail in an answer to another question. However, as a side effect, I can check for the presence of these files and the project being in a certain path to determine if this is running as a deployment, and insettings.py
I define the settingsIS_DEV
,IS_BETA
, andIS_PROD
asTrue
orFalse
. Finding the project's directory fromsettings.py
is just:Anything that needs a path into the project uses
BASE_DIR
. So inurls.py
, I have at the end:(I also have another URL in there that I use for UI testing and don't want on beta or production.)
This covers the development server case. For production, I just have to set the Apache configuration up to serve the static stuff. (This is an intranet application with low to medium load, so I don't have a lightweight webserver like lighttpd to serve the static stuff, contrary to the Django docs' recommendation.) Since I'm using Fedora Core, I add a
django.conf
file in/etc/httpd/conf.d
that reads similar to:IIRC, the key here is to put your
Alias
lines before yourWSGIScriptAlias
line. Also make sure that there's no way for the user to download your code; I did that by putting the static stuff in astatic
directory that is not in my Django project. That's whyBASE_DIR
gives the directory containing the Django project directory.You can omit the
WSGISocketPrefix
line. I have it because the admin wants the sockets in a non-default location.My WSGI file is at
/var/www/djangoproject/django.wsgi
(i.e./django.wsgi
in the Mercurial repository) and contains something like:The nice thing about WSGI daemons is that you just have to
touch django.wsgi
to restart your Django WSGI daemon; you don't need to reload or restart the Apache server. This makes the admin happy.Finally, since my
/var/www/djangoproject
is just a Mercurial repo, I have the following in/var/www/djangoproject/.hg/hgrc
:This clears Python bytecode, updates the working copy, fixes up all the perms, and restarts the daemon whenever a developer pushes into deployment, so anyone in the
djangoproject
group can push into it and not just the last one who added a file. Needless to say, be careful who you put in thedjangoproject
group.zeekay sets
STATIC_URL
,STATIC_ROOT
,STATICFILES_DIRS
,STATICFILES_FINDERS
and uses"django.contrib.staticfiles"
and"django.core.context_processors.static"
in his settings. I don't have those since my code dates back to Django 1.1 and don't use{{ STATIC_ROOT }}
.Hope this helps.