PageRenderTime 61ms CodeModel.GetById 43ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 1ms

/docs/howto/deployment/fastcgi.txt

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