Setup Apache and Php with mod_fcgid on Ubuntu/Debian
Mod Fcgid is an apache module that enables it to talk to fastcgi enabled application. It can be used to setup with apache to run php over fastcgi. It is an alternative to the older mod_fastcgi and has some differences with it.
In this post we shall be setting up apache with php using this module. You can also setup apache + php with mod_fastcgi.
Since fastcgi keeps php execution out of apache, we are free to use a thread based mpm like mpm worker.
For the setup we need apache, php (with cgi binary), mod_fcgid, mpm worker. Install them right away from the commandline.
# sudo apt-get install apache2 libapache2-mod-fcgid apache2-mpm-worker php5 php5-cgi
# sudo a2enmod fcgid
Locate configuration files
After installing the necessary packages, its time to configure mod_fcgid. The configuration is mostly done through various configuration files. Therefore its important to know where the configuration files are.
The apache configuration file on ubuntu/debian is located at the following path
To find out the location of apache configuration file for your distro, use the apache2/httpd/apachectl command.
# apachectl -S apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName VirtualHost configuration: wildcard NameVirtualHosts and _default_ servers: *:80 is a NameVirtualHost default server 127.0.1.1 (/etc/apache2/sites-enabled/000-default:1) port 80 namevhost 127.0.1.1 (/etc/apache2/sites-enabled/000-default:1) Syntax OK
So the configuration file is at /etc/apache2/sites-enabled/000-default.
Apache needs to configured to use mod_fcgid to process all ".php" files and mod_fcgid needs to be told the location of the php fastcgi binary, which is php-cgi located at
Add the following configuration to the root directory section in the vhost block
<Ifmodule mod_fcgid.c> # FCGID registers a handler named fcgid-script AddHandler fcgid-script .php Options +ExecCGI FcgidWrapper /usr/local/bin/php-fcgid-wrapper </IfModule>
This tells apache to use the wrapper script to launch fastcgi process php-cgi. It also tells apache to run .php files using fcgid handler.
To control the fcgid settings like maximum number of processes, add the relevant settings outside the vhost block.
<Ifmodule mod_fcgid.c> # Context - server config FcgidMaxProcesses 150 # Otherwise php output shall be buffered FcgidOutputBufferSize 0 </IfModule>
These settings apply to the server context and hence must be outside any Vhost block.
Now the wrapper script that is used by mod_fcgid to launch php-cgi processes.
#!/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 # Replace with the path to your FastCGI-enabled PHP executable exec /usr/bin/php-cgi
We are storing the wrapper script at /usr/local/bin/php-fcgid-wrapper but it can be stored anywhere and the path has to be mentioned in apache configuration.
Make the wrapper script executable using chmod
/usr/local/bin# chmod +x php-fcgid-wrapper
Otherwise you get an error in your apache log like this
[Tue Jun 11 02:53:20 2013] [warn] [client 127.0.0.1] (104)Connection reset by peer: mod_fcgid: error reading data from FastCGI server [Tue Jun 11 02:53:20 2013] [error] [client 127.0.0.1] Premature end of script headers: server.php
Also make sure not to use the "PHP_FCGI_CHILDREN" setting. The php-cgi binary can fork out multiple child processes and manage them, but fcgid will not pass more than a single request to the php-cgi binary at a time, hence the child processes wont be used. This is explained in the documentation
PHP child process management (PHP_FCGI_CHILDREN) should always be disabled with mod_fcgid, which will only route one request at a time to application processes it has spawned; thus, any child processes created by PHP will not be used effectively. (Additionally, the PHP child processes may not be terminated properly.) By default, and with the environment variable setting PHP_FCGI_CHILDREN=0, PHP child process management is disabled. The popular APC opcode cache for PHP cannot share a cache between PHP FastCGI processes unless PHP manages the child processes. Thus, the effectiveness of the cache is limited with mod_fcgid; concurrent PHP requests will use different opcode caches.
Also you cannot use APC with fcgid.