The Perfect LAMP Stack – Apache2, FastCGI, PHP-FPM, APC
So, what could be ideal setup which can cover these issues? What and how we can install Apache, PHP and others which can provide good performance and remain stable even within high loads.
In the following guide, we will be using some best technologies and interweave them to make a perfect LAMP installation.
Note: May be some of you people advise me that Nginx installation can be much more efficient then the Apache one but I have made this setup because of certain modules which were only available with Apache and there were no alternatives in Nginx for them.
Let us begin now:
1. Linux – The following installation instructions can be run over on all the linux flavors available today as we would be building everything from the source, However, FYI my webserver uses CentOS 5.3.
Learn More: The Advantages of Choosing Linux Webhosting
2. Apache2 HTTP server – Apache HTTP server has always been an industry standard webserver and been a first choice among the webhosting guys as a webserver solution. It is stable, easy to extend, customizable and efficient. We will be using Apache 2.2 for our perfect setup. You can obtain the latest version of Apache2 from http://httpd.apache.org/download.cgi
Learn More: Apache at your Web Service
3. FastCGI – FastCGI is just a variation of CGI interface which allows you to delegate your HTTP requests from webserver to the application. But the difference between FastCGI and CGI is that, the CGI is tied to the life of HTTP requests. CGI has to start and stop between each HTTP request cycle whereas using FastCGI, your application lives forever. The requests come from the HTTP server to FastCGI which only do the serving of response. With this architecture, a number of requests and responses can be served without loading the application every time.
In our setup, we will use FastCGI module for the Apache HTTP webserver. You can download it from http://www.fastcgi.com/dist/mod_fastcgi-current.tar.gz
Learn More: FastCGI – The Forgotten Treasure
4. PHP-FPM – PHP-FPM is a recent alternative implementation of PHP with FastCGI. It is actually the patches over the PHP source and allows you to have built-in FastCGI process management right inside in PHP. As of now, PHP-FPM is about to go into the core of PHP project in 5.3.3 and is currently under development. So in our installation, we will patch the PHP 5.2 source with PHP-FPM patches.
We will be using PHP 5.2.13 source and PHP-FPM 0.5.14 patch. You can download PHP from http://www.php.net/get/php-5.2.13.tar.gz/from/a/mirror and PHP-FPM from http://php-fpm.org/downloads/php-5.2.13-fpm-0.5.14.diff.gz
Learn More: PHP-FPM Home
4. PHP-APC – The Alternative PHP Cache (APC) is the robust, fast and efficient way of optimizing and caching PHP intermediate code (opcode). We will finally use this one, as an improving performance alternative. We will use the stable version and you can grab it from http://pecl.php.net/get/APC-3.0.19.tgz
Learn More: PHP-APC Official Manual
Lets Roll it now
We will assume that you have already downloaded the required packages on you server. To confirm, there would be following archives on your system after downloading.
httpd-2.2.15.tar.gz php-5.2.13.tar.gz mod_fastcgi-current.tar.gz php-5.2.13-fpm-0.5.4.diff.gz APC-3.0.19.tgz
Compile Apache httpd server
Run the following commands to build Apache httpd server. The below commands will
1. Unzip the httpd-2.2.15.tar.gz archive.
2. The plain configure command will configure the Apache source with default settings based on your server configuration. If you require to install additional modules or parameters, please refer to Apache httpd documentation.
3. Finally make all install command will build the Apache httpd server on your server.
tar xvzf httpd-2.2.15.tar.gz cd httpd-2.2.15 ./configure make all install
Compile mod_fastcgi module for Apache2
Apparently it is always advisable to install Apache modules as static objects, we will still be installing mod_fastcgi as a Dynamic Shared Object (DSO) for Apache2. I have tried hard to compile as a static library but failed to do so, so if anyone else was able to, please share with me.
Execute the following commands to build mod_fastcgi for Apache2
tar xvzf mod_fastcgi-current.tar.gz cd mod_fastcgi-2.4.6 apxs -o mod_fastcgi.so -c *.c apxs -i -a -n fastcgi mod_fastcgi.so
Note: If you are unable to compile the module and getting errors, it is most likely that the apxs is not found. In that case please refer to exact path to apxs and then compile the module.
Before building PHP, we would patch the PHP source with the PHP-FPM patches and will continue with the installation.
Execute the following commands
tar xvzf php-5.2.13.tar.gz gzip -cd php-5.2.13-fpm-0.5.4.diff.gz | patch -d php-5.2.13 -p1 cd php-5.2.13 ./configure --enable-fastcgi --enable-fpm --with-mysql=/var/lib/mysql --with-mysqlsock=var/lib/mysql/mysql.sock --with-zlib --with-zlib-dir --withgd --with-bz2 --enable-zip --with-curl=/usr/include --with-gettext --with-config-file-path=/usr/local/apache2/conf --enable-ftp --with-ttf --enable-mbstring --with-openssl --enable-soap --enableshmop --enable-sockets --with-pear=/usr/local/php --with-pdo-mysql --with-libdir=lib64 --with-png-dir --with-pcre-regex make all install cp php.ini-dist /usr/local/apache2/conf/php.ini
The above commands will patch the PHP source with PHP-FPM. If you notice, the configure command has two new parameters –enable-fastcgi and –enable-fpm. These parameters will enable the FastCGI process management in PHP. The other parameters are only for reference. You can add/remove any other parameter which you want to build with your PHP. If you get errors during the configure, it might be the reason that the dependency is not installed on your system. In that case, install the dependencies and rerun the configure command.
The last command will copy the PHP configuration file php.ini to the apache configuration directory and we have also referred to the same location during the compilation of PHP (–with-config-file-path=/usr/local/apache2/conf). The advantage of doing it is, all the configuration files are located at the same place on your webserver.
At the last, now we will build APC for our PHP setup. Run the following commands
tar xvzf APC-3.0.19.tgz cd APC-3.0.19 phpize ./configure --enable-apc --enable-apc-mmap --with-apxs=/ usr/local/apache2/bin/apxs --with-php-config=/usr/local/bin/php-config make make install cp modules/apc.so /usr/local/lib/php/extensions/apc.so
The phpize command will prepare the build environment for the PHP extension. To use APC with PHP on Apache requires the apxs for compilation. At the end, we copied the apc.so extension to the PHP extensions location. The same path is referred in php.ini file against extension_dir directive. If it is any other in your case, you can copy the apc.so to that location.
Finishing the job
So far we are complete with the installation of required components for our LAMP stack. Now we will configure the settings for them and will be done.
Following are the required configuration files which we will be editing:
/usr/local/apache2/conf/httpd.conf /usr/local/apache2/conf/php.ini /usr/local/etc/php-fpm.conf
The following parameters should exists in httpd.conf to make Apache aware about FastCGI and PHP-FPM
User apache Group apache LoadModule fastcgi_module modules/mod_fastcgi.so <IfModule mod_fastcgi.c> ScriptAlias /fcgi-bin/ "/usr/local/apache2/fcgi-bin/" FastCGIExternalServer /usr/local/apache2/fcgi-bin/php-cgi -host 127.0.0.1:9000 –pass-header Authorization AddHandler php-fastcgi .php Action php-fastcgi /fcgi-bin/php-cgi </IfModule>
In the above configurations, LoadModule directive would include the mod_fastcgi module into the Apache. The <IfModule> wrapper can also be located in /usr/local/apache2/conf/extra/httpd-vhosts.conf. The settings inside <IfModule> will be explained at the end of the post.
Following directives should be present and uncommented in php-fpm.conf file
<value name="owner">apache</value> <value name="group">apache</value> <value name="mode">0644</value> <value name="user">apache</value> <value name="group">apache</value>
Create a folder fcgi-bin inside /usr/local/apache2 folder and copy the php-cgi from /usr/local/bin to that location
mkdir /usr/local/apache2/fcgi-bin cp /usr/local/bin/php-cgi /usr/local/apache2/fcgi-bin/ chown -R apache: /usr/local/apache2/fcgi-bin chmod -R 755 /usr/local/apache2/fcgi-bin
What we have done above is, copied the php-cgi executable into fcgi-bin folder so that the PHP application can use it for processing the HTTP requests coming to the application.
The PHP-FPM configurations enforce that the process spawned due the requests coming to PHP FastCGI server should be accessed only by apache user or group. This is a good security model because it would not allow external user to access internal resources through PHP scripts.
Now, we can start our server and let it serve our applications efficiently.
php-fpm start /usr/local/apache2/bin/apachectl start
To share some details, the above setup has given a performance improvement of around 150% for a complex Zend Framework application which we were running in a setup of two application servers with one dedicated MySQL server and one hardware load balancer. I hope this can benefit you too.
If you had any questions, please feel free to ask.