1. ==============================================
    
  2. How to use Django with Apache and ``mod_wsgi``
    
  3. ==============================================
    
  4. 
    
  5. Deploying Django with Apache_ and `mod_wsgi`_ is a tried and tested way to get
    
  6. Django into production.
    
  7. 
    
  8. .. _Apache: https://httpd.apache.org/
    
  9. .. _mod_wsgi: https://modwsgi.readthedocs.io/en/develop/
    
  10. 
    
  11. mod_wsgi is an Apache module which can host any Python WSGI_ application,
    
  12. including Django. Django will work with any version of Apache which supports
    
  13. mod_wsgi.
    
  14. 
    
  15. .. _WSGI: https://wsgi.readthedocs.io/en/latest/
    
  16. 
    
  17. The `official mod_wsgi documentation`_ is your source for all the details about
    
  18. how to use mod_wsgi. You'll probably want to start with the `installation and
    
  19. configuration documentation`_.
    
  20. 
    
  21. .. _official mod_wsgi documentation: https://modwsgi.readthedocs.io/
    
  22. .. _installation and configuration documentation: https://modwsgi.readthedocs.io/en/develop/installation.html
    
  23. 
    
  24. Basic configuration
    
  25. ===================
    
  26. 
    
  27. Once you've got mod_wsgi installed and activated, edit your Apache server's
    
  28. `httpd.conf`_ file and add the following.
    
  29. 
    
  30. .. _httpd.conf: https://cwiki.apache.org/confluence/display/httpd/DistrosDefaultLayout
    
  31. 
    
  32. .. code-block:: apache
    
  33. 
    
  34.     WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
    
  35.     WSGIPythonHome /path/to/venv
    
  36.     WSGIPythonPath /path/to/mysite.com
    
  37. 
    
  38.     <Directory /path/to/mysite.com/mysite>
    
  39.     <Files wsgi.py>
    
  40.     Require all granted
    
  41.     </Files>
    
  42.     </Directory>
    
  43. 
    
  44. The first bit in the ``WSGIScriptAlias`` line is the base URL path you want to
    
  45. serve your application at (``/`` indicates the root url), and the second is the
    
  46. location of a "WSGI file" -- see below -- on your system, usually inside of
    
  47. your project package (``mysite`` in this example). This tells Apache to serve
    
  48. any request below the given URL using the WSGI application defined in that
    
  49. file.
    
  50. 
    
  51. If you install your project's Python dependencies inside a :mod:`virtual
    
  52. environment <venv>`, add the path using ``WSGIPythonHome``. See the `mod_wsgi
    
  53. virtual environment guide`_ for more details.
    
  54. 
    
  55. The ``WSGIPythonPath`` line ensures that your project package is available for
    
  56. import on the Python path; in other words, that ``import mysite`` works.
    
  57. 
    
  58. The ``<Directory>`` piece ensures that Apache can access your :file:`wsgi.py`
    
  59. file.
    
  60. 
    
  61. Next we'll need to ensure this :file:`wsgi.py` with a WSGI application object
    
  62. exists. As of Django version 1.4, :djadmin:`startproject` will have created one
    
  63. for you; otherwise, you'll need to create it. See the :doc:`WSGI overview
    
  64. documentation</howto/deployment/wsgi/index>` for the default contents you
    
  65. should put in this file, and what else you can add to it.
    
  66. 
    
  67. .. _mod_wsgi virtual environment guide: https://modwsgi.readthedocs.io/en/develop/user-guides/virtual-environments.html
    
  68. 
    
  69. .. warning::
    
  70. 
    
  71.     If multiple Django sites are run in a single mod_wsgi process, all of them
    
  72.     will use the settings of whichever one happens to run first. This can be
    
  73.     solved by changing::
    
  74. 
    
  75.         os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings")
    
  76. 
    
  77.     in ``wsgi.py``, to::
    
  78. 
    
  79.         os.environ["DJANGO_SETTINGS_MODULE"] = "{{ project_name }}.settings"
    
  80. 
    
  81.     or by :ref:`using mod_wsgi daemon mode<daemon-mode>` and ensuring that each
    
  82.     site runs in its own daemon process.
    
  83. 
    
  84. .. admonition:: Fixing ``UnicodeEncodeError`` for file uploads
    
  85. 
    
  86.     If you get a ``UnicodeEncodeError`` when uploading or writing files with
    
  87.     file names or content that contains non-ASCII characters, make sure Apache
    
  88.     is configured to support UTF-8 encoding::
    
  89. 
    
  90.         export LANG='en_US.UTF-8'
    
  91.         export LC_ALL='en_US.UTF-8'
    
  92. 
    
  93.     A common location to put this configuration is ``/etc/apache2/envvars``.
    
  94. 
    
  95.     Alternatively, if you are :ref:`using mod_wsgi daemon mode<daemon-mode>`
    
  96.     you can add ``lang`` and ``locale`` options to the ``WSGIDaemonProcess``
    
  97.     directive::
    
  98. 
    
  99.         WSGIDaemonProcess example.com lang='en_US.UTF-8' locale='en_US.UTF-8'
    
  100. 
    
  101.     See the :ref:`unicode-files` section of the Unicode reference guide for
    
  102.     details.
    
  103. 
    
  104. .. _daemon-mode:
    
  105. 
    
  106. Using ``mod_wsgi`` daemon mode
    
  107. ==============================
    
  108. 
    
  109. "Daemon mode" is the recommended mode for running mod_wsgi (on non-Windows
    
  110. platforms). To create the required daemon process group and delegate the
    
  111. Django instance to run in it, you will need to add appropriate
    
  112. ``WSGIDaemonProcess`` and ``WSGIProcessGroup`` directives. A further change
    
  113. required to the above configuration if you use daemon mode is that you can't
    
  114. use ``WSGIPythonPath``; instead you should use the ``python-path`` option to
    
  115. ``WSGIDaemonProcess``, for example:
    
  116. 
    
  117. .. code-block:: apache
    
  118. 
    
  119.     WSGIDaemonProcess example.com python-home=/path/to/venv python-path=/path/to/mysite.com
    
  120.     WSGIProcessGroup example.com
    
  121. 
    
  122. If you want to serve your project in a subdirectory
    
  123. (``https://example.com/mysite`` in this example), you can add ``WSGIScriptAlias``
    
  124. to the configuration above:
    
  125. 
    
  126. .. code-block:: apache
    
  127. 
    
  128.     WSGIScriptAlias /mysite /path/to/mysite.com/mysite/wsgi.py process-group=example.com
    
  129. 
    
  130. See the official mod_wsgi documentation for `details on setting up daemon
    
  131. mode`_.
    
  132. 
    
  133. .. _details on setting up daemon mode: https://modwsgi.readthedocs.io/en/develop/user-guides/quick-configuration-guide.html#delegation-to-daemon-process
    
  134. 
    
  135. .. _serving-files:
    
  136. 
    
  137. Serving files
    
  138. =============
    
  139. 
    
  140. Django doesn't serve files itself; it leaves that job to whichever web
    
  141. server you choose.
    
  142. 
    
  143. We recommend using a separate web server -- i.e., one that's not also running
    
  144. Django -- for serving media. Here are some good choices:
    
  145. 
    
  146. * Nginx_
    
  147. * A stripped-down version of Apache_
    
  148. 
    
  149. If, however, you have no option but to serve media files on the same Apache
    
  150. ``VirtualHost`` as Django, you can set up Apache to serve some URLs as
    
  151. static media, and others using the mod_wsgi interface to Django.
    
  152. 
    
  153. This example sets up Django at the site root, but serves ``robots.txt``,
    
  154. ``favicon.ico``, and anything in the ``/static/`` and ``/media/`` URL space as
    
  155. a static file. All other URLs will be served using mod_wsgi:
    
  156. 
    
  157. .. code-block:: apache
    
  158. 
    
  159.     Alias /robots.txt /path/to/mysite.com/static/robots.txt
    
  160.     Alias /favicon.ico /path/to/mysite.com/static/favicon.ico
    
  161. 
    
  162.     Alias /media/ /path/to/mysite.com/media/
    
  163.     Alias /static/ /path/to/mysite.com/static/
    
  164. 
    
  165.     <Directory /path/to/mysite.com/static>
    
  166.     Require all granted
    
  167.     </Directory>
    
  168. 
    
  169.     <Directory /path/to/mysite.com/media>
    
  170.     Require all granted
    
  171.     </Directory>
    
  172. 
    
  173.     WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
    
  174. 
    
  175.     <Directory /path/to/mysite.com/mysite>
    
  176.     <Files wsgi.py>
    
  177.     Require all granted
    
  178.     </Files>
    
  179.     </Directory>
    
  180. 
    
  181. .. _Nginx: https://nginx.org/en/
    
  182. .. _Apache: https://httpd.apache.org/
    
  183. 
    
  184. .. More details on configuring a mod_wsgi site to serve static files can be found
    
  185. .. in the mod_wsgi documentation on `hosting static files`_.
    
  186. 
    
  187. .. _hosting static files: https://modwsgi.readthedocs.io/en/develop/user-guides/configuration-guidelines.html#hosting-of-static-files
    
  188. 
    
  189. .. _serving-the-admin-files:
    
  190. 
    
  191. Serving the admin files
    
  192. =======================
    
  193. 
    
  194. When :mod:`django.contrib.staticfiles` is in :setting:`INSTALLED_APPS`, the
    
  195. Django development server automatically serves the static files of the
    
  196. admin app (and any other installed apps). This is however not the case when you
    
  197. use any other server arrangement. You're responsible for setting up Apache, or
    
  198. whichever web server you're using, to serve the admin files.
    
  199. 
    
  200. The admin files live in (:file:`django/contrib/admin/static/admin`) of the
    
  201. Django distribution.
    
  202. 
    
  203. We **strongly** recommend using :mod:`django.contrib.staticfiles` to handle the
    
  204. admin files (along with a web server as outlined in the previous section; this
    
  205. means using the :djadmin:`collectstatic` management command to collect the
    
  206. static files in :setting:`STATIC_ROOT`, and then configuring your web server to
    
  207. serve :setting:`STATIC_ROOT` at :setting:`STATIC_URL`), but here are three
    
  208. other approaches:
    
  209. 
    
  210. 1. Create a symbolic link to the admin static files from within your
    
  211.    document root (this may require ``+FollowSymLinks`` in your Apache
    
  212.    configuration).
    
  213. 
    
  214. 2. Use an ``Alias`` directive, as demonstrated above, to alias the appropriate
    
  215.    URL (probably :setting:`STATIC_URL` + ``admin/``) to the actual location of
    
  216.    the admin files.
    
  217. 
    
  218. 3. Copy the admin static files so that they live within your Apache
    
  219.    document root.
    
  220. 
    
  221. Authenticating against Django's user database from Apache
    
  222. =========================================================
    
  223. 
    
  224. Django provides a handler to allow Apache to authenticate users directly
    
  225. against Django's authentication backends. See the :doc:`mod_wsgi authentication
    
  226. documentation </howto/deployment/wsgi/apache-auth>`.