Code

Ticket #1736: fastcgi-updated.txt

File fastcgi-updated.txt, 18.6 KB (added by jcrasta@…, 8 years ago)

Updated ReST documentation to go with updated patch, includes mir@…'s diff

Line 
1==============================
2How to use Django with FastCGI
3==============================
4
5While the current preferred setup for running django is Apache_ with
6`mod_python`_, for many users on shared hosts FastCGI_ is the only viable
7option.  Also, for certain setups FastCGI allows better security and possibly
8better performance than mod_python.
9
10FastCGI is a method of having an external application serve pages to a
11web-server, via a socket.  Like mod_python, FastCGI allows code to stay in
12memory, thus allowing requests to be served with no start-up time.  Unlike
13mod_python or `mod_perl`_, your fastCGI process does not run inside the
14web-server process, but runs as a separate persistent process.
15
16.. _Apache: http://httpd.apache.org/
17.. _mod_python: http://www.modpython.org/
18.. _mod_perl: http://perl.apache.org/
19
20.. admonition:: Why run code in a separate process?
21
22    The traditional ``mod_foo`` trend in apache has various scripting languages
23    (such as PHP, Python, Perl) running inside the process space of your
24    web server.  While this does achieve a reduction of start time, it comes
25    at the cost of memory, as every apache process gets its own python
26    interpreter, which will use up a considerable amount of RAM. Due
27    to the nature of FastCGI, it is even possible to have processes which run
28    under a different user as the web server process.  On a shared system, this
29    means the ability to further secure your code from other users.
30
31
32Starting your FastCGI server
33============================
34
35Since FastCGI operates on a client-server model, in most cases you will be starting
36the FastCGI process on your own.   Your webserver (be it Apache, LigHTTPd, or otherwise)
37will only contact your Django-FastCGI process when it needs a dynamic page to be loaded.
38Since your daemon is already running with the code in memory, it will be able to serve up
39the response very quickly.
40
41.. admonition:: Note
42
43    Those who are on shared hosting systems will probably be forced to use
44    webserver-managed FastCGI processes.  See the section below on running
45    django with webserver-managed processes for more information on this.
46
47There are two ways the Web server can connect to your FastCGI server.  It can
48either use a unix domain socket (named pipe on win32 systems) or it can use a
49TCP socket.   What you choose is a manner of preference; a TCP socket is usually
50easier due to permissioning issues.
51
52To start your server, first change into the directory of your project (wherever
53your ``manage.py`` is, and then run the manage.py with the runfcgi option::
54
55    python manage.py runfcgi [options]
56
57You can specify ``help`` as the only option after runfcgi, and it will print out
58a listing of all the available options.  You will need to specify either a socket
59or a host and port.
60
61When you set up your web server, you will need to point it at the host/port or
62socket you chose when starting the FastCGI server.
63
64Examples
65--------
66
67Running a threaded server on a TCP port::
68   
69    ./manage.py runfcgi method=threaded host=127.0.0.1 port=3033
70
71Running a preforked server on a Unix domain socket::
72
73    ./manage.py runfcgi method=prefork socket=/home/user/mysite.sock pidfile=django.pid
74
75Run without daemonizing (backgrounding) the process (good for debugging)::
76
77    ./manage.py runfcgi daemonize=false socket=/tmp/mysite.sock
78
79
80Stopping the FastCGI daemon
81---------------------------
82
83If you have the process running in the foreground, it's easy enough to stop it,
84simply hitting ``Ctrl-C`` will cause the FastCGI server to exit.  However, when
85we're dealing with background processes, you will need to resort to the unix
86``kill`` command. 
87
88If you specify the ``pidfile`` option to your manage.py runfcgi, you can then kill
89the running FastCGI daemon like this::
90   
91    kill `cat $PIDFILE`
92
93For unix users, to easily restart your FastCGI daemon, this small
94shell script may be of use::
95
96    #!/bin/bash
97
98    PROJDIR="/home/user/myproject"
99    PIDFILE="$PROJDIR/mysite.pid"
100    SOCKET="$PROJDIR/mysite.sock"
101
102    cd $PROJDIR
103    if [ -f $PIDFILE ]; then
104        kill `cat -- $PIDFILE`
105        rm -f -- $PIDFILE
106    fi
107
108    exec /usr/bin/env - \
109      PYTHONPATH="../python:.." \
110      ./manage.py runfcgi socket=$SOCKET pidfile=$PIDFILE
111
112   
113Apache Setup
114============
115
116To configure Django with apache and FastCGI, you must have Apache installed
117and set up, with mod_fastcgi installed and enabled.  Consult your server
118documentation for doing so.
119
120Add the following to your httpd.conf::
121
122    # Connect to FastCGI via a socket / named pipe
123    FastCGIExternalServer /home/user/public_html/mysite.fcgi -socket /home/user/mysite.sock
124    # Connect to FastCGI via a TCP host/port
125    # FastCGIExternalServer /home/user/public_html/mysite.fcgi -host 127.0.0.1:3033
126
127    <VirtualHost 64.92.160.91>
128      ServerName mysite.com
129      DocumentRoot /home/user/public_html
130      Alias /media /home/user/python/django/contrib/admin/media
131      RewriteEngine On
132      RewriteRule ^/(media.*)$ /$1 [QSA,L]
133      RewriteCond %{REQUEST_FILENAME} !-f
134      RewriteRule ^/(.*)$ /mysite.fcgi/$1 [QSA,L]
135    </VirtualHost>
136
137Note that while you have to specify a mysite.fcgi, that this file doesn't
138actually have to exist.  It is just an internal URL to the webserver which
139signifies that any requests to that URL will go to the external FastCGI
140server.
141
142
143
144LigHTTPd Setup
145==============
146
147LigHTTPd is a light-weight asynchronous web-server, which is commonly used
148for serving static files.  However, it supports FastCGI natively, and as such
149is a very good choice for serving both static and dynamic media, if your site
150does not have any apache-specific components.
151
152Make sure ``mod_fastcgi`` is in your modules list, somewhere after
153mod_rewrite and mod_access, but not after mod_accesslog.  You'll probably
154want mod_alias as well, for serving admin media.
155
156Add the following to your lighttpd config file::
157
158    server.document-root = "/home/user/public_html"
159    fastcgi.server = (
160        "/mysite.fcgi" => (
161            "main" => (
162                # Use host / port instead of socket for TCP fastcgi
163                # "host" => "127.0.0.1",
164                # "port"  => 3033,
165                "socket" => "/home/user/mysite.sock",
166                "check-local" => "disable",
167            )
168        ),
169    )
170    alias.url = (
171        "/media/" => "/home/user/django/contrib/admin/media/",
172    )
173
174    url.rewrite-once = (
175        "^(/media.*)$" => "$1",
176        "^/favicon\.ico$" => "/media/favicon.ico",
177        "^(/.*)$" => "/mysite.fcgi$1",
178    )
179
180Running multiple django sites on one LigHTTPd
181---------------------------------------------
182
183LigHTTPd allows you to use what is called conditional configuration to allow
184configuration to be customized per-host.  In order to specify multiple fastcgi
185sites, simply add a conditional block around your fastcgi config for each site::
186
187    $HTTP["host"] == "www.website1.com" {
188        server.document-root = "/foo/site1"
189        fastcgi.server = (
190           ...
191        )
192        ...
193    }
194
195    $HTTP["host"] == "www.website2.com" {
196        server.document-root = "/foo/site2"
197        fastcgi.server = (
198           ...
199        )
200        ...
201    }
202
203You can also run multiple django installations on the same site simply by
204specifying multiple entries in the ``fastcgi.server`` directive, add one
205fastcgi host for each.
206
207
208Running Django on a shared-hosting provider
209===========================================
210
211For many users on shared-hosting providers, you aren't able to run your own
212server daemons nor do they have access to the httpd.conf of their webserver.
213However, it is still possible to run Django using webserver-spawned processes.
214
215
216.. admonition:: Note
217
218    If you are using webserver-managed processes, there's no need for you
219    to start the FastCGI server on your own.  Apache will spawn a number
220    of processes, scaling as it needs to.
221
222
223In your web root directory, add this to a file named .htaccess ::
224
225    AddHandler fastcgi-script .fcgi
226    RewriteEngine On
227    RewriteCond %{REQUEST_FILENAME} !-f
228    RewriteRule ^/(.*)$ /mysite.fcgi/$1 [QSA,L]
229
230
231Now you must add a small shim script in order for apache to properly
232spawn your FastCGI program.  Create a mysite.fcgi and place it in your
233web directory, making it executable ::
234
235    #!/usr/bin/python
236    import sys, os
237
238    # add a custom pythonpath
239    sys.path.insert(0, "/home/user/python")
240
241    # switch to the directory of your project. (optional)
242    # os.chdir("/home/user/myproject")
243
244    # change to the name of your app's settings module
245    os.environ['DJANGO_SETTINGS_MODULE'] = "myproject.settings"
246
247    from django.core.servers.fastcgi import runfastcgi
248    runfastcgi(["method=threaded", "daemonize=false"])
249
250
251Restarting the spawned server
252-----------------------------
253
254If you change the code of your site, to make apache re-load your django
255application, you do not need to restart the server.  Simply re-upload or
256edit your ``mysite.fcgi`` in such a way that the timestamp on the file
257will change.  When apache sees that the file has been updated, it will
258restart your django application for you.
259
260If you have access to a command shell on a unix system, restarting the
261server can be done with the ``touch`` command::
262   
263    touch mysite.fcgi