parts/django/docs/howto/deployment/modpython.txt
changeset 69 c6bca38c1cbf
equal deleted inserted replaced
68:5ff1fc726848 69:c6bca38c1cbf
       
     1 .. _howto-deployment-modpython:
       
     2 
       
     3 ============================================
       
     4 How to use Django with Apache and mod_python
       
     5 ============================================
       
     6 
       
     7 .. warning::
       
     8 
       
     9     Support for mod_python will be deprecated in a future release of Django. If
       
    10     you are configuring a new deployment, you are strongly encouraged to
       
    11     consider using :doc:`mod_wsgi </howto/deployment/modwsgi>` or any of the
       
    12     other :doc:`supported backends </howto/deployment/index>`.
       
    13 
       
    14 .. highlight:: apache
       
    15 
       
    16 The `mod_python`_ module for Apache_ can be used to deploy Django to a
       
    17 production server, although it has been mostly superseded by the simpler
       
    18 :doc:`mod_wsgi deployment option </howto/deployment/modwsgi>`.
       
    19 
       
    20 mod_python is similar to (and inspired by) `mod_perl`_ : It embeds Python within
       
    21 Apache and loads Python code into memory when the server starts. Code stays in
       
    22 memory throughout the life of an Apache process, which leads to significant
       
    23 performance gains over other server arrangements.
       
    24 
       
    25 Django requires Apache 2.x and mod_python 3.x, and you should use Apache's
       
    26 `prefork MPM`_, as opposed to the `worker MPM`_.
       
    27 
       
    28 .. seealso::
       
    29 
       
    30     * Apache is a big, complex animal, and this document only scratches the
       
    31       surface of what Apache can do. If you need more advanced information about
       
    32       Apache, there's no better source than `Apache's own official
       
    33       documentation`_
       
    34 
       
    35     * You may also be interested in :doc:`How to use Django with FastCGI, SCGI,
       
    36       or AJP </howto/deployment/fastcgi>`.
       
    37 
       
    38 .. _Apache: http://httpd.apache.org/
       
    39 .. _mod_python: http://www.modpython.org/
       
    40 .. _mod_perl: http://perl.apache.org/
       
    41 .. _prefork MPM: http://httpd.apache.org/docs/2.2/mod/prefork.html
       
    42 .. _worker MPM: http://httpd.apache.org/docs/2.2/mod/worker.html
       
    43 .. _apache's own official documentation: http://httpd.apache.org/docs/
       
    44 
       
    45 Basic configuration
       
    46 ===================
       
    47 
       
    48 To configure Django with mod_python, first make sure you have Apache installed,
       
    49 with the mod_python module activated.
       
    50 
       
    51 Then edit your ``httpd.conf`` file and add the following::
       
    52 
       
    53     <Location "/mysite/">
       
    54         SetHandler python-program
       
    55         PythonHandler django.core.handlers.modpython
       
    56         SetEnv DJANGO_SETTINGS_MODULE mysite.settings
       
    57         PythonOption django.root /mysite
       
    58         PythonDebug On
       
    59     </Location>
       
    60 
       
    61 ...and replace ``mysite.settings`` with the Python import path to your Django
       
    62 project's settings file.
       
    63 
       
    64 This tells Apache: "Use mod_python for any URL at or under '/mysite/', using the
       
    65 Django mod_python handler." It passes the value of :ref:`DJANGO_SETTINGS_MODULE
       
    66 <django-settings-module>` so mod_python knows which settings to use.
       
    67 
       
    68 .. versionadded:: 1.0
       
    69     The ``PythonOption django.root ...`` is new in this version.
       
    70 
       
    71 Because mod_python does not know we are serving this site from underneath the
       
    72 ``/mysite/`` prefix, this value needs to be passed through to the mod_python
       
    73 handler in Django, via the ``PythonOption django.root ...`` line. The value set
       
    74 on that line (the last item) should match the string given in the ``<Location
       
    75 ...>`` directive. The effect of this is that Django will automatically strip the
       
    76 ``/mysite`` string from the front of any URLs before matching them against your
       
    77 URLconf patterns. If you later move your site to live under ``/mysite2``, you
       
    78 will not have to change anything except the ``django.root`` option in the config
       
    79 file.
       
    80 
       
    81 When using ``django.root`` you should make sure that what's left, after the
       
    82 prefix has been removed, begins with a slash. Your URLconf patterns that are
       
    83 expecting an initial slash will then work correctly. In the above example,
       
    84 since we want to send things like ``/mysite/admin/`` to ``/admin/``, we need
       
    85 to remove the string ``/mysite`` from the beginning, so that is the
       
    86 ``django.root`` value. It would be an error to use ``/mysite/`` (with a
       
    87 trailing slash) in this case.
       
    88 
       
    89 Note that we're using the ``<Location>`` directive, not the ``<Directory>``
       
    90 directive. The latter is used for pointing at places on your filesystem,
       
    91 whereas ``<Location>`` points at places in the URL structure of a Web site.
       
    92 ``<Directory>`` would be meaningless here.
       
    93 
       
    94 Also, if your Django project is not on the default ``PYTHONPATH`` for your
       
    95 computer, you'll have to tell mod_python where your project can be found:
       
    96 
       
    97 .. parsed-literal::
       
    98 
       
    99     <Location "/mysite/">
       
   100         SetHandler python-program
       
   101         PythonHandler django.core.handlers.modpython
       
   102         SetEnv DJANGO_SETTINGS_MODULE mysite.settings
       
   103         PythonOption django.root /mysite
       
   104         PythonDebug On
       
   105         **PythonPath "['/path/to/project'] + sys.path"**
       
   106     </Location>
       
   107 
       
   108 The value you use for ``PythonPath`` should include the parent directories of
       
   109 all the modules you are going to import in your application. It should also
       
   110 include the parent directory of the :ref:`DJANGO_SETTINGS_MODULE
       
   111 <django-settings-module>` location. This is exactly the same situation as
       
   112 setting the Python path for interactive usage. Whenever you try to import
       
   113 something, Python will run through all the directories in ``sys.path`` in turn,
       
   114 from first to last, and try to import from each directory until one succeeds.
       
   115 
       
   116 Make sure that your Python source files' permissions are set such that the
       
   117 Apache user (usually named ``apache`` or ``httpd`` on most systems) will have
       
   118 read access to the files.
       
   119 
       
   120 An example might make this clearer. Suppose you have some applications under
       
   121 ``/usr/local/django-apps/`` (for example, ``/usr/local/django-apps/weblog/`` and
       
   122 so forth), your settings file is at ``/var/www/mysite/settings.py`` and you have
       
   123 specified :ref:`DJANGO_SETTINGS_MODULE <django-settings-module>` as in the above
       
   124 example. In this case, you would need to write your ``PythonPath`` directive
       
   125 as::
       
   126 
       
   127     PythonPath "['/usr/local/django-apps/', '/var/www'] + sys.path"
       
   128 
       
   129 With this path, ``import weblog`` and ``import mysite.settings`` will both
       
   130 work. If you had ``import blogroll`` in your code somewhere and ``blogroll``
       
   131 lived under the ``weblog/`` directory, you would *also* need to add
       
   132 ``/usr/local/django-apps/weblog/`` to your ``PythonPath``. Remember: the
       
   133 **parent directories** of anything you import directly must be on the Python
       
   134 path.
       
   135 
       
   136 .. note::
       
   137 
       
   138     If you're using Windows, we still recommended that you use forward
       
   139     slashes in the pathnames, even though Windows normally uses the backslash
       
   140     character as its native separator. Apache knows how to convert from the
       
   141     forward slash format to the native format, so this approach is portable and
       
   142     easier to read. (It avoids tricky problems with having to double-escape
       
   143     backslashes.)
       
   144 
       
   145     This is valid even on a Windows system::
       
   146 
       
   147         PythonPath "['c:/path/to/project'] + sys.path"
       
   148 
       
   149 You can also add directives such as ``PythonAutoReload Off`` for performance.
       
   150 See the `mod_python documentation`_ for a full list of options.
       
   151 
       
   152 Note that you should set ``PythonDebug Off`` on a production server. If you
       
   153 leave ``PythonDebug On``, your users would see ugly (and revealing) Python
       
   154 tracebacks if something goes wrong within mod_python.
       
   155 
       
   156 Restart Apache, and any request to ``/mysite/`` or below will be served by
       
   157 Django. Note that Django's URLconfs won't trim the "/mysite/" -- they get passed
       
   158 the full URL.
       
   159 
       
   160 When deploying Django sites on mod_python, you'll need to restart Apache each
       
   161 time you make changes to your Python code.
       
   162 
       
   163 .. _mod_python documentation: http://modpython.org/live/current/doc-html/directives.html
       
   164 
       
   165 Multiple Django installations on the same Apache
       
   166 ================================================
       
   167 
       
   168 It's entirely possible to run multiple Django installations on the same Apache
       
   169 instance. Just use ``VirtualHost`` for that, like so::
       
   170 
       
   171     NameVirtualHost *
       
   172 
       
   173     <VirtualHost *>
       
   174         ServerName www.example.com
       
   175         # ...
       
   176         SetEnv DJANGO_SETTINGS_MODULE mysite.settings
       
   177     </VirtualHost>
       
   178 
       
   179     <VirtualHost *>
       
   180         ServerName www2.example.com
       
   181         # ...
       
   182         SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
       
   183     </VirtualHost>
       
   184 
       
   185 If you need to put two Django installations within the same ``VirtualHost``
       
   186 (or in different ``VirtualHost`` blocks that share the same server name),
       
   187 you'll need to take a special precaution to ensure mod_python's cache doesn't
       
   188 mess things up. Use the ``PythonInterpreter`` directive to give different
       
   189 ``<Location>`` directives separate interpreters::
       
   190 
       
   191     <VirtualHost *>
       
   192         ServerName www.example.com
       
   193         # ...
       
   194         <Location "/something">
       
   195             SetEnv DJANGO_SETTINGS_MODULE mysite.settings
       
   196             PythonInterpreter mysite
       
   197         </Location>
       
   198 
       
   199         <Location "/otherthing">
       
   200             SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
       
   201             PythonInterpreter othersite
       
   202         </Location>
       
   203     </VirtualHost>
       
   204 
       
   205 The values of ``PythonInterpreter`` don't really matter, as long as they're
       
   206 different between the two ``Location`` blocks.
       
   207 
       
   208 Running a development server with mod_python
       
   209 ============================================
       
   210 
       
   211 If you use mod_python for your development server, you can avoid the hassle of
       
   212 having to restart the server each time you make code changes. Just set
       
   213 ``MaxRequestsPerChild 1`` in your ``httpd.conf`` file to force Apache to reload
       
   214 everything for each request. But don't do that on a production server, or we'll
       
   215 revoke your Django privileges.
       
   216 
       
   217 If you're the type of programmer who debugs using scattered ``print``
       
   218 statements, note that output to ``stdout`` will not appear in the Apache
       
   219 log and can even `cause response errors`_.
       
   220 
       
   221 .. _cause response errors: http://blog.dscpl.com.au/2009/04/wsgi-and-printing-to-standard-output.html
       
   222 
       
   223 If you have the need to print debugging information in a mod_python setup, you
       
   224 have a few options. You can print to ``stderr`` explicitly, like so::
       
   225 
       
   226     print >> sys.stderr, 'debug text'
       
   227     sys.stderr.flush()
       
   228 
       
   229 (note that ``stderr`` is buffered, so calling ``flush`` is necessary if you wish
       
   230 debugging information to be displayed promptly.)
       
   231 
       
   232 A more compact approach is to use an assertion::
       
   233 
       
   234     assert False, 'debug text'
       
   235 
       
   236 Another alternative is to add debugging information to the template of your page.
       
   237 
       
   238 .. _serving-media-files:
       
   239 
       
   240 Serving media files
       
   241 ===================
       
   242 
       
   243 Django doesn't serve media files itself; it leaves that job to whichever Web
       
   244 server you choose.
       
   245 
       
   246 We recommend using a separate Web server -- i.e., one that's not also running
       
   247 Django -- for serving media. Here are some good choices:
       
   248 
       
   249     * lighttpd_
       
   250     * Nginx_
       
   251     * TUX_
       
   252     * A stripped-down version of Apache_
       
   253     * Cherokee_
       
   254 
       
   255 If, however, you have no option but to serve media files on the same Apache
       
   256 ``VirtualHost`` as Django, here's how you can turn off mod_python for a
       
   257 particular part of the site::
       
   258 
       
   259     <Location "/media">
       
   260         SetHandler None
       
   261     </Location>
       
   262 
       
   263 Just change ``Location`` to the root URL of your media files. You can also use
       
   264 ``<LocationMatch>`` to match a regular expression.
       
   265 
       
   266 This example sets up Django at the site root but explicitly disables Django for
       
   267 the ``media`` subdirectory and any URL that ends with ``.jpg``, ``.gif`` or
       
   268 ``.png``::
       
   269 
       
   270     <Location "/">
       
   271         SetHandler python-program
       
   272         PythonHandler django.core.handlers.modpython
       
   273         SetEnv DJANGO_SETTINGS_MODULE mysite.settings
       
   274     </Location>
       
   275 
       
   276     <Location "/media">
       
   277         SetHandler None
       
   278     </Location>
       
   279 
       
   280     <LocationMatch "\.(jpg|gif|png)$">
       
   281         SetHandler None
       
   282     </LocationMatch>
       
   283 
       
   284 
       
   285 .. _lighttpd: http://www.lighttpd.net/
       
   286 .. _Nginx: http://wiki.nginx.org/Main
       
   287 .. _TUX: http://en.wikipedia.org/wiki/TUX_web_server
       
   288 .. _Apache: http://httpd.apache.org/
       
   289 .. _Cherokee: http://www.cherokee-project.com/
       
   290 
       
   291 .. _serving-the-admin-files:
       
   292 
       
   293 Serving the admin files
       
   294 =======================
       
   295 
       
   296 Note that the Django development server automagically serves admin media files,
       
   297 but this is not the case when you use any other server arrangement. You're
       
   298 responsible for setting up Apache, or whichever media server you're using, to
       
   299 serve the admin files.
       
   300 
       
   301 The admin files live in (:file:`django/contrib/admin/media`) of the Django
       
   302 distribution.
       
   303 
       
   304 Here are two recommended approaches:
       
   305 
       
   306     1. Create a symbolic link to the admin media files from within your
       
   307        document root. This way, all of your Django-related files -- code **and**
       
   308        templates -- stay in one place, and you'll still be able to ``svn
       
   309        update`` your code to get the latest admin templates, if they change.
       
   310 
       
   311     2. Or, copy the admin media files so that they live within your Apache
       
   312        document root.
       
   313 
       
   314 Using "eggs" with mod_python
       
   315 ============================
       
   316 
       
   317 If you installed Django from a Python egg_ or are using eggs in your Django
       
   318 project, some extra configuration is required. Create an extra file in your
       
   319 project (or somewhere else) that contains something like the following:
       
   320 
       
   321 .. code-block:: python
       
   322 
       
   323     import os
       
   324     os.environ['PYTHON_EGG_CACHE'] = '/some/directory'
       
   325 
       
   326 Here, ``/some/directory`` is a directory that the Apache Web server process can
       
   327 write to. It will be used as the location for any unpacking of code the eggs
       
   328 need to do.
       
   329 
       
   330 Then you have to tell mod_python to import this file before doing anything
       
   331 else. This is done using the PythonImport_ directive to mod_python. You need
       
   332 to ensure that you have specified the ``PythonInterpreter`` directive to
       
   333 mod_python as described above__ (you need to do this even if you aren't
       
   334 serving multiple installations in this case). Then add the ``PythonImport``
       
   335 line in the main server configuration (i.e., outside the ``Location`` or
       
   336 ``VirtualHost`` sections). For example::
       
   337 
       
   338     PythonInterpreter my_django
       
   339     PythonImport /path/to/my/project/file.py my_django
       
   340 
       
   341 Note that you can use an absolute path here (or a normal dotted import path),
       
   342 as described in the `mod_python manual`_. We use an absolute path in the
       
   343 above example because if any Python path modifications are required to access
       
   344 your project, they will not have been done at the time the ``PythonImport``
       
   345 line is processed.
       
   346 
       
   347 .. _Egg: http://peak.telecommunity.com/DevCenter/PythonEggs
       
   348 .. _PythonImport: http://www.modpython.org/live/current/doc-html/dir-other-pimp.html
       
   349 .. _mod_python manual: PythonImport_
       
   350 __ `Multiple Django installations on the same Apache`_
       
   351 
       
   352 Error handling
       
   353 ==============
       
   354 
       
   355 When you use Apache/mod_python, errors will be caught by Django -- in other
       
   356 words, they won't propagate to the Apache level and won't appear in the Apache
       
   357 ``error_log``.
       
   358 
       
   359 The exception for this is if something is really wonky in your Django setup. In
       
   360 that case, you'll see an "Internal Server Error" page in your browser and the
       
   361 full Python traceback in your Apache ``error_log`` file. The ``error_log``
       
   362 traceback is spread over multiple lines. (Yes, this is ugly and rather hard to
       
   363 read, but it's how mod_python does things.)
       
   364 
       
   365 If you get a segmentation fault
       
   366 ===============================
       
   367 
       
   368 If Apache causes a segmentation fault, there are two probable causes, neither
       
   369 of which has to do with Django itself.
       
   370 
       
   371     1. It may be because your Python code is importing the "pyexpat" module,
       
   372        which may conflict with the version embedded in Apache. For full
       
   373        information, see `Expat Causing Apache Crash`_.
       
   374 
       
   375     2. It may be because you're running mod_python and mod_php in the same
       
   376        Apache instance, with MySQL as your database backend. In some cases,
       
   377        this causes a known mod_python issue due to version conflicts in PHP and
       
   378        the Python MySQL backend. There's full information in the
       
   379        `mod_python FAQ entry`_.
       
   380 
       
   381 If you continue to have problems setting up mod_python, a good thing to do is
       
   382 get a barebones mod_python site working, without the Django framework. This is
       
   383 an easy way to isolate mod_python-specific problems. `Getting mod_python Working`_
       
   384 details this procedure.
       
   385 
       
   386 The next step should be to edit your test code and add an import of any
       
   387 Django-specific code you're using -- your views, your models, your URLconf,
       
   388 your RSS configuration, etc. Put these imports in your test handler function
       
   389 and access your test URL in a browser. If this causes a crash, you've confirmed
       
   390 it's the importing of Django code that causes the problem. Gradually reduce the
       
   391 set of imports until it stops crashing, so as to find the specific module that
       
   392 causes the problem. Drop down further into modules and look into their imports,
       
   393 as necessary.
       
   394 
       
   395 .. _Expat Causing Apache Crash: http://www.dscpl.com.au/wiki/ModPython/Articles/ExpatCausingApacheCrash
       
   396 .. _mod_python FAQ entry: http://modpython.org/FAQ/faqw.py?req=show&file=faq02.013.htp
       
   397 .. _Getting mod_python Working: http://www.dscpl.com.au/wiki/ModPython/Articles/GettingModPythonWorking
       
   398 
       
   399 If you get a UnicodeEncodeError
       
   400 ===============================
       
   401 
       
   402 If you're taking advantage of the internationalization features of Django (see
       
   403 :doc:`/topics/i18n/index`) and you intend to allow users to upload files, you must
       
   404 ensure that the environment used to start Apache is configured to accept
       
   405 non-ASCII file names. If your environment is not correctly configured, you
       
   406 will trigger ``UnicodeEncodeError`` exceptions when calling functions like
       
   407 ``os.path()`` on filenames that contain non-ASCII characters.
       
   408 
       
   409 To avoid these problems, the environment used to start Apache should contain
       
   410 settings analogous to the following::
       
   411 
       
   412     export LANG='en_US.UTF-8'
       
   413     export LC_ALL='en_US.UTF-8'
       
   414 
       
   415 Consult the documentation for your operating system for the appropriate syntax
       
   416 and location to put these configuration items; ``/etc/apache2/envvars`` is a
       
   417 common location on Unix platforms. Once you have added these statements
       
   418 to your environment, restart Apache.