contact

Loading enum info ...

Debian PHP5 fastcgi

Index

About this document
Installing needed packages
Enabling needed apache2 modules
Change configuration files
Create user and wrapper script
Test the setup
Some extra tips for the setup to speedup things

About this document

In this article we will describe how we did our Debian Apache2+PHP5+fastcgi setup.
This is by no means THE way to do it, it's just how we did it and it works great in production.
We choose fastcgi because this gives us control over who has php access and we can run
different websites with a different set of php configs without too much trouble.
For example, we still have some applications that need the infamous register_globals setting enabled.

Installing needed packages

For this setup we need apache2, php5-cgi, fastcgi, and suexec. On Debian this can be installed with:

aptitude install apache2-mpm-worker php5-cgi libapache2-mod-fastcgi libapache2-mod-fcgid 

Enable needed apache2 modules

By default, not all the modules for apache2 are enabled. To make this work correctly we need:
suexec - to run the php cgi as it's own user.
fastcgi - to make php stay in memory and spawn a php session manager
actions - to link files with the php extension to the fastcgi php manager
headers - to send the browser some nice extra headers and to allow header manipulation from fastcgi
include - not sure why, but it seems to work better with this one enabled
To enabled them all:

# a2enmod suexec
# a2enmod fastcgi
# a2enmod actions
# a2enmod headers
# a2enmod include

 

Change configuration files

The default configuration files are by no means suitable for running this kind of setup.

First, let us optimize the fastcgi configuration to run our PHP workers. For this make sure your /etc/apache2/mods-enabled/fastcgi.conf looks like this:

<IfModule mod_fastcgi.c>
FastCgiWrapper /usr/lib/apache2/suexec
FastCgiConfig -pass-header HTTP_AUTHORIZATION -autoUpdate -killInterval 120 -idle-timeout 110
FastCgiIpcDir /var/lib/apache2/fastcgi
</IfModule mod_fastcgi.c>

This will use the correct wrapper for the fastcgi manager (this is actuallly the default in Debian, but it can't hurt to state it here)
It will also allow websites with HTTP authentication and it will recycle idle workers after 120 seconds

Now we will specify the location of the wrapper script and some other fastcgi
directives that are true for all php sites. That's why we want them globally and the best place to do so is in /etc/apache2/httpd.conf. Make sure it looks like this(any own configuration can be left untouched):

# fastcgi with suexec needs the cgi script in the webroot
ScriptAlias /cgi-bin /var/www/cgi-bin/
<Directory /var/www/cgi-bin/>
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
# Link our wrapperscript to fastcgi
<Location /cgi-bin/php5-fcgi>
SetHandler fastcgi-script
</Location>
# We are running php applications as user/group fcgi
SuexecUserGroup "fcgi" "fcgi"
# Define an action to run on files with handler php5-fastcgi
Action php5-fastcgi /cgi-bin/php5-fcgi
# We put this here for the correct mimetype headers
AddType application/x-httpd-php .php
# for serverwide php access set this here
# otherwise put this line in every VirtualHost that needs php access
AddHandler php5-fastcgi .php

As you can see fastcgi+suexec need the wrapperscript to be in the documentroot.
We also define this as a scriptalias, afterall it's still a cgi. Therefore you will have toremove the scriptalias from the default VirtualHost configuration in /etc/apache2/sites-enabled/000-default.
We removed both the ScriptAlias line as the block from that file.

Create user and wrapper script

We are going to run our php applications as user fcgi for more security.
Add this user to the system without entering anything as the password. That way nobody will be able to login
to this system using that useraccount.

adduser fcgi

Now create the wrapperscript that will actually attach PHP as a handler for fastcgi:

vim /var/www/cgi-bin/php5-fcgi

Make the file look like this:

#!/bin/sh
# Configuration directory
PHPRC="/etc/php5/cgi"
export PHPRC
# How much children per manager
PHP_FCGI_CHILDREN=4
export PHP_FCGI_CHILDREN
# How much requests should be queued per child
PHP_FCGI_MAX_REQUESTS=5
export PHP_FCGI_MAX_REQUESTS
# What binary to run with above settings
exec /usr/lib/cgi-bin/php5

make this chown fcgi:fcgi and chmod 755

Test the setup

Create a file called phpinfo.php in /var/www with the following content:

<?php
phpinfo();
?>

Start apache with: /etc/init.d/apache2 start

Point your browser to http://ip.of.webserver.box/phpinfo.php
If all is well you will see the phpinfo page

Run ps afx on the webserver.
The output shoud be like:

21073 ?        Ss     0:00 /usr/sbin/apache2 -k start
21074 ? S 0:00 \_ /usr/sbin/apache2 -k start
21075 ? S 0:00 \_ /usr/sbin/fcgi-pm -k start
21134 ? Ss 0:00 | \_ /usr/lib/cgi-bin/php5
21135 ? S 0:00 | \_ /usr/lib/cgi-bin/php5
21136 ? S 0:00 | \_ /usr/lib/cgi-bin/php5
21137 ? S 0:00 | \_ /usr/lib/cgi-bin/php5
21138 ? S 0:00 | \_ /usr/lib/cgi-bin/php5
21076 ? Sl 0:00 \_ /usr/sbin/apache2 -k start
21078 ? Sl 0:00 \_ /usr/sbin/apache2 -k start

Notice how everything php related is located as childprocess of the fcgi-pm.
If this is not the case review your configuration files and check them against the lines above.

That should be it. Now it's time to create webapplications.

Some extra tips for the setup to speedup things

To make fastcgi and PHP cache objects in memory you can use apache2's mem_cache module.
Enable it with:
# a2enmod mem_cache
It will probably tell you it enabled the module cache as well. If it tells you this module was already loaded, don't worry.
Now edit the file /etc/apache2/mods-enabled/mem_cache.conf to give it a little more memory to store objects in:

<IfModule mod_mem_cache.c>
CacheEnable mem /
MCacheSize 32768
MCacheMaxObjectCount 2000
MCacheMinObjectSize 1
MCacheMaxObjectSize 2048
</Ifmodule>

To make transfer times a bit smaller we can enable mod_deflate. This will zip the output before it leaves the server.
All modern browsers understand this kind of content so why shouldn't we save both time and bandwidth:

# a2enmod deflate

The default does zip too much. We need to tell it what files to zip and what the compression level is.
We found out compression level 1 is a very good one. Almost no extra CPU load (around 0.5% an a normal CPU and medium traffic) and still it saves a lot of bandwidth. Here's the content of the /etc/apache2/mods-enabled/deflate.conf:

<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript
Header set Vary *
DeflateCompressionLevel 1
</IfModule>

Adding an opcode cache to PHP can speedup things even more. This is left as excersice to the reader.

 



 Feedback on this page or article:

This article has no feedback yet

 Give feedback:

To give feedback on this article, click here
Copyright (c) 2006-2008 Michiel van Baak.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU Free Documentation License".
< back | print | text | Debian PHP5 fastcgi