|
1 ================================= |
|
2 How to use Django with mod_python |
|
3 ================================= |
|
4 |
|
5 Apache_ with `mod_python`_ currently is the preferred setup for using Django |
|
6 on a production server. |
|
7 |
|
8 mod_python is similar to `mod_perl`_ : It embeds Python within Apache and loads |
|
9 Python code into memory when the server starts. Code stays in memory throughout |
|
10 the life of an Apache process, which leads to significant performance gains over |
|
11 other server arrangements. |
|
12 |
|
13 Django requires Apache 2.x and mod_python 3.x, and you should use Apache's |
|
14 `prefork MPM`_, as opposed to the `worker MPM`_. |
|
15 |
|
16 You may also be interested in `How to use Django with FastCGI`_. |
|
17 |
|
18 .. _Apache: http://httpd.apache.org/ |
|
19 .. _mod_python: http://www.modpython.org/ |
|
20 .. _mod_perl: http://perl.apache.org/ |
|
21 .. _prefork MPM: http://httpd.apache.org/docs/2.2/mod/prefork.html |
|
22 .. _worker MPM: http://httpd.apache.org/docs/2.2/mod/worker.html |
|
23 .. _How to use Django with FastCGI: ../fastcgi/ |
|
24 |
|
25 Basic configuration |
|
26 =================== |
|
27 |
|
28 To configure Django with mod_python, first make sure you have Apache installed, |
|
29 with the mod_python module activated. |
|
30 |
|
31 Then edit your ``httpd.conf`` file and add the following:: |
|
32 |
|
33 <Location "/mysite/"> |
|
34 SetHandler python-program |
|
35 PythonHandler django.core.handlers.modpython |
|
36 SetEnv DJANGO_SETTINGS_MODULE mysite.settings |
|
37 PythonDebug On |
|
38 </Location> |
|
39 |
|
40 ...and replace ``mysite.settings`` with the Python path to your settings file. |
|
41 |
|
42 This tells Apache: "Use mod_python for any URL at or under '/mysite/', using the |
|
43 Django mod_python handler." It passes the value of ``DJANGO_SETTINGS_MODULE`` |
|
44 so mod_python knows which settings to use. |
|
45 |
|
46 Note that we're using the ``<Location>`` directive, not the ``<Directory>`` |
|
47 directive. The latter is used for pointing at places on your filesystem, |
|
48 whereas ``<Location>`` points at places in the URL structure of a Web site. |
|
49 ``<Directory>`` would be meaningless here. |
|
50 |
|
51 Also, if you've manually altered your ``PYTHONPATH`` to put your Django project |
|
52 on it, you'll need to tell mod_python:: |
|
53 |
|
54 PythonPath "['/path/to/project'] + sys.path" |
|
55 |
|
56 You can also add directives such as ``PythonAutoReload Off`` for performance. |
|
57 See the `mod_python documentation`_ for a full list of options. |
|
58 |
|
59 Note that you should set ``PythonDebug Off`` on a production server. If you |
|
60 leave ``PythonDebug On``, your users would see ugly (and revealing) Python |
|
61 tracebacks if something goes wrong within mod_python. |
|
62 |
|
63 Restart Apache, and any request to /mysite/ or below will be served by Django. |
|
64 Note that Django's URLconfs won't trim the "/mysite/" -- they get passed the |
|
65 full URL. |
|
66 |
|
67 When deploying Django sites on mod_python, you'll need to restart Apache each |
|
68 time you make changes to your Python code. |
|
69 |
|
70 Multiple Django installations on the same Apache |
|
71 ================================================ |
|
72 |
|
73 It's entirely possible to run multiple Django installations on the same Apache |
|
74 instance. Just use ``VirtualHost`` for that, like so:: |
|
75 |
|
76 NameVirtualHost * |
|
77 |
|
78 <VirtualHost *> |
|
79 ServerName www.example.com |
|
80 # ... |
|
81 SetEnv DJANGO_SETTINGS_MODULE mysite.settings |
|
82 </VirtualHost> |
|
83 |
|
84 <VirtualHost *> |
|
85 ServerName www2.example.com |
|
86 # ... |
|
87 SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings |
|
88 </VirtualHost> |
|
89 |
|
90 If you need to put two Django installations within the same ``VirtualHost``, |
|
91 you'll need to take a special precaution to ensure mod_python's cache doesn't |
|
92 mess things up. Use the ``PythonInterpreter`` directive to give different |
|
93 ``<Location>`` directives separate interpreters:: |
|
94 |
|
95 <VirtualHost *> |
|
96 ServerName www.example.com |
|
97 # ... |
|
98 <Location "/something"> |
|
99 SetEnv DJANGO_SETTINGS_MODULE mysite.settings |
|
100 PythonInterpreter mysite |
|
101 </Location> |
|
102 |
|
103 <Location "/otherthing"> |
|
104 SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings |
|
105 PythonInterpreter mysite_other |
|
106 </Location> |
|
107 </VirtualHost> |
|
108 |
|
109 The values of ``PythonInterpreter`` don't really matter, as long as they're |
|
110 different between the two ``Location`` blocks. |
|
111 |
|
112 Running a development server with mod_python |
|
113 ============================================ |
|
114 |
|
115 If you use mod_python for your development server, you can avoid the hassle of |
|
116 having to restart the server each time you make code changes. Just set |
|
117 ``MaxRequestsPerChild 1`` in your ``httpd.conf`` file to force Apache to reload |
|
118 everything for each request. But don't do that on a production server, or we'll |
|
119 revoke your Django privileges. |
|
120 |
|
121 If you're the type of programmer who debugs using scattered ``print`` |
|
122 statements, note that ``print`` statements have no effect in mod_python; they |
|
123 don't appear in the Apache log, as one might expect. If you have the need to |
|
124 print debugging information in a mod_python setup, either do this:: |
|
125 |
|
126 assert False, the_value_i_want_to_see |
|
127 |
|
128 Or add the debugging information to the template of your page. |
|
129 |
|
130 .. _mod_python documentation: http://modpython.org/live/current/doc-html/directives.html |
|
131 |
|
132 Serving media files |
|
133 =================== |
|
134 |
|
135 Django doesn't serve media files itself; it leaves that job to whichever Web |
|
136 server you choose. |
|
137 |
|
138 We recommend using a separate Web server -- i.e., one that's not also running |
|
139 Django -- for serving media. Here are some good choices: |
|
140 |
|
141 * lighttpd_ |
|
142 * TUX_ |
|
143 * A stripped-down version of Apache_ |
|
144 |
|
145 If, however, you have no option but to serve media files on the same Apache |
|
146 ``VirtualHost`` as Django, here's how you can turn off mod_python for a |
|
147 particular part of the site:: |
|
148 |
|
149 <Location "/media/"> |
|
150 SetHandler None |
|
151 </Location> |
|
152 |
|
153 Just change ``Location`` to the root URL of your media files. You can also use |
|
154 ``<LocationMatch>`` to match a regular expression. |
|
155 |
|
156 This example sets up Django at the site root but explicitly disables Django for |
|
157 the ``media`` subdirectory and any URL that ends with ``.jpg``, ``.gif`` or |
|
158 ``.png``:: |
|
159 |
|
160 <Location "/"> |
|
161 SetHandler python-program |
|
162 PythonHandler django.core.handlers.modpython |
|
163 SetEnv DJANGO_SETTINGS_MODULE mysite.settings |
|
164 </Location> |
|
165 |
|
166 <Location "media"> |
|
167 SetHandler None |
|
168 </Location> |
|
169 |
|
170 <LocationMatch "\.(jpg|gif|png)$"> |
|
171 SetHandler None |
|
172 </LocationMatch> |
|
173 |
|
174 |
|
175 .. _lighttpd: http://www.lighttpd.net/ |
|
176 .. _TUX: http://en.wikipedia.org/wiki/TUX_web_server |
|
177 .. _Apache: http://httpd.apache.org/ |
|
178 |
|
179 Serving the admin files |
|
180 ======================= |
|
181 |
|
182 Note that the Django development server automagically serves admin media files, |
|
183 but this is not the case when you use any other server arrangement. You're |
|
184 responsible for setting up Apache, or whichever media server you're using, to |
|
185 serve the admin files. |
|
186 |
|
187 The admin files live in (``django/contrib/admin/media``) of the Django |
|
188 distribution. |
|
189 |
|
190 Here are two recommended approaches: |
|
191 |
|
192 1. Create a symbolic link to the admin media files from within your |
|
193 document root. This way, all of your Django-related files -- code |
|
194 **and** templates -- stay in one place, and you'll still be able to |
|
195 ``svn update`` your code to get the latest admin templates, if they |
|
196 change. |
|
197 2. Or, copy the admin media files so that they live within your Apache |
|
198 document root. |
|
199 |
|
200 Error handling |
|
201 ============== |
|
202 |
|
203 When you use Apache/mod_python, errors will be caught by Django -- in other |
|
204 words, they won't propagate to the Apache level and won't appear in the Apache |
|
205 ``error_log``. |
|
206 |
|
207 The exception for this is if something is really wonky in your Django setup. In |
|
208 that case, you'll see an "Internal Server Error" page in your browser and the |
|
209 full Python traceback in your Apache ``error_log`` file. The ``error_log`` |
|
210 traceback is spread over multiple lines. (Yes, this is ugly and rather hard to |
|
211 read, but it's how mod_python does things.) |
|
212 |
|
213 If you get a segmentation fault |
|
214 =============================== |
|
215 |
|
216 If Apache causes a segmentation fault, there are two probable causes, neither |
|
217 of which has to do with Django itself. |
|
218 |
|
219 1. It may be because your Python code is importing the "pyexpat" module, |
|
220 which may conflict with the version embedded in Apache. For full |
|
221 information, see `Expat Causing Apache Crash`_. |
|
222 2. It may be because you're running mod_python and mod_php in the same |
|
223 Apache instance, with MySQL as your database backend. In some cases, |
|
224 this causes a known mod_python issue due to version conflicts in PHP and |
|
225 the Python MySQL backend. There's full information in the |
|
226 `mod_python FAQ entry`_. |
|
227 |
|
228 If you continue to have problems setting up mod_python, a good thing to do is |
|
229 get a barebones mod_python site working, without the Django framework. This is |
|
230 an easy way to isolate mod_python-specific problems. `Getting mod_python Working`_ |
|
231 details this procedure. |
|
232 |
|
233 The next step should be to edit your test code and add an import of any |
|
234 Django-specific code you're using -- your views, your models, your URLconf, |
|
235 your RSS configuration, etc. Put these imports in your test handler function |
|
236 and access your test URL in a browser. If this causes a crash, you've confirmed |
|
237 it's the importing of Django code that causes the problem. Gradually reduce the |
|
238 set of imports until it stops crashing, so as to find the specific module that |
|
239 causes the problem. Drop down further into modules and look into their imports, |
|
240 as necessary. |
|
241 |
|
242 .. _Expat Causing Apache Crash: http://www.dscpl.com.au/articles/modpython-006.html |
|
243 .. _mod_python FAQ entry: http://modpython.org/FAQ/faqw.py?req=show&file=faq02.013.htp |
|
244 .. _Getting mod_python Working: http://www.dscpl.com.au/articles/modpython-001.html |