$Id: $

the FastCGI Interface
=====================

lighttpd provides an interface to a external programs that support the
FastCGI interface. The FastCGI Interface is defined by
http://www.fastcgi.com/ and is a platform-indepentant and server 
independant interface between a web-application and a webserver.

This means that FastCGI programs that run with the Apache Webserver will run
seamlessly with lighttpd and vice versa.

FastCGI
-------
FastCGI is removes a lot of the limitations of CGI programs. CGI programs
have the problem that they have to be restarted by the webserver for every
request which leads to really bad performance values.

FastCGI removes this limitation by keeping the process running and handling
the requests by this always running process. This removes the time used for
the fork() and the overall startup and cleanup time which is neccesary to
create and destroy a process.

While CGI programs communicate to the server over pipes, FastCGI processes
use Unix-Domain-Sockets or TCP/IP to talk with the webserver. This gives you
the second advantage over simple CGI programs: FastCGI don't have to run on
the Webserver itself but everywhere in the network. 

lighttpd takes it a little bit further by providing a internal FastCGI
load-balancer which can be used to balance the load over multiple FastCGI
Servers. In contrast to other solutions only the FastCGI process has to be
on the cluster and not the whole webserver. That gives the FastCGI process
more resources than a e.g. load-balancer+apache+mod_php solution.

If you compare FastCGI against a apache+mod_php solution you should note
that FastCGI provides additional security as the FastCGI process can be run
under different permissions that the webserver and can also live a chroot
which might be different than the one the webserver is running in. 

Preparing PHP as a FastCGI program
----------------------------------

One of the most important application that has a FastCGI interface is php
which can be downloaded from http://www.php.net/ . You have to recompile the
php from source to enable the FastCGI interface as it is normally not
enabled by default in the distributions.

If you already have a working installation of PHP on a webserver execute a small
script which just contains

  <?php phpinfo(); ?>
  
and search for the line in that contains the configure call. You can use it as 
the base for the compilation.

You have to add three switches to compile PHP with FastCGI support 

  $ ./configure \
    --enable-fastcgi \
    --enable-discard-path \
    --enable-force-cgi-redirect \
    ...
    
--enable-fastcgi enables the FastCGI support in the CGI-Server API which
means that all switches to enable APXS or Apache SAPI have to be removed.

After compilation and installation check that your PHP binary contains
FastCGI support by calling:

  $ php -v
  PHP 4.3.3RC2-dev (cgi-fcgi) (built: Oct 19 2003 23:19:17)

The important part is the (cgi-fcgi).

Starting a FastCGI-PHP
----------------------

For convinience you should use the spawn-php.sh script located in the
download area of lighttpd for starting a FastCGI-PHP.

The script has a set of config variables you should take a look at:

## ABSOLUTE path to the spawn-fcgi binary
SPAWNFCGI="/usr/local/sbin/spawn-fcgi"

## ABSOLUTE path to the PHP binary
FCGIPROGRAM="/usr/local/bin/php"

## bind to tcp-port on localhost
FCGIPORT="1026"

## number of PHP childs to spawn
PHP_FCGI_CHILDREN=10

## number of request server by a single php-process until is will be restarted
PHP_FCGI_MAX_REQUESTS=1000

## IP adresses where PHP should access server connections from
FCGI_WEB_SERVER_ADDRS="127.0.0.1,192.168.0.1"

# allowed environment variables sperated by spaces
ALLOWED_ENV="ORACLE_HOME PATH USER"

## if this script is run as root switch to the following user
USERID=wwwrun
GROUPID=wwwrun

If you have set the variables to values that fit to your setup you can start
it by calling:

  $ spawn-php.sh
  spawn-fcgi.c.136: child spawned successfully: PID: 6925
  
If you get "child spawned successfully: PID:" the php processes could be
started successfully. You should see them in your processlist:
  $ ps ax | grep php
  6925 ?        S      0:00 /usr/local/bin/php
  6928 ?        S      0:00 /usr/local/bin/php
  ...
  
The number of processes should be PHP_FCGI_CHILDREN + 1. Here the process
6925 is the master of the slaves which handle the work in parallel. Number
of parallel workers can be set by PHP_FCGI_CHILDREN. A worker dies
automaticly of handling PHP_FCGI_MAX_REQUESTS requests as PHP might have
memory leaks.

If you start the script as user root php processes will be running as the
user USERID and group GROUPID to drop the root permissions. Otherwise the
php processes will run as the user you started script as.

As the script might be started from a unknown stage or even directly from
the command-line it cleans the environment before starting the processes.
ALLOWED_ENV contains all the external environement variables that should be
available to the php-process.



Configuring lighttpd for FastCGI
--------------------------------

lighttpd provides the FastCGI support via the fastcgi-module (mod_fastcgi)
which provides 2 options in the config-file:

fastcgi.debug
  a value between 0 and 65535 to set the debug-level in the FastCGI module.
  Currently only 0 and 1 are used. Use 1 to enable some debug output, 0 to
  disable it.
  
fastcgi.server
  tell the module where to send FastCGI requests to. Every file-extension
  can have it own handler. Load-Balancing is done by specifying multiple
  handles for the same extension.

  structure of custom-ARRAY:
    ( <extension> => 
      ( <handle> => 
        ( "host" => <string> ,
	  "docroot" => <string>,  # OPTIONAL
	  "port" => <integer> )
      ), 
      ( <handle> => ... 
      )
    )
    
  <extension> is the file-extension
  <handle>    is just a unique handle name
  "host"      is hostname/ip of the FastCGI process
  "docroot"   is optional and is the docroot on the remote host
  "port"      is tcp-port on the "host" used by the FastCGI process

  e.g.:
  fastcgi.server              = ( ".php" =>
 				  ( "grisu" => 
				    ( 
				      "host" => "192.168.0.2",
				      "port" => 1026
				    )
				  )
			        )
				



Troubleshooting
---------------

fastcgi.debug should be enabled for troubleshooting.

If you get:

(fcgi.c.274) connect delayed:  8
(fcgi.c.289) connect succeeded:  8
(fcgi.c.745) unexpected end-of-file (perhaps the fastcgi process died):  8

the fastcgi process accepted the connection but closed it right away. This
happens if FCGI_WEB_SERVER_ADDRS doesn't include the host where you are
connection from.

If you get 

(fcgi.c.274) connect delayed:  7
(fcgi.c.1107) error: unexpected close of fastcgi connection for /peterp/seite1.php (no fastcgi process on host/port ?)
(fcgi.c.1015) emergency exit: fastcgi: connection-fd: 5 fcgi-fd: 7

the fastcgi process is not running on the host/port you are connection to.
Check your configuration.

If you get

(fcgi.c.274) connect delayed:  7
(fcgi.c.289) connect succeeded:  7

everything is fine. The connect() call just was delayed a little bit and is
completly normal.

