How to use Django with Apache and mod_wsgi¶
mod_wsgi is an Apache module which can host any Python WSGI application, including Django. Django will work with any version of Apache which supports mod_wsgi.
Once you’ve got mod_wsgi installed and activated, edit your Apache server’s httpd.conf file and add the following. If you are using a version of Apache older than 2.4, replace Require all granted with Allow from all and also add the line Order deny,allow above it.
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py WSGIPythonPath /path/to/mysite.com <Directory /path/to/mysite.com/mysite> <Files wsgi.py> Require all granted </Files> </Directory>
The first bit in the WSGIScriptAlias line is the base URL path you want to serve your application at (/ indicates the root url), and the second is the location of a “WSGI file” – see below – on your system, usually inside of your project package (mysite in this example). This tells Apache to serve any request below the given URL using the WSGI application defined in that file.
The WSGIPythonPath line ensures that your project package is available for import on the Python path; in other words, that import mysite works.
The <Directory> piece just ensures that Apache can access your wsgi.py file.
Next we’ll need to ensure this wsgi.py with a WSGI application object exists. As of Django version 1.4, startproject will have created one for you; otherwise, you’ll need to create it. See the WSGI overview documentation for the default contents you should put in this file, and what else you can add to it.
If multiple Django sites are run in a single mod_wsgi process, all of them will use the settings of whichever one happens to run first. This can be solved with a minor edit to wsgi.py (see comment in the file for details), or by using mod_wsgi daemon mode and ensuring that each site runs in its own daemon process.
Using a virtualenv¶
If you install your project’s Python dependencies inside a virtualenv, you’ll need to add the path to this virtualenv’s site-packages directory to your Python path as well. To do this, add an additional path to your WSGIPythonPath directive, with multiple paths separated by a colon (:) if using a UNIX-like system, or a semicolon (;) if using Windows. If any part of a directory path contains a space character, the complete argument string to WSGIPythonPath must be quoted:
Make sure you give the correct path to your virtualenv, and replace python3.X with the correct Python version (e.g. python3.4).
Using mod_wsgi daemon mode¶
“Daemon mode” is the recommended mode for running mod_wsgi (on non-Windows platforms). To create the required daemon process group and delegate the Django instance to run in it, you will need to add appropriate WSGIDaemonProcess and WSGIProcessGroup directives. A further change required to the above configuration if you use daemon mode is that you can’t use WSGIPythonPath; instead you should use the python-path option to WSGIDaemonProcess, for example:
WSGIDaemonProcess example.com python-path=/path/to/mysite.com:/path/to/venv/lib/python2.7/site-packages WSGIProcessGroup example.com
See the official mod_wsgi documentation for details on setting up daemon mode.
Django doesn’t serve files itself; it leaves that job to whichever Web server you choose.
We recommend using a separate Web server – i.e., one that’s not also running Django – for serving media. Here are some good choices:
If, however, you have no option but to serve media files on the same Apache VirtualHost as Django, you can set up Apache to serve some URLs as static media, and others using the mod_wsgi interface to Django.
This example sets up Django at the site root, but explicitly serves robots.txt, favicon.ico, any CSS file, and anything in the /static/ and /media/ URL space as a static file. All other URLs will be served using mod_wsgi:
Alias /robots.txt /path/to/mysite.com/static/robots.txt Alias /favicon.ico /path/to/mysite.com/static/favicon.ico AliasMatch ^/([^/]*\.css) /path/to/mysite.com/static/styles/$1 Alias /media/ /path/to/mysite.com/media/ Alias /static/ /path/to/mysite.com/static/ <Directory /path/to/mysite.com/static> Require all granted </Directory> <Directory /path/to/mysite.com/media> Require all granted </Directory> WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py <Directory /path/to/mysite.com/mysite> <Files wsgi.py> Require all granted </Files> </Directory>
If you are using a version of Apache older than 2.4, replace Require all granted with Allow from all and also add the line Order deny,allow above it.
Serving the admin files¶
When django.contrib.staticfiles is in INSTALLED_APPS, the Django development server automatically serves the static files of the admin app (and any other installed apps). This is however not the case when you use any other server arrangement. You’re responsible for setting up Apache, or whichever Web server you’re using, to serve the admin files.
The admin files live in (django/contrib/admin/static/admin) of the Django distribution.
We strongly recommend using django.contrib.staticfiles to handle the admin files (along with a Web server as outlined in the previous section; this means using the collectstatic management command to collect the static files in STATIC_ROOT, and then configuring your Web server to serve STATIC_ROOT at STATIC_URL), but here are three other approaches:
- Create a symbolic link to the admin static files from within your document root (this may require +FollowSymLinks in your Apache configuration).
- Use an Alias directive, as demonstrated above, to alias the appropriate URL (probably STATIC_URL + admin/) to the actual location of the admin files.
- Copy the admin static files so that they live within your Apache document root.
Authenticating against Django’s user database from Apache¶
Django provides a handler to allow Apache to authenticate users directly against Django’s authentication backends. See the mod_wsgi authentication documentation.
If you get a UnicodeEncodeError¶
If you’re taking advantage of the internationalization features of Django (see Internationalization and localization) and you intend to allow users to upload files, you must ensure that the environment used to start Apache is configured to accept non-ASCII file names. If your environment is not correctly configured, you will trigger UnicodeEncodeError exceptions when calling functions like os.path() on filenames that contain non-ASCII characters.
To avoid these problems, the environment used to start Apache should contain settings analogous to the following:
export LANG='en_US.UTF-8' export LC_ALL='en_US.UTF-8'
Consult the documentation for your operating system for the appropriate syntax and location to put these configuration items; /etc/apache2/envvars is a common location on Unix platforms. Once you have added these statements to your environment, restart Apache.
Having trouble? We'd like to help!
- Try the FAQ — it's got answers to many common questions.
- Search for information in the archives of the django-users mailing list, or post a question.
- Ask a question in the #django IRC channel, or search the IRC logs to see if it has been asked before.
- If you notice errors with this documentation, please open a ticket and let us know! Please only use the ticket tracker for criticisms and improvements on the docs. For tech support, use the resources above.