2011-10-22 12:30:10 +08:00
|
|
|
==========================================
|
|
|
|
How to use Django with Apache and mod_wsgi
|
|
|
|
==========================================
|
|
|
|
|
|
|
|
Deploying Django with Apache_ and `mod_wsgi`_ is a tried and tested way to get
|
|
|
|
Django into production.
|
|
|
|
|
2015-11-30 00:29:46 +08:00
|
|
|
.. _Apache: https://httpd.apache.org/
|
2015-09-04 05:23:08 +08:00
|
|
|
.. _mod_wsgi: http://www.modwsgi.org/
|
2011-10-22 12:30:10 +08:00
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
.. _WSGI: http://www.wsgi.org
|
|
|
|
|
|
|
|
The `official mod_wsgi documentation`_ is fantastic; it's your source for all
|
|
|
|
the details about how to use mod_wsgi. You'll probably want to start with the
|
|
|
|
`installation and configuration documentation`_.
|
|
|
|
|
2015-11-30 00:29:46 +08:00
|
|
|
.. _official mod_wsgi documentation: https://modwsgi.readthedocs.org/
|
|
|
|
.. _installation and configuration documentation: https://modwsgi.readthedocs.org/en/develop/installation.html
|
2011-10-22 12:30:10 +08:00
|
|
|
|
|
|
|
Basic configuration
|
|
|
|
===================
|
|
|
|
|
|
|
|
Once you've got mod_wsgi installed and activated, edit your Apache server's
|
2015-12-11 02:49:29 +08:00
|
|
|
`httpd.conf`_ file (or a `virtual host`_ 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.
|
|
|
|
|
|
|
|
.. _httpd.conf: https://wiki.apache.org/httpd/DistrosDefaultLayout
|
|
|
|
.. _virtual host: https://httpd.apache.org/docs/current/en/vhosts/
|
2012-09-30 12:46:32 +08:00
|
|
|
|
|
|
|
.. code-block:: apache
|
2011-10-22 12:30:10 +08:00
|
|
|
|
|
|
|
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
|
|
|
|
WSGIPythonPath /path/to/mysite.com
|
|
|
|
|
|
|
|
<Directory /path/to/mysite.com/mysite>
|
|
|
|
<Files wsgi.py>
|
2013-06-21 01:34:02 +08:00
|
|
|
Require all granted
|
2011-10-22 12:30:10 +08:00
|
|
|
</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
|
|
|
|
:file:`wsgi.py` file.
|
|
|
|
|
|
|
|
Next we'll need to ensure this :file:`wsgi.py` with a WSGI application object
|
|
|
|
exists. As of Django version 1.4, :djadmin:`startproject` will have created one
|
|
|
|
for you; otherwise, you'll need to create it. See the :doc:`WSGI overview
|
|
|
|
documentation</howto/deployment/wsgi/index>` for the default contents you
|
|
|
|
should put in this file, and what else you can add to it.
|
|
|
|
|
2012-09-28 10:16:38 +08:00
|
|
|
.. warning::
|
|
|
|
|
2014-10-28 06:17:50 +08:00
|
|
|
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 by changing::
|
2012-09-28 10:16:38 +08:00
|
|
|
|
2014-10-28 06:17:50 +08:00
|
|
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings")
|
|
|
|
|
|
|
|
in ``wsgi.py``, to::
|
|
|
|
|
|
|
|
os.environ["DJANGO_SETTINGS_MODULE"] = "{{ project_name }}.settings"
|
|
|
|
|
|
|
|
or by :ref:`using mod_wsgi daemon mode<daemon-mode>` and ensuring that each
|
|
|
|
site runs in its own daemon process.
|
2012-09-28 10:16:38 +08:00
|
|
|
|
2015-11-07 22:35:07 +08:00
|
|
|
.. admonition:: Fixing ``UnicodeEncodeError`` for file uploads
|
|
|
|
|
|
|
|
If you get a ``UnicodeEncodeError`` when uploading files with file names
|
|
|
|
that contain non-ASCII characters, make sure Apache is configured to accept
|
|
|
|
non-ASCII file names::
|
|
|
|
|
|
|
|
export LANG='en_US.UTF-8'
|
|
|
|
export LC_ALL='en_US.UTF-8'
|
|
|
|
|
|
|
|
A common location to put this configuration is ``/etc/apache2/envvars``.
|
|
|
|
|
|
|
|
See the :ref:`unicode-files` section of the Unicode reference guide for
|
|
|
|
details.
|
|
|
|
|
2011-10-22 12:30:10 +08:00
|
|
|
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
|
2012-09-30 12:46:32 +08:00
|
|
|
your Python path as well. To do this, add an additional path to your
|
2014-02-25 01:26:29 +08:00
|
|
|
``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
|
2015-02-08 05:32:31 +08:00
|
|
|
string to ``WSGIPythonPath`` must be quoted:
|
|
|
|
|
|
|
|
.. code-block:: apache
|
2011-10-22 12:30:10 +08:00
|
|
|
|
2014-04-20 14:32:57 +08:00
|
|
|
WSGIPythonPath /path/to/mysite.com:/path/to/your/venv/lib/python3.X/site-packages
|
2011-10-22 12:30:10 +08:00
|
|
|
|
|
|
|
Make sure you give the correct path to your virtualenv, and replace
|
2014-04-20 14:32:57 +08:00
|
|
|
``python3.X`` with the correct Python version (e.g. ``python3.4``).
|
2011-10-22 12:30:10 +08:00
|
|
|
|
|
|
|
.. _virtualenv: http://www.virtualenv.org
|
|
|
|
|
2012-09-28 10:16:38 +08:00
|
|
|
.. _daemon-mode:
|
|
|
|
|
2011-10-22 12:30:10 +08:00
|
|
|
Using mod_wsgi daemon mode
|
|
|
|
==========================
|
|
|
|
|
|
|
|
"Daemon mode" is the recommended mode for running mod_wsgi (on non-Windows
|
2012-10-30 04:39:12 +08:00
|
|
|
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
|
2015-02-08 05:32:31 +08:00
|
|
|
``WSGIDaemonProcess``, for example:
|
|
|
|
|
|
|
|
.. code-block:: apache
|
2011-10-22 12:30:10 +08:00
|
|
|
|
|
|
|
WSGIDaemonProcess example.com python-path=/path/to/mysite.com:/path/to/venv/lib/python2.7/site-packages
|
2012-10-30 04:39:12 +08:00
|
|
|
WSGIProcessGroup example.com
|
|
|
|
|
2015-02-08 05:13:07 +08:00
|
|
|
If you want to serve your project in a subdirectory
|
2015-11-30 00:29:46 +08:00
|
|
|
(``https://example.com/mysite`` in this example), you can add ``WSGIScriptAlias``
|
2015-02-08 05:13:07 +08:00
|
|
|
to the configuration above:
|
|
|
|
|
|
|
|
.. code-block:: apache
|
|
|
|
|
|
|
|
WSGIScriptAlias /mysite /path/to/mysite.com/mysite/wsgi.py process-group=example.com
|
|
|
|
|
2012-10-30 04:39:12 +08:00
|
|
|
See the official mod_wsgi documentation for `details on setting up daemon
|
|
|
|
mode`_.
|
|
|
|
|
2015-11-30 00:29:46 +08:00
|
|
|
.. _details on setting up daemon mode: https://code.google.com/p/modwsgi/wiki/QuickConfigurationGuide#Delegation_To_Daemon_Process
|
2011-10-22 12:30:10 +08:00
|
|
|
|
|
|
|
.. _serving-files:
|
|
|
|
|
|
|
|
Serving files
|
|
|
|
=============
|
|
|
|
|
|
|
|
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:
|
|
|
|
|
|
|
|
* Nginx_
|
|
|
|
* A stripped-down version of Apache_
|
|
|
|
|
|
|
|
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
|
2015-02-08 05:32:31 +08:00
|
|
|
will be served using mod_wsgi:
|
|
|
|
|
|
|
|
.. code-block:: apache
|
2011-10-22 12:30:10 +08:00
|
|
|
|
|
|
|
Alias /robots.txt /path/to/mysite.com/static/robots.txt
|
|
|
|
Alias /favicon.ico /path/to/mysite.com/static/favicon.ico
|
|
|
|
|
|
|
|
Alias /media/ /path/to/mysite.com/media/
|
|
|
|
Alias /static/ /path/to/mysite.com/static/
|
|
|
|
|
|
|
|
<Directory /path/to/mysite.com/static>
|
2014-02-18 22:29:22 +08:00
|
|
|
Require all granted
|
2011-10-22 12:30:10 +08:00
|
|
|
</Directory>
|
|
|
|
|
|
|
|
<Directory /path/to/mysite.com/media>
|
2014-02-18 22:29:22 +08:00
|
|
|
Require all granted
|
2011-10-22 12:30:10 +08:00
|
|
|
</Directory>
|
|
|
|
|
|
|
|
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
|
|
|
|
|
|
|
|
<Directory /path/to/mysite.com/mysite>
|
|
|
|
<Files wsgi.py>
|
2014-02-18 22:29:22 +08:00
|
|
|
Require all granted
|
2011-10-22 12:30:10 +08:00
|
|
|
</Files>
|
|
|
|
</Directory>
|
|
|
|
|
2014-02-18 22:29:22 +08:00
|
|
|
If you are using a version of Apache older than 2.4, replace
|
2014-04-16 05:43:29 +08:00
|
|
|
``Require all granted`` with ``Allow from all`` and also add the line
|
|
|
|
``Order deny,allow`` above it.
|
2014-02-18 22:29:22 +08:00
|
|
|
|
2011-10-22 12:30:10 +08:00
|
|
|
.. _Nginx: http://wiki.nginx.org/Main
|
2015-11-30 00:29:46 +08:00
|
|
|
.. _Apache: https://httpd.apache.org/
|
2011-10-22 12:30:10 +08:00
|
|
|
|
|
|
|
.. More details on configuring a mod_wsgi site to serve static files can be found
|
|
|
|
.. in the mod_wsgi documentation on `hosting static files`_.
|
|
|
|
|
2015-11-30 00:29:46 +08:00
|
|
|
.. _hosting static files: https://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines#Hosting_Of_Static_Files
|
2011-10-22 12:30:10 +08:00
|
|
|
|
|
|
|
.. _serving-the-admin-files:
|
|
|
|
|
|
|
|
Serving the admin files
|
|
|
|
=======================
|
|
|
|
|
2013-09-01 12:04:32 +08:00
|
|
|
When :mod:`django.contrib.staticfiles` is in :setting:`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.
|
2011-10-22 12:30:10 +08:00
|
|
|
|
|
|
|
The admin files live in (:file:`django/contrib/admin/static/admin`) of the
|
|
|
|
Django distribution.
|
|
|
|
|
2012-01-05 02:08:13 +08:00
|
|
|
We **strongly** recommend using :mod:`django.contrib.staticfiles` to handle the
|
|
|
|
admin files (along with a Web server as outlined in the previous section; this
|
|
|
|
means using the :djadmin:`collectstatic` management command to collect the
|
2012-02-04 01:51:14 +08:00
|
|
|
static files in :setting:`STATIC_ROOT`, and then configuring your Web server to
|
2012-01-05 02:08:13 +08:00
|
|
|
serve :setting:`STATIC_ROOT` at :setting:`STATIC_URL`), but here are three
|
|
|
|
other approaches:
|
2011-10-22 12:30:10 +08:00
|
|
|
|
|
|
|
1. Create a symbolic link to the admin static files from within your
|
|
|
|
document root (this may require ``+FollowSymLinks`` in your Apache
|
|
|
|
configuration).
|
|
|
|
|
|
|
|
2. Use an ``Alias`` directive, as demonstrated above, to alias the appropriate
|
2013-08-15 19:14:10 +08:00
|
|
|
URL (probably :setting:`STATIC_URL` + ``admin/``) to the actual location of
|
2011-10-22 12:30:10 +08:00
|
|
|
the admin files.
|
|
|
|
|
|
|
|
3. Copy the admin static files so that they live within your Apache
|
|
|
|
document root.
|
2012-03-31 18:34:11 +08:00
|
|
|
|
2012-09-24 13:48:13 +08:00
|
|
|
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 :doc:`mod_wsgi authentication
|
|
|
|
documentation </howto/deployment/wsgi/apache-auth>`.
|