==============================How to use Django with FastCGI==============================Although the `current preferred setup`_ for running Django is Apache_ with`mod_python`_, many people use shared hosting, on which FastCGI is the onlyviable option. In some setups, FastCGI also allows better security -- and,possibly, better performance -- than mod_python.Essentially, FastCGI is an efficient way of letting an external applicationserve pages to a Web server. The Web server delegates the incoming Web requests(via a socket) to FastCGI, which executes the code and passes the response backto the Web server, which, in turn, passes it back to the client's Web browser.Like mod_python, FastCGI allows code to stay in memory, allowing requests to beserved with no startup time. Unlike mod_python (or `mod_perl`_), a FastCGIprocess doesn't run inside the Web server process, but in a separate,persistent process... _current preferred setup: ../modpython/.. _Apache: http://httpd.apache.org/.. _mod_python: http://www.modpython.org/.. _mod_perl: http://perl.apache.org/.. admonition:: Why run code in a separate process? The traditional ``mod_*`` arrangements in Apache embed various scripting languages (most notably PHP, Python and Perl) inside the process space of your Web server. Although this lowers startup time -- because code doesn't have to be read off disk for every request -- it comes at the cost of memory use. For mod_python, for example, every Apache process gets its own Python interpreter, which uses up a considerable amount of RAM. Due to the nature of FastCGI, it's even possible to have processes that run under a different user account than the Web server process. That's a nice security benefit on shared systems, because it means you can secure your code from other users.Prerequisite: flup==================Before you can start using FastCGI with Django, you'll need to install flup_,which is a Python library for dealing with FastCGI. Make sure to use the latestSubversion snapshot of flup, as some users have reported stalled pages witholder flup versions... _flup: http://www.saddi.com/software/flup/Starting your FastCGI server============================FastCGI operates on a client-server model, and in most cases you'll be startingthe FastCGI process on your own. Your Web server (be it Apache, lighttpd, orotherwise) only contacts your Django-FastCGI process when the server needs adynamic page to be loaded. Because the daemon is already running with the codein memory, it's able to serve the response very quickly... admonition:: Note If you're on a shared hosting system, you'll probably be forced to use Web server-managed FastCGI processes. See the section below on running Django with Web server-managed processes for more information.A Web server can connect to a FastCGI server in one of two ways: It can useeither a Unix domain socket (a "named pipe" on Win32 systems), or it can use aTCP socket. What you choose is a manner of preference; a TCP socket is usuallyeasier due to permissions issues.To start your server, first change into the directory of your project (whereveryour ``manage.py`` is), and then run ``manage.py`` with the ``runfcgi`` option:: ./manage.py runfcgi [options]If you specify ``help`` as the only option after ``runfcgi``, it'll display alist of all the available options.You'll need to specify either a ``socket`` or both ``host`` and ``port``. Then,when you set up your Web server, you'll just need to point it at the host/portor socket you specified when starting the FastCGI server.Examples--------Running a threaded server on a TCP port:: ./manage.py runfcgi method=threaded host=127.0.0.1 port=3033Running a preforked server on a Unix domain socket:: ./manage.py runfcgi method=prefork socket=/home/user/mysite.sock pidfile=django.pidRun without daemonizing (backgrounding) the process (good for debugging):: ./manage.py runfcgi daemonize=false socket=/tmp/mysite.sockStopping the FastCGI daemon---------------------------If you have the process running in the foreground, it's easy enough to stop it:Simply hitting ``Ctrl-C`` will stop and quit the FastCGI server. However, whenyou're dealing with background processes, you'll need to resort to the Unix``kill`` command.If you specify the ``pidfile`` option to your ``manage.py runfcgi``, you cankill the running FastCGI daemon like this:: kill `cat $PIDFILE`...where ``$PIDFILE`` is the ``pidfile`` you specified.To easily restart your FastCGI daemon on Unix, try this small shell script:: #!/bin/bash # Replace these three settings. PROJDIR="/home/user/myproject" PIDFILE="$PROJDIR/mysite.pid" SOCKET="$PROJDIR/mysite.sock" cd $PROJDIR if [ -f $PIDFILE ]; then kill `cat -- $PIDFILE` rm -f -- $PIDFILE fi exec /usr/bin/env - \ PYTHONPATH="../python:.." \ ./manage.py runfcgi socket=$SOCKET pidfile=$PIDFILEApache setup============To use Django with Apache and FastCGI, you'll need Apache installed andconfigured, with `mod_fastcgi`_ installed and enabled. Consult the Apachedocumentation for instructions.Once you've got that set up, point Apache at your Django FastCGI instance byediting the ``httpd.conf`` (Apache configuration) file. You'll need to do twothings: * Use the ``FastCGIExternalServer`` directive to specify the location of your FastCGI server. * Use ``mod_rewrite`` to point URLs at FastCGI as appropriate... _mod_fastcgi: http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.htmlSpecifying the location of the FastCGI server---------------------------------------------The ``FastCGIExternalServer`` directive tells Apache how to find your FastCGIserver. As the `FastCGIExternalServer docs`_ explain, you can specify either a``socket`` or a ``host``. Here are examples of both:: # Connect to FastCGI via a socket / named pipe. FastCGIExternalServer /home/user/public_html/mysite.fcgi -socket /home/user/mysite.sock # Connect to FastCGI via a TCP host/port. FastCGIExternalServer /home/user/public_html/mysite.fcgi -host 127.0.0.1:3033In either case, the file ``/home/user/public_html/mysite.fcgi`` doesn'tactually have to exist. It's just a URL used by the Web server internally -- ahook for signifying which requests at a URL should be handled by FastCGI. (Moreon this in the next section.).. _FastCGIExternalServer docs: http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html#FastCgiExternalServerUsing mod_rewrite to point URLs at FastCGI------------------------------------------The second step is telling Apache to use FastCGI for URLs that match a certainpattern. To do this, use the `mod_rewrite`_ module and rewrite URLs to``mysite.fcgi`` (or whatever you specified in the ``FastCGIExternalServer``directive, as explained in the previous section).In this example, we tell Apache to use FastCGI to handle any request thatdoesn't represent a file on the filesystem and doesn't start with ``/media/``.This is probably the most common case, if you're using Django's admin site:: <VirtualHost 12.34.56.78> ServerName example.com DocumentRoot /home/user/public_html Alias /media /home/user/python/django/contrib/admin/media RewriteEngine On RewriteRule ^/(media.*)$ /$1 [QSA,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^/(.*)$ /mysite.fcgi/$1 [QSA,L] </VirtualHost>.. _mod_rewrite: http://httpd.apache.org/docs/2.0/mod/mod_rewrite.htmllighttpd setup==============lighttpd is a lightweight Web server commonly used for serving static files. Itsupports FastCGI natively and, thus, is a good choice for serving both staticand dynamic pages, if your site doesn't have any Apache-specific needs.Make sure ``mod_fastcgi`` is in your modules list, somewhere after``mod_rewrite`` and ``mod_access``, but not after ``mod_accesslog``. You'llprobably want ``mod_alias`` as well, for serving admin media.Add the following to your lighttpd config file:: server.document-root = "/home/user/public_html" fastcgi.server = ( "/mysite.fcgi" => ( "main" => ( # Use host / port instead of socket for TCP fastcgi # "host" => "127.0.0.1", # "port" => 3033, "socket" => "/home/user/mysite.sock", "check-local" => "disable", ) ), ) alias.url = ( "/media/" => "/home/user/django/contrib/admin/media/", ) url.rewrite-once = ( "^(/media.*)$" => "$1", "^/favicon\.ico$" => "/media/favicon.ico", "^(/.*)$" => "/mysite.fcgi$1", )Running multiple Django sites on one lighttpd---------------------------------------------lighttpd lets you use "conditional configuration" to allow configuration to becustomized per host. To specify multiple FastCGI sites, just add a conditionalblock around your FastCGI config for each site:: # If the hostname is 'www.example1.com'... $HTTP["host"] == "www.example1.com" { server.document-root = "/foo/site1" fastcgi.server = ( ... ) ... } # If the hostname is 'www.example2.com'... $HTTP["host"] == "www.example2.com" { server.document-root = "/foo/site2" fastcgi.server = ( ... ) ... }You can also run multiple Django installations on the same site simply byspecifying multiple entries in the ``fastcgi.server`` directive. Add oneFastCGI host for each.Running Django on a shared-hosting provider with Apache=======================================================Many shared-hosting providers don't allow you to run your own server daemons oredit the ``httpd.conf`` file. In these cases, it's still possible to run Djangousing Web server-spawned processes... admonition:: Note If you're using Web server-spawned processes, as explained in this section, there's no need for you to start the FastCGI server on your own. Apache will spawn a number of processes, scaling as it needs to.In your Web root directory, add this to a file named ``.htaccess`` :: AddHandler fastcgi-script .fcgi RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ mysite.fcgi/$1 [QSA,L]Then, create a small script that tells Apache how to spawn your FastCGIprogram. Create a file ``mysite.fcgi`` and place it in your Web directory, andbe sure to make it executable:: #!/usr/bin/python import sys, os # Add a custom Python path. sys.path.insert(0, "/home/user/python") # Switch to the directory of your project. (Optional.) # os.chdir("/home/user/myproject") # Set the DJANGO_SETTINGS_MODULE environment variable. os.environ['DJANGO_SETTINGS_MODULE'] = "myproject.settings" from django.core.servers.fastcgi import runfastcgi runfastcgi(method="threaded", daemonize="false")Restarting the spawned server-----------------------------If you change any Python code on your site, you'll need to tell FastCGI thecode has changed. But there's no need to restart Apache in this case. Rather,just reupload ``mysite.fcgi``, or edit the file, so that the timestamp on thefile will change. When Apache sees the file has been updated, it will restartyour Django application for you.If you have access to a command shell on a Unix system, you can accomplish thiseasily by using the ``touch`` command:: touch mysite.fcgiServing admin media files=========================Regardless of the server and configuration you eventually decide to use, you willalso need to give some thought to how to serve the admin media files. Theadvice given in the modpython_ documentation is also applicable in the setupsdetailed above... _modpython: ../modpython/#serving-the-admin-files