123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- ==========================================
- 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.
- .. _Apache: http://httpd.apache.org/
- .. _mod_wsgi: http://www.modwsgi.org/
- 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`_.
- .. _official mod_wsgi documentation: http://modwsgi.readthedocs.org/
- .. _installation and configuration documentation: http://modwsgi.readthedocs.org/en/develop/installation.html
- Basic configuration
- ===================
- 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.
- .. code-block:: apache
- 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
- :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.
- .. warning::
- 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::
- 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.
- 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:
- .. code-block:: apache
- WSGIPythonPath /path/to/mysite.com:/path/to/your/venv/lib/python3.X/site-packages
- Make sure you give the correct path to your virtualenv, and replace
- ``python3.X`` with the correct Python version (e.g. ``python3.4``).
- .. _virtualenv: http://www.virtualenv.org
- .. _daemon-mode:
- 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:
- .. code-block:: apache
- WSGIDaemonProcess example.com python-path=/path/to/mysite.com:/path/to/venv/lib/python2.7/site-packages
- WSGIProcessGroup example.com
- If you want to serve your project in a subdirectory
- (``http://example.com/mysite`` in this example), you can add ``WSGIScriptAlias``
- to the configuration above:
- .. code-block:: apache
- WSGIScriptAlias /mysite /path/to/mysite.com/mysite/wsgi.py process-group=example.com
- See the official mod_wsgi documentation for `details on setting up daemon
- mode`_.
- .. _details on setting up daemon mode: http://code.google.com/p/modwsgi/wiki/QuickConfigurationGuide#Delegation_To_Daemon_Process
- .. _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
- will be served using mod_wsgi:
- .. code-block:: apache
- 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>
- 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.
- .. _Nginx: http://wiki.nginx.org/Main
- .. _Apache: http://httpd.apache.org/
- .. More details on configuring a mod_wsgi site to serve static files can be found
- .. in the mod_wsgi documentation on `hosting static files`_.
- .. _hosting static files: http://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines#Hosting_Of_Static_Files
- .. _serving-the-admin-files:
- Serving the admin files
- =======================
- 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.
- The admin files live in (:file:`django/contrib/admin/static/admin`) of the
- Django distribution.
- 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
- static files in :setting:`STATIC_ROOT`, and then configuring your Web server to
- serve :setting:`STATIC_ROOT` at :setting:`STATIC_URL`), but here are three
- other approaches:
- 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
- URL (probably :setting:`STATIC_URL` + ``admin/``) to the actual location of
- the admin files.
- 3. 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 :doc:`mod_wsgi authentication
- documentation </howto/deployment/wsgi/apache-auth>`.
- If you get a UnicodeEncodeError
- ===============================
- If you're taking advantage of the internationalization features of Django (see
- :doc:`/topics/i18n/index`) 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
- the ones in :mod:`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.
|