Apache FastCGI
httpd(8) has multiple implementations of the CGI and FastCGI specifications. The below are the most common and easiest to use.
Mod_fcgid
mod_fcgid was designed to be a comprehensive upgrade from mod_cgi and mod_cgid.
Load the mod_fcgid module to enable it.
Perl Example
Consider the following Perl script, which should live under /var/www/fcgi-bin:
use CGI::Fast; while (my $q = CGI::Fast->new) { print("Content-Type: text/plain\n\n"); foreach $var (sort(keys(%ENV))) { $val = $ENV{$var}; $val =~ s|\n|\\n|g; $val =~ s|"|\\"|g; print "${var}=\"${val}\"\n"; } }
With mod_fcgi, httpd(8) can be made to execute this with very little configuration.
<Directory /var/www/fcgi-bin/> SetHandler fcgid-script Options +ExecCGI Order allow,deny Allow from all </Directory>
PHP Example
PHP works very similarly. Consider the following script:
<?php phpinfo(); ?>
Because many servers of significance are written in PHP, it's not realistic to require that they be installed under the web root. While the above script could live anywhere, the below configurations will reference /usr/local/myapp/ as its location.
A wrapper script under /var/www/fcgi-bin will be necessary. It should look like:
# PHP FastCGI processes exit after 500 requests by default. PHP_FCGI_MAX_REQUESTS=10000 export PHP_FCGI_MAX_REQUESTS # Replace with the path to your FastCGI-enabled PHP executable exec /usr/local/bin/php-cgi
Finally, the httpd(8) configuration should look like:
Alias /myapp/ /usr/local/myapp/ <Location /myapp/> AddHandler fcgid-script .php Options +ExecCGI FcgidWrapper /var/www/fcgi-bin/php-wrapper .php Order allow,deny Allow from all </Location>
PHP-FPM
php-fpm(8) is a more performant option, but requires the installation and configuration of a separate server. See here for details on doing that.
Load the mod_proxy and mod_proxy_fcgi modules to enable httpd(8) to proxy to that server.
httpd(8) just needs to be configured to proxy requests.
ProxyPass "/myapp/" "fcgi://localhost:9000/" enablereuse=on
The ProxyPassMatch directive will not only match multiple locations, but will implicitly append the requested URL to the second argument.
ProxyPassMatch "^/myapp/.*\.php(/.*)?$" "fcgi://localhost:9000/var/www/" enablereuse=on
Unix Sockets
If using a Unix socket to pass requests, the configuration should look like:
ProxyPassMatch "^/myapp/(.*\.php(/.*)?)$" "unix:/var/run/php-fpm.sock|fcgi://localhost/var/www/"
Note that the hostname and optional port following fcgi:// are ignored. (The document root is not ignored.)