Overview
The FastCGI module in IIS enables popular application frameworks
that support the FastCGI protocol to be hosted on the IIS web server in
a high-performance and reliable way. FastCGI provides a
high-performance alternative to the Common Gateway Interface (CGI), a
standard way of interfacing external applications with Web servers that
has been supported as part of the IIS feature-set since the very first
release.
CGI programs are executables launched by the web server for each
request in order to process the request and generate dynamic responses
that are sent back to the client. Because many of these frameworks do
not support multi-threaded execution, CGI enables them to execute
reliably on IIS by executing exactly one request per process.
Unfortunately, it provides poor performance due to the high cost of
starting and shutting down a process for each request.
FastCGI addresses the performance issues inherent in CGI by
providing a mechanism to reuse a single process over and over again for
many requests. Additionally, FastCGI maintains compatibility with
non-thread-safe libraries by providing a pool of reusable processes and
ensuring that each process will only handle one request at a time.
Enabling FastCGI Support in IIS 7.0
Windows Server 2008
Add the CGI role service by going to Server Manager -> Roles
-> Add Role Services. This enables both the CGI and FastCGI services:
Windows Vista SP1
Add the CGI feature by going to Control Panel -> Programs and
Features -> Turn Windows features on or off. This enables both the
CGI and FastCGI services.
IMPORTANT: Install the update for FastCGI module
The update for IIS 7.0 FastCGI module fixes several known
compatibility issues with popular PHP applications. Install the update
from one of the following locations:
- Update for Windows Server 2008
- Update for Windows Server 2008 x64 Edition
- Update for Windows Server 2008 for Itanium-based Systems
- Update for Windows Vista SP1
- Update for Windows Vista SP1 for x64 based Systems
Install Administration Pack for IIS 7.0
NOTE: This step is optional.
Among other useful features Administration Pack for IIS 7.0 has a
very convenient user interface for configuring FastCGI settings.
Administration Pack can be installed from these locations:
Install and Configure PHP
It is recommended to use a non-thread safe build of PHP with IIS 7.0
FastCGI. A non-thread safe build of PHP provides significant
performance gains over the standard build by not doing any
thread-safety checks, which are not necessary, since FastCGI ensures a
single threaded execution environment.
- Download the latest non-thread safe zip package with binaries of PHP from http://www.php.net/downloads.php.
- Unpack the files to a directory of your choice (e.g. C:\PHP). Rename the php.ini-recommended to php.ini.
- Open the php.ini file, then uncomment and modify settings as follows:
- Set fastcgi.impersonate = 1. FastCGI under IIS supports the ability to impersonate security tokens of the calling client. This allows IIS to define the security context that the request runs under.
- Set cgi.fix_pathinfo=1. cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI. PHP's previous behavior was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not care what PATH_INFO is. For more information on PATH_INFO, see the cgi specs. Setting this to 1 will cause PHP CGI to fix its paths to conform to the spec
- Set cgi.force_redirect = 0.
- Set open_basedir to point to a folder or network path where the content of the web site(s) is located.
- Set extension_dir to point to a location where PHP extensions reside. Typically, for PHP 5.2.X that would be set as extension_dir = "./ext"
- Enable the required PHP extension by un-commenting corresponding lines, for example:
extension=php_mssql.dll
extension=php_mysql.dll
- To test if the PHP installation is successful, run the following from the command line prompt:
C:\PHP>php –info
If PHP was installed correctly and all its dependencies are
available on the machine, then this command will output the current PHP
configuration information.
Configure IIS 7.0 to Handle PHP Requests
In order for IIS 7.0 to host PHP applications, it is necessary to
add a handler mapping that tells IIS to pass all PHP specific requests
to the PHP application framework via FastCGI protocol.
Using IIS Manager
Open IIS Manager and then select and open “Handler Mappings” at the server level:
Select the “Add Module Mapping” action and specify the configurations settings as below:
- Request path: *.php
- Module: FastCgiModule
- Executable: "C:\[Path to your PHP installation]\php-cgi.exe"
- Name: PHP via FastCGI
Click OK. A dialog box appears asking if you want to create a FastCGI application for this executable. Click Yes.
Test that the handler mapping works correctly by creating a
phpinfo.php file in the C:\inetpub\wwwroot folder that contains the
following code:
<?php phpinfo(); ?>
Open a browser and navigate to http://localhost/phpinfo.php. If everything was setup correctly, then you will see the standard PHP information page:
NOTE: If you do not see "FastCgiModule" in the
"Modules:" drop-down list then it means that the module is not
registered or not enabled. To check if FastCGI module is registered
open the IIS configuration file
%WINDIR%\windows\system32\config\applicationHost.config and check that
the following line is present in <globalModules> section:
<add name="FastCgiModule" p_w_picpath="%windir%\System32\inetsrv\iisfcgi.dll" />
Also, in the same file, check that the FastCGI module is added to the <modules> section:
<add name="FastCgiModule" />
Using command line
Alternatively, the above mentioned steps can be completed by using command line tool appcmd.
To create the FastCGI application process pool, run the following command:
C:\>%windir%\system32\inetsrv\appcmd set config /section:system.webServer/fastCGI /+[fullPath='c:\{php_folder}\php-cgi.exe']
After that, create the handler mapping:
C:\>%windir%\system32\inetsrv\appcmd
set config /section:system.webServer/handlers
/+[name='PHP_via_FastCGI',path='*.php',verb='*',modules='FastCgiModule',scriptProcessor='c:\{php_folder}\php-cgi.exe',resourceType='Unspecified']
Note: If you are using PHP version 4.X, instead of php-cgi.exe, you can use php.exe.
Best Practices for Configuring FastCGI and PHP
This download contains a summary presentation on Best Practices for hosting PHP in a shared hosting environment.
Security Isolation for PHP Web Sites
The recommendation for isolating PHP web sites in a shared hosting
environment is consistent with all general security isolation
recommendations for IIS 7.0. In particular, it is recommended to:
- Use one application pool per web site
- Use a dedicated user account as an identity for the application pool
- Configure anonymous user identity to use the application pool identity
- Ensure that FastCGI impersonation is enabled in the php.ini file (fastcgi.impersonate=1)
For more details about security isolation in a shared hosting environment, refer to Isolating Sites with Application Pools.
PHP Process Recycling Behavior
Make sure that FastCGI always recycles the php-cgi.exe processes
before the native PHP recycling kicks in. The FastCGI process recycling
behavior is controlled by the configuration property instanceMaxRequests.
This property specifies how many requests the FastCGI process will
process before recycling. PHP also has a similar process recycling
functionality that is controlled by an environment variable PHP_FCGI_MAX_REQUESTS. By setting instanceMaxRequests to be smaller or equal to PHP_FCGI_MAX_REQUESTS, you can ensure that the native PHP process recycling logic will never kick in.
The FastCGI settings can be configured either by using IIS Manager or by using the command line tool appcmd.
Using IIS manager
To configure FastCGI recycling settings by using IIS Manager, you need to install Administration Pack for IIS 7.0 and then select FastCGI settings at the server level:
Next select the FastCGI application that you want to configure and click "Edit..." in the Actions pane on right hand side:
In the "Edit FastCGI application" dialog, set instanceMaxRequest to 10000 and then click on the browse button next to the EnvironmentVariables setting:
Add the PHP_FCGI_MAX_REQUESTS environment variable and set its value to 10000:
Note: If you do not configure these settings, then the following default settings are used: instanceMaxRequests = 200, PHP_FCGI_MAX_REQUESTS = 500 (on most PHP builds).
Using command line
To configure the recycling behavior of FastCGI and PHP via appcmd, use the following commands:
C:\>%windir%\system32\inetsrv\appcmd
set config -section:system.webServer/fastCgi
/[fullPath='c:\{php_folder}\php-cgi.exe'].instanceMaxRequests:10000C:\>%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/fastCgi /+"[fullPath='C:\{php_folder}\php-cgi.exe'].environmentVariables.[name='PHP_FCGI_MAX_REQUESTS',value='10000']"
PHP Versioning
Many PHP applications may rely on functions or features available
only in certain versions of PHP. If such applications are to be hosted
on the same server then different PHP versions must be enabled and
running side-by-side. The IIS 7.0 FastCGI handler fully supports
running multiple versions of PHP on the same web server.
For example, let’s assume that on your web server you plan to
support PHP 4.4.8, PHP 5.2.1 and PHP 5.2.5 non-thread safe. To enable
that, you must place corresponding PHP binaries in separate folders on
the file system (e.g. C:\php448\, C:\php521\ and C:\php525nts) and then
create FastCGI application process pools for each version:
C:\>%windir%\system32\inetsrv\appcmd set config /section:system.webServer/fastCGI /+[fullPath='c:\php448\php.exe']C:\>%windir%\system32\inetsrv\appcmd set config /section:system.webServer/fastCGI /+[fullPath='c:\php521\php-cgi.exe']
C:\>%windir%\system32\inetsrv\appcmd set config /section:system.webServer/fastCGI /+[fullPath='c:\php525nts\php-cgi.exe']
Now, if you have 3 web sites (site1, site2, site3), where each site
needs to use a different PHP version, you can define handler mappings
on each of those sites to reference a corresponding FastCGI application
process pool.
Note: Each FastCGI process pool is uniquely identified by a combination of fullPath and arguments properties.
C:\>%windir%\system32\inetsrv\appcmd
set config site1 –section:system.webServer/handlers
/+”..[name=’PHP448_via_FastCGI’,path=’*.php’,verb=’*’,modules=’FastCgiModule’,scriptProcessor=’c:\php448\php.exe’,resourceType=’Either’]C:\>%windir%\system32\inetsrv\appcmd set config site2 –section:system.webServer/handlers /+”..[name=’PHP521_via_FastCGI’,path=’*.php’,verb=’*’,modules=’FastCgiModule’,scriptProcessor=’c:\php521\php-cgi.exe’,resourceType=’Either’]
C:\>%windir%\system32\inetsrv\appcmd set config site3 –section:system.webServer/handlers /+”..[name=’PHP525nts_via_FastCGI’,path=’*.php’,verb=’*’,modules=’FastCgiModule’,scriptProcessor=’c:\php525nts\php-cgi.exe’,resourceType=’Either’]
PHP Security Recommendations
The following settings can be used to tighten the security of a PHP
installation. To make the recommended changes locate and open the
php.ini file and edit the configuration settings as described below:
Setting | Description |
---|---|
allow_url_fopen=Off allow_url_include=Off |
Disable remote URLs for file handling functions, which may cause code injection vulnerabilities. |
register_globals=Off | Disable register_globals. |
open_basedir="c:\inetpub\" | Restrict where PHP processes can read and write on a file system. |
safe_mode=Off safe_mode_gid=Off |
Disable safe mode |
max_execution_time=30 max_input_time=60 |
Limit script execution time |
memory_limit=16M upload_max_filesize=2M post_max_size=8M max_input_nesting_levels=64 |
Limit memory usage and file sizes |
display_errors=Off log_errors=On error_log="C:\path\of\your\choice" |
Configure error messages and logging |
fastcgi.logging=0 | IIS FastCGI module will fail the request when PHP sends any data on stderr by using FastCGI protocol. Disabling FastCGI logging will prevent PHP from sending error information over stderr, and generating 500 response codes for the client. |
expose_php=Off | Hide presence of PHP |
Enabling per-site PHP configuration
The section describes the recommended way of enabling per-site PHP
configuration . Note that this recommendation was discovered and
validated by Radney Jasmin with hosting provider GoDaddy.com who now offers PHP hosting on Windows Server 2008 via FastCGI.
Per-site PHP process pools
When each web site has its own application pool (which is a
recommended practice on IIS 7.0), it is possible to associate a
dedicated FastCGI process pool with each web site. A FastCGI process
pool is uniquely identified by the combination of fullPath and arguments
attributes. So, if it is necessary to create several FastCGI process
pools for the same process executable, such as php-cgi.exe, the arguments
attribute can be used to distinguish process pools definitions. In
addition, with php-cgi.exe processes the command line switch "-d" can
be used to define an INI entry for PHP process. This switch can be used
to set a PHP setting that makes the arguments string unique.
For example, if there are two web sites "website1" and "website2"
that need to have their own set of PHP settings, the FastCGI process
pools can be defined as follows:
<fastCgi><application fullPath="C:\PHP\php-cgi.exe" arguments="-d open_basedir=C:\Websites\Website1" />
<application fullPath="C:\PHP\php-cgi.exe" arguments="-d open_basedir=C:\Websites\Website2" />
</fastCgi>
In this example the PHP setting open_basedir is
used to distinguish between process pool definitions. In addition it
enforces that the PHP executable for each process pool can perform file
operations only within the root folder of the corresponding web site.
Then website1 can have the PHP handler mapping as follows:
<system.webServer><handlers accessPolicy="Read, Script">
<add name="PHP via FastCGI" path="*.php" verb="*" modules="FastCgiModule" scriptProcessor="C:\PHP\php-cgi.exe|-d open_basedir=C:\Websites\Website1" resourceType="Unspecified" requireAccess="Script" />
</handlers>
</system.webServer>
and website2 can have the PHP handler mapping as follows:
<system.webServer><handlers accessPolicy="Read, Script">
<add name="PHP via FastCGI" path="*.php" verb="*" modules="FastCgiModule" scriptProcessor="C:\PHP\php-cgi.exe|-d open_basedir=C:\Websites\Website2" resourceType="Unspecified" requireAccess="Script" />
</handlers>
</system.webServer>
Specifying php.ini location
When the PHP process starts it determines the location of the configuration php.ini file by using various settings. The PHP documentation
provides detailed description of the PHP start up process. Note that
one of the places where PHP process searches for php.ini location is
the PHPRC environment variable. If PHP process finds a php.ini file in
the path specified in this environment variable then it will use it,
otherwise it will revert to default location of php.ini. This
environment variable can be used to allow hosting customers to use
their own versions of php.ini files.
For example if there are two websites: website1 and website2;
located at the following file paths: C:\WebSites\website1 and
C:\WebSites\website2 then the php-cgi.exe process pools in the
<fastCgi> section of applicationHost.config can be configured as
below:
<fastCgi><application fullPath="C:\PHP\php-cgi.exe" arguments="-d open_basedir=C:\Websites\Website1">
<environmentVariables>
<environmentVariable name="PHPRC" value="C:\WebSites\website1" />
</environmentVariables>
</application>
<application fullPath="C:\PHP\php-cgi.exe" arguments="-d open_basedir=C:\WebSites\Website2">
<environmentVariables>
<environmentVariable name="PHPRC" value="C:\WebSites\website2" />
</environmentVariables>
</application>
</fastCgi>
This way website1 can have its own version of php.ini in the
C:\WebSites\website1, while website2 can have its own version of
php.ini located in C:\WebSites\website2. This configuration also
ensures that if there is no php.ini found in location specified by
PHPRC environment variable then PHP will fall back to using the default
php.ini file located in the same folder where php-cgi.exe is located.