xref: /lighttpd1.4/doc/outdated/fastcgi.txt (revision c752d469)
1=====================
2the FastCGI Interface
3=====================
4
5-------------------
6Module: mod_fastcgi
7-------------------
8
9:Author: Jan Kneschke
10:Date: $Date: 2004/11/03 22:26:05 $
11:Revision: $Revision: 1.3 $
12
13:abstract:
14  The FastCGI interface is the fastest and most secure way
15  to interface external process-handlers like Perl, PHP and
16  your self-written applications.
17
18.. meta::
19  :keywords: lighttpd, FastCGI
20
21.. contents:: Table of Contents
22
23Description
24===========
25
26lighttpd provides an interface to a external programs that
27support the FastCGI interface. The FastCGI Interface is
28defined by http://www.fastcgi.com/ and is a
29platform-independent and server independent interface between
30a web-application and a webserver.
31
32This means that FastCGI programs that run with the Apache
33Webserver will run seamlessly with lighttpd and vice versa.
34
35
36FastCGI
37-------
38
39FastCGI is removes a lot of the limitations of CGI programs.
40CGI programs have the problem that they have to be restarted
41by the webserver for every request which leads to really bad
42performance values.
43
44FastCGI removes this limitation by keeping the process running
45and handling the requests by this always running process. This
46removes the time used for the fork() and the overall startup
47and cleanup time which is necessary to create and destroy a
48process.
49
50While CGI programs communicate to the server over pipes,
51FastCGI processes use Unix-Domain-Sockets or TCP/IP to talk
52with the webserver. This gives you the second advantage over
53simple CGI programs: FastCGI don't have to run on the Webserver
54itself but everywhere in the network.
55
56lighttpd takes it a little bit further by providing a internal
57FastCGI load-balancer which can be used to balance the load
58over multiple FastCGI Servers. In contrast to other solutions
59only the FastCGI process has to be on the cluster and not the
60whole webserver. That gives the FastCGI process more resources
61than a e.g. load-balancer+apache+mod_php solution.
62
63If you compare FastCGI against a apache+mod_php solution you
64should note that FastCGI provides additional security as the
65FastCGI process can be run under different permissions that
66the webserver and can also live a chroot which might be
67different than the one the webserver is running in.
68
69Options
70=======
71
72lighttpd provides the FastCGI support via the fastcgi-module
73(mod_fastcgi) which provides 2 options in the config-file:
74
75fastcgi.debug
76  a value between 0 and 65535 to set the debug-level in the
77  FastCGI module. Currently only 0 and 1 are used. Use 1 to
78  enable some debug output, 0 to disable it.
79
80fastcgi.map-extensions
81  map multiple extensions to the same fastcgi server
82
83  Example: ::
84
85    fastcgi.map-extensions = ( ".php3" => ".php" )
86
87fastcgi.server
88  tell the module where to send FastCGI requests to. Every
89  file-extension can have it own handler. Load-Balancing is
90  done by specifying multiple handles for the same extension.
91
92  structure of fastcgi.server section: ::
93
94    ( <extension> =>
95      (
96        ( "host" => <string> ,
97          "port" => <integer> ,
98          "socket" => <string>,       # either socket
99                                      # or host+port
100          "bin-path" => <string>,     # OPTIONAL
101          "bin-environment" => <array>, # OPTIONAL
102          "bin-copy-environment" => <array>, # OPTIONAL
103          "mode" => <string>,         # OPTIONAL
104          "docroot" => <string> ,     # OPTIONAL if "mode"
105                                      # is not "authorizer"
106          "check-local" => <string>,  # OPTIONAL
107          "max-procs" => <integer>,   # OPTIONAL
108          "broken-scriptfilename" => <boolean>, # OPTIONAL
109          "disable-time" => <integer>, # optional
110          "x-sendfile" => <boolean>, # optional (replaces "allow-x-send-file")
111          "x-sendfile-docroot" => <boolean>, # optional
112          "kill-signal" => <integer>, # OPTIONAL
113          "fix-root-scriptname" => <boolean>,
114                                      # OPTIONAL
115        ( "host" => ...
116        )
117      )
118    )
119
120  :<extension>: is the file-extension or prefix
121                (if started with "/")
122  :"host":      is hostname/ip of the FastCGI process
123  :"port":      is tcp-port on the "host" used by the FastCGI
124                process
125  :"bin-path":  path to the local FastCGI binary which should be
126                started if no local FastCGI is running
127  :"socket":    path to the unix-domain socket
128  :"mode":      is the FastCGI protocol mode.
129                Default is "responder", also "authorizer"
130                mode is implemented.
131  :"docroot":   is optional and is the docroot on the remote
132                host for default "responder" mode. For
133                "authorizer" mode it is MANDATORY and it points
134                to docroot for authorized requests. For security
135                reasons it is recommended to keep this docroot
136                outside of server.document-root tree.
137  :"check-local": is optional and may be "enable" (default) or
138                "disable". If enabled the server first check
139                for a file in local server.document-root tree
140                and return 404 (Not Found) if no such file.
141                If disabled, the server forward request to
142                FastCGI interface without this check.
143  :"broken-scriptfilename": breaks SCRIPT_FILENAME in a wat that
144                PHP can extract PATH_INFO from it (default: disabled)
145  :"disable-time": time to wait before a disabled backend is checked
146                again
147  :"x-sendfile": controls if X-Sendfile backend response header is allowed
148                (deprecated headers: X-Sendfile2 and X-LIGHTTPD-send-file)
149                ("x-sendfile" replaces "allow-x-sendfile")
150  :"x-sendfile-docroot": list of directory trees permitted with X-Sendfile
151  :"fix-root-scriptname": fix broken path-info split for "/" extension ("prefix")
152
153  If bin-path is set:
154
155  :"max-procs": the upper limit of the processes to start
156  :"bin-environment": put an entry into the environment of
157                the started process
158  :"bin-copy-environement": clean up the environment and copy
159                only the specified entries into the fresh
160                environment of the spawn process
161  :"kill-signal": signal to terminate the FastCGI process with,
162                defaults to SIGTERM
163
164Examples
165--------
166
167  Multiple extensions for the same host ::
168
169    fastcgi.server = ( ".php" =>
170      (( "host" => "127.0.0.1",
171         "port" => 1026,
172         "bin-path" => "/usr/local/bin/php"
173      )),
174      ".php4" =>
175      (( "host" => "127.0.0.1",
176         "port" => 1026
177      ))
178    )
179
180  Example with prefix: ::
181
182    fastcgi.server = ( "/remote_scripts/" =>
183      (( "host" => "192.168.0.3",
184         "port" => 9000,
185         "check-local" => "disable",
186         "docroot" => "/" # remote server may use
187                          # it's own docroot
188      ))
189    )
190
191  The request `http://my.host.com/remote_scripts/test.cgi` will
192  be forwarded to fastcgi server at 192.168.0.3 and the value
193  "/remote_scripts/test.cgi" will be used for the SCRIPT_NAME
194  variable. Remote server may prepend it with its own
195  document root. The handling of index files is also the
196  responsibility of remote server for this case.
197
198  In the case that the prefix is not terminated with a slash
199  the prefix will be handled as file and /test.cgi would become
200  a PATH_INFO instead of part of SCRIPT_NAME.
201
202
203  Example for "authorizer" mode: ::
204
205    fastcgi.server = ( "/remote_scripts/" =>
206      (( "host" => "10.0.0.2",
207         "port" => 9000,
208         "docroot" => "/path_to_private_docs",
209         "mode" => "authorizer"
210      ))
211    )
212
213  Note that if "docroot" is specified then its value will be
214  used in DOCUMENT_ROOT and SCRIPT_FILENAME variables passed
215  to FastCGI server.
216
217Load-Balancing
218==============
219
220The FastCGI plugin provides automatically a load-balancing between
221multiple FastCGI servers. ::
222
223  fastcgi.server = ( ".php" =>
224     (( "host" => "10.0.0.2", "port" => 1030 ),
225      ( "host" => "10.0.0.3", "port" => 1030 ))
226    )
227
228
229To understand how the load-balancing works you can enable the
230fastcgi.debug option and will get a similar output as here: ::
231
232  proc: 127.0.0.1 1031  1 1 1 31454
233  proc: 127.0.0.1 1028  1 1 1 31442
234  proc: 127.0.0.1 1030  1 1 1 31449
235  proc: 127.0.0.1 1029  1 1 2 31447
236  proc: 127.0.0.1 1026  1 1 2 31438
237  got proc: 34 31454
238  release proc: 40 31438
239  proc: 127.0.0.1 1026  1 1 1 31438
240  proc: 127.0.0.1 1028  1 1 1 31442
241  proc: 127.0.0.1 1030  1 1 1 31449
242  proc: 127.0.0.1 1031  1 1 2 31454
243  proc: 127.0.0.1 1029  1 1 2 31447
244
245Even if this for multiple FastCGI children on the local machine
246the following explanation is valid for remote connections too.
247
248The output shows:
249
250- IP, port, unix-socket (is empty here)
251- is-local, state (0 - unset, 1 - running, ... )
252- active connections (load)
253- PID
254
255As you can see the list is always sorted by the load field.
256
257Whenever a new connection is requested, the first entry (the one
258with the lowest load) is selected, the load is increased (got proc: ...)
259and the list is sorted again.
260
261If a FastCGI request is done or the connection is dropped, the load on the
262FastCGI proc decreases and the list is sorted again (release proc: ...)
263
264This behaviour is very light-weight in code and still very efficient
265as it keeps the fastcgi-servers equally loaded even if they have different
266CPUs.
267
268Adaptive Process Spawning
269=========================
270
271.. note:: This feature is disabled in 1.3.14 again. min-procs is
272          ignored in that release
273
274Starting with 1.3.8 lighttpd can spawn processes on demand if
275a bin-path is specified and the FastCGI process runs locally.
276
277If you want to have a least one FastCGI process running and
278more of the number of requests increases you can use min-procs
279and max-procs.
280
281A new process is spawned as soon as the average number of
282requests waiting to be handle by a single process increases the
283max-load-per-proc setting.
284
285The idle-timeout specifies how long a fastcgi-process should wait
286for a new request before it kills itself.
287
288Example
289-------
290::
291
292  fastcgi.server = ( ".php" =>
293    (( "socket" => "/tmp/php.socket",
294       "bin-path" => "/usr/local/bin/php",
295       "min-procs" => 1,
296       "max-procs" => 32,
297       "max-load-per-proc" => 4,
298       "idle-timeout" => 20
299    ))
300   )
301
302Disabling Adaptive Spawning
303---------------------------
304
305Adaptive Spawning is a quite new feature and it might misbehave
306for your setup. There are several ways to control how the spawning
307is done:
308
3091. ``"max-load-per-proc" => 1``
310   if that works for you, great.
311
3122. If not set ``min-procs == max-procs``.
313
3143. For PHP you can also use: ::
315
316     $ PHP_FCGI_CHILDREN=384 ./lighttpd -f ./lighttpd.conf
317
318     fastcgi.server = ( ".php" =>
319        (( "socket" => "/tmp/php.socket",
320           "bin-path" => "/usr/local/bin/php",
321           "min-procs" => 1,
322           "max-procs" => 1,
323           "max-load-per-proc" => 4,
324           "idle-timeout" => 20
325        ))
326      )
327
328   It will create one socket and let's PHP create the 384 processes itself.
329
3304. If you don't want lighttpd to manage the fastcgi processes, remove the
331   bin-path and use spawn-fcgi to spawn them itself.
332
333
334FastCGI and Programming Languages
335=================================
336
337Preparing PHP as a FastCGI program
338----------------------------------
339
340One of the most important application that has a FastCGI
341interface is php which can be downloaded from
342http://www.php.net/ . You have to recompile the php from
343source to enable the FastCGI interface as it is normally
344not enabled by default in the distributions.
345
346If you already have a working installation of PHP on a
347webserver execute a small script which just contains ::
348
349  <?php phpinfo(); ?>
350
351and search for the line in that contains the configure call.
352You can use it as the base for the compilation.
353
354You have to remove all occurrences of `--with-apxs`, `--with-apxs2`
355and the like which would build PHP with Apache support.  Add the
356next three switches to compile PHP with FastCGI support::
357
358  $ ./configure \
359    --enable-fastcgi \
360    --enable-force-cgi-redirect \
361    ...
362
363After compilation and installation check that your PHP
364binary contains FastCGI support by calling: ::
365
366  $ php -v
367  PHP 4.3.3RC2-dev (cgi-fcgi) (built: Oct 19 2003 23:19:17)
368
369The important part is the (cgi-fcgi).
370
371
372Starting a FastCGI-PHP
373----------------------
374
375Starting with version 1.3.6 lighttpd can spawn the FastCGI
376processes locally itself if necessary: ::
377
378  fastcgi.server = ( ".php" =>
379    (( "socket" => "/tmp/php-fastcgi.socket",
380       "bin-path" => "/usr/local/bin/php"
381    ))
382  )
383
384PHP provides 2 special environment variables which control the number of
385spawned works under the control of a single watching process
386(PHP_FCGI_CHILDREN) and the number of requests what a single worker
387handles before it kills itself. ::
388
389  fastcgi.server = ( ".php" =>
390     (( "socket" => "/tmp/php-fastcgi.socket",
391        "bin-path" => "/usr/local/bin/php",
392        "bin-environment" => (
393          "PHP_FCGI_CHILDREN" => "16",
394          "PHP_FCGI_MAX_REQUESTS" => "10000"
395        )
396     ))
397   )
398
399To increase the security of the started process you should only pass
400the necessary environment variables to the FastCGI process. ::
401
402  fastcgi.server = ( ".php" =>
403     (( "socket" => "/tmp/php-fastcgi.socket",
404        "bin-path" => "/usr/local/bin/php",
405        "bin-environment" => (
406           "PHP_FCGI_CHILDREN" => "16",
407           "PHP_FCGI_MAX_REQUESTS" => "10000" ),
408        "bin-copy-environment" => (
409           "PATH", "SHELL", "USER" )
410     ))
411   )
412
413Configuring PHP
414---------------
415
416If you want to use PATH_INFO and PHP_SELF in you PHP scripts you have to
417configure php and lighttpd. The php.ini needs the option: ::
418
419  cgi.fix_pathinfo = 1
420
421and the option ``broken-scriptfilename`` in your fastcgi.server config: ::
422
423  fastcgi.server = ( ".php" =>
424     (( "socket" => "/tmp/php-fastcgi.socket",
425        "bin-path" => "/usr/local/bin/php",
426        "bin-environment" => (
427          "PHP_FCGI_CHILDREN" => "16",
428          "PHP_FCGI_MAX_REQUESTS" => "10000" ),
429        "bin-copy-environment" => (
430          "PATH", "SHELL", "USER" ),
431        "broken-scriptfilename" => "enable"
432     ))
433   )
434
435Why this ? the ``cgi.fix_pathinfo = 0`` would give you a working ``PATH_INFO``
436but no ``PHP_SELF``. If you enable it, it turns around. To fix the
437``PATH_INFO`` `--enable-discard-path` needs a SCRIPT_FILENAME which is against the CGI spec, a
438broken-scriptfilename. With ``cgi.fix_pathinfo = 1`` in php.ini and
439``broken-scriptfilename => "enable"`` you get both.
440
441
442External Spawning
443-----------------
444
445Spawning FastCGI processes directly in the webserver has some
446disadvantages like
447
448- FastCGI process can only run locally
449- has the same permissions as the webserver
450- has the same base-dir as the webserver
451
452As soon as you are using a separate FastCGI Server to
453take off some load from the webserver you have to control
454the FastCGI process by a external program like spawn-fcgi.
455
456spawn-fcgi is used to start a FastCGI process in its own
457environment and set the user-id, group-id and change to
458another root-directory (chroot).
459
460For convenience a wrapper script should be used which takes
461care of all the necessary option. Such a script in included
462in the lighttpd distribution and is call spawn-php.sh.
463
464The script has a set of config variables you should take
465a look at: ::
466
467  ## ABSOLUTE path to the spawn-fcgi binary
468  SPAWNFCGI="/usr/local/sbin/spawn-fcgi"
469
470  ## ABSOLUTE path to the PHP binary
471  FCGIPROGRAM="/usr/local/bin/php"
472
473  ## bind to tcp-port on localhost
474  FCGIPORT="1026"
475
476  ## bind to unix domain socket
477  # FCGISOCKET="/tmp/php.sock"
478
479  ## number of PHP children to spawn
480  PHP_FCGI_CHILDREN=10
481
482  ## number of request server by a single php-process until
483  ## is will be restarted
484  PHP_FCGI_MAX_REQUESTS=1000
485
486  ## IP addresses where PHP should access server connections
487  ## from
488  FCGI_WEB_SERVER_ADDRS="127.0.0.1,192.168.0.1"
489
490  # allowed environment variables sperated by spaces
491  ALLOWED_ENV="ORACLE_HOME PATH USER"
492
493  ## if this script is run as root switch to the following user
494  USERID=wwwrun
495  GROUPID=wwwrun
496
497If you have set the variables to values that fit to your
498setup you can start it by calling: ::
499
500  $ spawn-php.sh
501  spawn-fcgi.c.136: child spawned successfully: PID: 6925
502
503If you get "child spawned successfully: PID:" the php
504processes could be started successfully. You should see them
505in your processlist: ::
506
507  $ ps ax | grep php
508  6925 ?        S      0:00 /usr/local/bin/php
509  6928 ?        S      0:00 /usr/local/bin/php
510  ...
511
512The number of processes should be PHP_FCGI_CHILDREN + 1.
513Here the process 6925 is the master of the slaves which
514handle the work in parallel. Number of parallel workers can
515be set by PHP_FCGI_CHILDREN. A worker dies automatically of
516handling PHP_FCGI_MAX_REQUESTS requests as PHP might have
517memory leaks.
518
519If you start the script as user root php processes will be
520running as the user USERID and group GROUPID to drop the
521root permissions. Otherwise the php processes will run as
522the user you started script as.
523
524As the script might be started from a unknown stage or even
525directly from the command-line it cleans the environment
526before starting the processes. ALLOWED_ENV contains all
527the external environment variables that should be available
528to the php-process.
529
530
531Perl
532----
533
534For Perl you have to install the FCGI module from CPAN.
535
536Skeleton for remote authorizer
537==============================
538
539The basic functionality of authorizer is as follows (see
540http://www.fastcgi.com/devkit/doc/fcgi-spec.html, 6.3 for
541details). ::
542
543  #include <fcgi_stdio.h>
544  #include <stdlib.h>
545  #include <unistd.h>
546  int main () {
547    char* p;
548
549    while (FCGI_Accept() >= 0) {
550      /* wait for fastcgi authorizer request */
551
552      printf("Content-type: text/html\r\n");
553
554      if ((p = getenv("QUERY_STRING")) == NULL) ||
555           <QUERY_STRING is unauthorized>)
556           printf("Status: 403 Forbidden\r\n\r\n");
557
558      else printf("\r\n");
559        /* default Status is 200 - allow access */
560    }
561
562    return 0;
563  }
564
565It is possible to use any other variables provided by
566FastCGI interface for authorization check. Here is only an
567example.
568
569
570Troubleshooting
571===============
572
573fastcgi.debug should be enabled for troubleshooting.
574
575If you get: ::
576
577  (fcgi.c.274) connect delayed:  8
578  (fcgi.c.289) connect succeeded:  8
579  (fcgi.c.745) unexpected end-of-file (perhaps the fastcgi
580     process died):  8
581
582the fastcgi process accepted the connection but closed it
583right away. This happens if FCGI_WEB_SERVER_ADDRS doesn't
584include the host where you are connection from.
585
586If you get ::
587
588  (fcgi.c.274) connect delayed:  7
589  (fcgi.c.1107) error: unexpected close of fastcgi connection
590     for /peterp/seite1.php (no fastcgi process on host/port ?)
591  (fcgi.c.1015) emergency exit: fastcgi: connection-fd: 5
592     fcgi-fd: 7
593
594the fastcgi process is not running on the host/port you are
595connection to. Check your configuration.
596
597If you get ::
598
599  (fcgi.c.274) connect delayed:  7
600  (fcgi.c.289) connect succeeded:  7
601
602everything is fine. The connect() call just was delayed a
603little bit and is completely normal.
604
605