Fastcgi based php handler
Mod_fastcgi is an apache module that enables apache to talk to fastcgi enabled applications. It can be used to run php code over fastcgi through the php-cgi binary which is fastcgi enabled.
Fastcgi has many improvements over the traditional cgi model of executing external programs inside a webserver. With fastcgi multiple processes are kept alive and each process is reused to serve multiple requests one after another. There are settings to control the maximum number of requests a process can serve, after which the process is terminated and a new one is started.
Install the packages
The first thing to do is install the necessary packages from synaptic. We need to install the apache server, mod_fastcgi, mpm worker and php along with the cgi binary. Note that if you already have php installed with mpm prefork and mod-php then it would be removed upon installing these packages
$ sudo apt-get install apache2 libapache2-mod-fastcgi apache2-mpm-worker php5 php5-cgi
On ubuntu the apache configuration file located at
/etc/apache2/sites-enabled/000-default
The php cgi binary is located at /usr/bin/php-cgi.
Configure fastcgi
After installing the packages, its time to configure apache to use mod_fastcgi to run php scripts. Like cgi, fastcgi will also run php processes using the php-cgi binary.
First enable the fastcgi module with a2enmod command
$ sudo a2enmod fastcgi
The a2enmod command copies the configuration file of the module from /etc/apache2/mods-available to the directory /etc/apache2/mods-enabled. The configuration file in this case is fastcgi.conf. It looks like this
<IfModule mod_fastcgi.c> AddHandler fastcgi-script .fcgi FastCgiIpcDir /var/lib/apache2/fastcgi </IfModule>
Mod_fastcgi registers a handler called fastcgi-script with apache. This can be used to specify which programs to execute through mod_fastcgi.
Ok, lets move on. Next thing is to configure the relevant vhost to run php using the fastcgi handler. Put the following configuration inside the desired vhost block in the apache configuration file.
<Ifmodule mod_fastcgi.c> FastCgiServer /usr/local/bin/php-fastcgi-wrapper -processes 10 -restart-delay 1 -init-start-delay 1 -pass-header HTTP_AUTHORIZATION Alias /binary /usr/local/bin <Location /binary/php-fastcgi-wrapper> Options ExecCGI SetHandler fastcgi-script </Location> AddHandler php-fastcgi .php Action php-fastcgi /binary/php-fastcgi-wrapper </IfModule>
The FastCgiServer registers /usr/local/bin/php-fastcgi-wrapper as the fastcgi application with various options.
Note that this is a shell script that will launch the php-cgi binary with various settings. Note that we asked the FastCgiServer to create and manage 10 processes.
The AddHandler line declares a new handler for ".php" files called php-fastcgi. This can named to anything you like.
The Action line tells apache to handle php-fastcgi file using the cgi program /cgi-bin/php-fastcgi-wrapper.
Now the location /cgi-bin/php-fastcgi-wrapper is not a real one. To make it point to the real location of wrapper script, the Alias directive is used. It points /cgi-bin to /usr/local/bin.
Wrapper script
Now comes the wrapper script that will be used by fastcgi to run php.
#!/bin/sh # Set desired PHP_FCGI_* environment variables. # Example: # PHP FastCGI processes exit after 500 requests by default. PHP_FCGI_MAX_REQUESTS=10000 export PHP_FCGI_MAX_REQUESTS PHP_FCGI_CHILDREN=5 export PHP_FCGI_CHILDREN # Replace with the path to your FastCGI-enabled PHP executable exec /usr/bin/php-cgi
Note the PHP_FCGI_CHILDREN setting. It specifies that each php process should further fork and manage 5 more child php processes. So earlier fastcgi was told to create 10 processes. The total is 10*5 = 50 processes. There are 2 levels of process management going on. Mod_fastcgi manages 10 php processes and each php process further manages 5 process each.
This file is stored at the following path
/usr/local/bin/php-fastcgi-wrapper
Make sure that the file is executable. Do a chmod on it
/usr/local/bin# chmod +x php-fastcgi-wrapper
The location of the file does not matter. The wrapper script is necessary so that various options like PHP_FCGI_MAX_REQUESTS can be passed on to the php process.
Now restart apache and test the setup by opening a php script in browser. View the contents of the $_SERVER variable in php. It should contain [FCGI_ROLE] => RESPONDER. This indicates that fastcgi is in action.
Also check the process table using htop or System Monitor. You should see 50 php-cgi processes running.
Resource
http://www.fastcgi.com/drupal/node/25
http://www.opensource.apple.com/source/apache_mod_php/apache_mod_php-12/php/sapi/cgi/README.FastCGI
My previous comment about “client denied by server configuration: /usr/local/bin/php-fastcgi-wrapper” has not yet been approved, so I can’t see, edit, or reply to it. But I wanted to post my fix. From: http://stackoverflow.com/a/13923526/135101. Add
[Directory /usr/local/bin]
Require all granted
[/Directory]
to your vhost config.
EDIT: I guess I can’t use markdown here and Disqus is munging my “html” of the directory element, so I replaced angle brackets with brackets.
I got this working on Ubuntu 12.04 with no problems (thanks!). But on 14.04 (with Apache 2.4.7), when I visit the main page, I get a 403 forbidden error that says: “You don’t have permission to access /binary/php-fastcgi-wrapper/index.php”. Do you know why that would be?
I had to enable the multiverse source for apt-get to find the libapache2-mod-fastcgi. This is on ubuntu 12.04 running through vagrant.
And also had to sudo a2enmod actions to be able to restart apache2 successfully.
Thanks for this article. Helped me get set up with a WAY faster method for working with PHP!
I had to enable the multiverse source, but only from Ubuntu 14.04 (see instructions here: http://serversforhackers.com/articles/2014/05/05/apache-proxy-fcgi/. I just needed the section labeled Ubuntu 14.04). I didn’t on 12.04.
I also had to run `sudo a2enmod actions`.