There are two ways to set up PHP to run via
mod_fcgid. The majority of the steps are the same for both, the only difference is in your Apache VirtualHost configuration. This document will explain both.
Step 1: Installation and Preparation
Chances are you’ve already done these steps
- Install the PHP CGI binary
- Install and enable the following modules:
mod_actions(only required for Option 2)
mod_phpif it is installed
Typically you’ll install these using the package manager for your OS (e.g.
Step 2: Create PHP launcher in a suEXEC-friendly location
suEXEC only allows scripts under /var/www/ to be executed, and is picky about permissions.
Create a directory under which we can put our script:
mkdir /var/www/fcgi-bin/ mkdir /var/www/fcgi-bin/someuser/
Next we make our script:
----- File: /var/www/fcgi-bin/someuser/php.fcgi ----- #!/bin/bash exec /usr/bin/php-cgi
And of course mark it as executable and set ownership:
chmod a+x /var/www/fcgi-bin/someuser/php.fcgi chown -R someuser:someuser /var/www/fcgi-bin/someuser/
It’s also a good idea to remove write permission from this dir and all its files.
chmod a-w -R /var/www/fcgi-bin/someuser
Note that any additional PHP configuration you want to do can go into that file. Specifying
a per-user php.ini file for example by changing PHPRC and other PHP environment variables.
Step 3: Apache Configuration
First of all, remove (comment out) any PHP configuration already there. Next, you may want to
add the following fcgid configuration:
AddHandler fcgid-script .fcgi .php .fpl # useful for other fastcgi FcgidConnectTimeout 20 # 20 second timeout on connnect FcgidMaxRequestLen 268435456 # 256MB upload/post limit FcgidMaxProcessesPerClass 10 # Up to 10 PHP processes per user at a time FcgidIOTimeout 300 # 5 minute timeout on request
For the actual PHP configuration, there are two ways to do it. The first way requires ExecCGI to be set on your document root directory, and the second does some munging with URL paths that might break RewriteRules. Note that the configuration shown below is the bare minimum to get this working. You may also want to add thinks like setting a default content-type, additional
Option 1: Using FcgidWrapper
<VirtualHost *:80> Servername example.com DirectoryIndex index.php SuexecUserGroup someuser someuser AddHandler fcgid-script .php FcgidWrapper /var/www/fcgi-bin/someuser/php.fcgi .php <Directory /home/someuser/public_html/> Options +ExecCGI </Directory> </VirtualHost>
Option 2: Using Action
Note that this option has some security concerns, since you’re granting direct access to your executable PHP invocatation script. It also uses
/php-fcgi/php.fcgi as your script name, which could make for problems down the road.
I’m including this example in the interest of completeness, but Option 1 is probably better all around.
<VirtualHost *:80> Servername example.com DirectoryIndex index.php SuexecUserGroup someuser someuser ScriptAlias /php-fcgi/ /var/www/fcgi-bin/someuser/ AddHandler php-via-fcgi .php Action php-via-fcgi /php-fcgi/php.fcgi </VirtualHost>
With this setup,
ExecCGI needs to be set for the directory where you find
php.fcgi instead of where your
.php files are located. We handle this implicitly by using
ScriptAlias instead of
The suEXEC security checks are applied to the
.fcgifile, not to the
.phpfiles. This means that the scripts themselves and the directories they reside in may be owned by any user (for better or for worse).
If you have multiple users, then each user gets his own directory and
/var/www/fcgi-bin/. You can customize the PHP environment for each user by customizing that file.
If you aren’t using suEXEC, then you don’t need a per-user
php.fcgifile, nor does it need to be in a per-user directory. Simply creating one file at
/var/www/php-fcgi/php.fcgiwill be sufficient.
Your working directory while executing your PHP scripts will be
/var/www/php-fcgi/someuser/. Make sure you either
chdirto your desired working directory or design your scripts so that they won’t depend on this particular detail.