Django

Code

root/django/branches/gis/docs/fastcgi.txt

Revision 8215, 14.2 kB (checked in by jbronn, 4 months ago)

gis: Merged revisions 7981-8001,8003-8011,8013-8033,8035-8036,8038-8039,8041-8063,8065-8076,8078-8139,8141-8154,8156-8214 via svnmerge from trunk.

  • Property svn:eol-style set to native
Line 
1 ===========================================
2 How to use Django with FastCGI, SCGI or AJP
3 ===========================================
4
5 Although the `current preferred setup`_ for running Django is Apache_ with
6 `mod_python`_, many people use shared hosting, on which protocols such as
7 FastCGI, SCGI or AJP are the only viable options. In some setups, these protocols
8 also allow better security -- and, possibly, better performance -- than mod_python.
9
10 .. admonition:: Note
11
12     This document primarily focuses on FastCGI. Other protocols, such as SCGI
13     and AJP, are also supported, through the ``flup`` Python package. See the
14     "Protocols" section below for specifics about SCGI and AJP.
15
16 Essentially, FastCGI is an efficient way of letting an external application
17 serve pages to a Web server. The Web server delegates the incoming Web requests
18 (via a socket) to FastCGI, which executes the code and passes the response back
19 to the Web server, which, in turn, passes it back to the client's Web browser.
20
21 Like mod_python, FastCGI allows code to stay in memory, allowing requests to be
22 served with no startup time. Unlike mod_python (or `mod_perl`_), a FastCGI
23 process doesn't run inside the Web server process, but in a separate,
24 persistent process.
25
26 .. _current preferred setup: ../modpython/
27 .. _Apache: http://httpd.apache.org/
28 .. _mod_python: http://www.modpython.org/
29 .. _mod_perl: http://perl.apache.org/
30
31 .. admonition:: Why run code in a separate process?
32
33     The traditional ``mod_*`` arrangements in Apache embed various scripting
34     languages (most notably PHP, Python and Perl) inside the process space of
35     your Web server. Although this lowers startup time -- because code doesn't
36     have to be read off disk for every request -- it comes at the cost of
37     memory use. For mod_python, for example, every Apache process gets its own
38     Python interpreter, which uses up a considerable amount of RAM.
39
40     Due to the nature of FastCGI, it's even possible to have processes that run
41     under a different user account than the Web server process. That's a nice
42     security benefit on shared systems, because it means you can secure your
43     code from other users.
44
45 Prerequisite: flup
46 ==================
47
48 Before you can start using FastCGI with Django, you'll need to install flup_,
49 which is a Python library for dealing with FastCGI. Version 0.5 or newer should
50 work fine.
51
52 .. _flup: http://www.saddi.com/software/flup/
53
54 Starting your FastCGI server
55 ============================
56
57 FastCGI operates on a client-server model, and in most cases you'll be starting
58 the FastCGI process on your own. Your Web server (be it Apache, lighttpd, or
59 otherwise) only contacts your Django-FastCGI process when the server needs a
60 dynamic page to be loaded. Because the daemon is already running with the code
61 in memory, it's able to serve the response very quickly.
62
63 .. admonition:: Note
64
65     If you're on a shared hosting system, you'll probably be forced to use
66     Web server-managed FastCGI processes. See the section below on running
67     Django with Web server-managed processes for more information.
68
69 A Web server can connect to a FastCGI server in one of two ways: It can use
70 either a Unix domain socket (a "named pipe" on Win32 systems), or it can use a
71 TCP socket. What you choose is a manner of preference; a TCP socket is usually
72 easier due to permissions issues.
73
74 To start your server, first change into the directory of your project (wherever
75 your ``manage.py`` is), and then run ``manage.py`` with the ``runfcgi`` option::
76
77     ./manage.py runfcgi [options]
78
79 If you specify ``help`` as the only option after ``runfcgi``, it'll display a
80 list of all the available options.
81
82 You'll need to specify either a ``socket``, ``protocol`` or both ``host`` and
83 ``port``. Then, when you set up your Web server, you'll just need to point it
84 at the host/port or socket you specified when starting the FastCGI server.
85
86 Protocols
87 ---------
88
89 Django supports all the protocols that flup_ does, namely fastcgi_, `SCGI`_ and
90 `AJP1.3`_ (the Apache JServ Protocol, version 1.3). Select your preferred
91 protocol by using the ``protocol=<protocol_name>`` option with
92 ``./manage.py runfcgi`` -- where ``<protocol_name>`` may be one of: ``fcgi``
93 (the default), ``scgi`` or ``ajp``. For example::
94
95     ./manage.py runfcgi protocol=scgi
96
97 .. _flup: http://www.saddi.com/software/flup/
98 .. _fastcgi: http://www.fastcgi.com/
99 .. _SCGI: http://python.ca/scgi/protocol.txt
100 .. _AJP1.3: http://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html
101
102 Examples
103 --------
104
105 Running a threaded server on a TCP port::
106
107     ./manage.py runfcgi method=threaded host=127.0.0.1 port=3033
108
109 Running a preforked server on a Unix domain socket::
110
111     ./manage.py runfcgi method=prefork socket=/home/user/mysite.sock pidfile=django.pid
112
113 Run without daemonizing (backgrounding) the process (good for debugging)::
114
115     ./manage.py runfcgi daemonize=false socket=/tmp/mysite.sock maxrequests=1
116
117 Stopping the FastCGI daemon
118 ---------------------------
119
120 If you have the process running in the foreground, it's easy enough to stop it:
121 Simply hitting ``Ctrl-C`` will stop and quit the FastCGI server. However, when
122 you're dealing with background processes, you'll need to resort to the Unix
123 ``kill`` command.
124
125 If you specify the ``pidfile`` option to your ``manage.py runfcgi``, you can
126 kill the running FastCGI daemon like this::
127
128     kill `cat $PIDFILE`
129
130 ...where ``$PIDFILE`` is the ``pidfile`` you specified.
131
132 To easily restart your FastCGI daemon on Unix, try this small shell script::
133
134     #!/bin/bash
135
136     # Replace these three settings.
137     PROJDIR="/home/user/myproject"
138     PIDFILE="$PROJDIR/mysite.pid"
139     SOCKET="$PROJDIR/mysite.sock"
140
141     cd $PROJDIR
142     if [ -f $PIDFILE ]; then
143         kill `cat -- $PIDFILE`
144         rm -f -- $PIDFILE
145     fi
146
147     exec /usr/bin/env - \
148       PYTHONPATH="../python:.." \
149       ./manage.py runfcgi socket=$SOCKET pidfile=$PIDFILE
150
151 Apache setup
152 ============
153
154 To use Django with Apache and FastCGI, you'll need Apache installed and
155 configured, with `mod_fastcgi`_ installed and enabled. Consult the Apache
156 documentation for instructions.
157
158 Once you've got that set up, point Apache at your Django FastCGI instance by
159 editing the ``httpd.conf`` (Apache configuration) file. You'll need to do two
160 things:
161
162     * Use the ``FastCGIExternalServer`` directive to specify the location of
163       your FastCGI server.
164     * Use ``mod_rewrite`` to point URLs at FastCGI as appropriate.
165
166 .. _mod_fastcgi: http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html
167
168 Specifying the location of the FastCGI server
169 ---------------------------------------------
170
171 The ``FastCGIExternalServer`` directive tells Apache how to find your FastCGI
172 server. As the `FastCGIExternalServer docs`_ explain, you can specify either a
173 ``socket`` or a ``host``. Here are examples of both::
174
175     # Connect to FastCGI via a socket / named pipe.
176     FastCGIExternalServer /home/user/public_html/mysite.fcgi -socket /home/user/mysite.sock
177
178     # Connect to FastCGI via a TCP host/port.
179     FastCGIExternalServer /home/user/public_html/mysite.fcgi -host 127.0.0.1:3033
180
181 In either case, the file ``/home/user/public_html/mysite.fcgi`` doesn't
182 actually have to exist. It's just a URL used by the Web server internally -- a
183 hook for signifying which requests at a URL should be handled by FastCGI. (More
184 on this in the next section.)
185
186 .. _FastCGIExternalServer docs: http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html#FastCgiExternalServer
187
188 Using mod_rewrite to point URLs at FastCGI
189 ------------------------------------------
190
191 The second step is telling Apache to use FastCGI for URLs that match a certain
192 pattern. To do this, use the `mod_rewrite`_ module and rewrite URLs to
193 ``mysite.fcgi`` (or whatever you specified in the ``FastCGIExternalServer``
194 directive, as explained in the previous section).
195
196 In this example, we tell Apache to use FastCGI to handle any request that
197 doesn't represent a file on the filesystem and doesn't start with ``/media/``.
198 This is probably the most common case, if you're using Django's admin site::
199
200     <VirtualHost 12.34.56.78>
201       ServerName example.com
202       DocumentRoot /home/user/public_html
203       Alias /media /home/user/python/django/contrib/admin/media
204       RewriteEngine On
205       RewriteRule ^/(media.*)$ /$1 [QSA,L,PT]
206       RewriteCond %{REQUEST_FILENAME} !-f
207       RewriteRule ^/(.*)$ /mysite.fcgi/$1 [QSA,L]
208     </VirtualHost>
209
210 .. _mod_rewrite: http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html
211
212 Django will automatically use the pre-rewrite version of the URL when
213 constructing URLs with the ``{% url %}`` template tag (and similar methods).
214
215 lighttpd setup
216 ==============
217
218 lighttpd is a lightweight Web server commonly used for serving static files. It
219 supports FastCGI natively and, thus, is a good choice for serving both static
220 and dynamic pages, if your site doesn't have any Apache-specific needs.
221
222 Make sure ``mod_fastcgi`` is in your modules list, somewhere after
223 ``mod_rewrite`` and ``mod_access``, but not after ``mod_accesslog``. You'll
224 probably want ``mod_alias`` as well, for serving admin media.
225
226 Add the following to your lighttpd config file::
227
228     server.document-root = "/home/user/public_html"
229     fastcgi.server = (
230         "/mysite.fcgi" => (
231             "main" => (
232                 # Use host / port instead of socket for TCP fastcgi
233                 # "host" => "127.0.0.1",
234                 # "port" => 3033,
235                 "socket" => "/home/user/mysite.sock",
236                 "check-local" => "disable",
237             )
238         ),
239     )
240     alias.url = (
241         "/media/" => "/home/user/django/contrib/admin/media/",
242     )
243
244     url.rewrite-once = (
245         "^(/media.*)$" => "$1",
246         "^/favicon\.ico$" => "/media/favicon.ico",
247         "^(/.*)$" => "/mysite.fcgi$1",
248     )
249
250 Running multiple Django sites on one lighttpd
251 ---------------------------------------------
252
253 lighttpd lets you use "conditional configuration" to allow configuration to be
254 customized per host. To specify multiple FastCGI sites, just add a conditional
255 block around your FastCGI config for each site::
256
257     # If the hostname is 'www.example1.com'...
258     $HTTP["host"] == "www.example1.com" {
259         server.document-root = "/foo/site1"
260         fastcgi.server = (
261            ...
262         )
263         ...
264     }
265
266     # If the hostname is 'www.example2.com'...
267     $HTTP["host"] == "www.example2.com" {
268         server.document-root = "/foo/site2"
269         fastcgi.server = (
270            ...
271         )
272         ...
273     }
274
275 You can also run multiple Django installations on the same site simply by
276 specifying multiple entries in the ``fastcgi.server`` directive. Add one
277 FastCGI host for each.
278
279 Running Django on a shared-hosting provider with Apache
280 =======================================================
281
282 Many shared-hosting providers don't allow you to run your own server daemons or
283 edit the ``httpd.conf`` file. In these cases, it's still possible to run Django
284 using Web server-spawned processes.
285
286 .. admonition:: Note
287
288     If you're using Web server-spawned processes, as explained in this section,
289     there's no need for you to start the FastCGI server on your own. Apache
290     will spawn a number of processes, scaling as it needs to.
291
292 In your Web root directory, add this to a file named ``.htaccess`` ::
293
294     AddHandler fastcgi-script .fcgi
295     RewriteEngine On
296     RewriteCond %{REQUEST_FILENAME} !-f
297     RewriteRule ^(.*)$ mysite.fcgi/$1 [QSA,L]
298
299 Then, create a small script that tells Apache how to spawn your FastCGI
300 program. Create a file ``mysite.fcgi`` and place it in your Web directory, and
301 be sure to make it executable::
302
303     #!/usr/bin/python
304     import sys, os
305
306     # Add a custom Python path.
307     sys.path.insert(0, "/home/user/python")
308
309     # Switch to the directory of your project. (Optional.)
310     # os.chdir("/home/user/myproject")
311
312     # Set the DJANGO_SETTINGS_MODULE environment variable.
313     os.environ['DJANGO_SETTINGS_MODULE'] = "myproject.settings"
314
315     from django.core.servers.fastcgi import runfastcgi
316     runfastcgi(method="threaded", daemonize="false")
317
318 Restarting the spawned server
319 -----------------------------
320
321 If you change any Python code on your site, you'll need to tell FastCGI the
322 code has changed. But there's no need to restart Apache in this case. Rather,
323 just reupload ``mysite.fcgi``, or edit the file, so that the timestamp on the
324 file will change. When Apache sees the file has been updated, it will restart
325 your Django application for you.
326
327 If you have access to a command shell on a Unix system, you can accomplish this
328 easily by using the ``touch`` command::
329
330     touch mysite.fcgi
331
332 Serving admin media files
333 =========================
334
335 Regardless of the server and configuration you eventually decide to use, you will
336 also need to give some thought to how to serve the admin media files. The
337 advice given in the modpython_ documentation is also applicable in the setups
338 detailed above.
339
340 .. _modpython: ../modpython/#serving-the-admin-files
341
342 Forcing the URL prefix to a particular value
343 ============================================
344
345 Because many of these fastcgi-based solutions require rewriting the URL at
346 some point inside the webserver, the path information that Django sees may not
347 resemble the original URL that was passed in. This is a problem if the Django
348 application is being served from under a particular prefix and you want your
349 URLs from the ``{% url %}`` tag to look like the prefix, rather than the
350 rewritten version, which might contain, for example, ``mysite.fcgi``.
351
352 Django makes a good attempt to work out what the real script name prefix
353 should be. In particular, if the webserver sets the ``SCRIPT_URL`` (specific
354 to Apache's mod_rewrite), or ``REDIRECT_URL`` (set by a few servers, including
355 Apache + mod_rewrite in some situations), Django will work out the original
356 prefix automatically.
357
358 In the cases where Django cannot work out the prefix correctly and where you
359 want the original value to be used in URLs, you can set the
360 ``FORCE_SCRIPT_NAME`` setting in your main ``settings`` file. This sets the
361 script name uniformly for every URL served via that settings file. Thus you'll
362 need to use different settings files if you want different sets of URLs to
363 have different script names in this case, but that is a rare situation.
364
365 As an example of how to use it, if your Django configuration is serving all of
366 the URLs under ``'/'`` and you wanted to use this setting, you would set
367 ``FORCE_SCRIPT_NAME = ''`` in your settings file.
Note: See TracBrowser for help on using the browser.