Installing PHP-FPM with Apache

Submitted by Eric on Thu, 03/29/2018 - 21:20

Many people prefer to use nginx, but for Magento it makes no difference since the PHP process is the big villain and not static content.
Right after the installation of Magento we have a large amount of PHP files:

find . -type f -name "*.php" | wc -l

Total 8.112.

Some reasons to use PHP-FPM with Apache:

  • You want the performance and flexibility of FPM;
  • You want to run PHP as the user who owns the code (not Apache) to avoid permission problems;
  • You need to use .htaccess files;
  • You prefer the support and experience with Apache and do not want to use nginx.

Let's now install, the tutorial was done with RHEL / CentOS, but can be changed to any distro.

Installing FPM:

yum install php-fpm

By default you will have FPM running as apache and configured in the file /etc/php-fpm.d/www.conf.You may need to configure multiple files per domain and user so that you do not have permission problems.
Let's configure the FPM pool to run over the socket instead of TCP over port 9000.
Also configure the user and permission for the socket, usually the same as the sFTP user.

Execute the commands below:

cd /etc/php-fpm.d
cp www.conf usuario.conf 
mv www.conf www.conf.disabled 
vim usuario.conf

Make the following changes:

;listen =
listen = /dev/shm/usuario-php.sock

listen.owner = usuario = apache
listen.mode = 0660

user = usuario

pm.max_children = 100
pm.start_servers = 35
pm.min_spare_servers = 35

php_admin_value[error_log] = /var/log/php/
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 512M

Installing mod_fastcgi:

We need to install fastcgi to communicate with FPM, there are not many packages available so we have the option of compiling or using a version made by Nexcess where a but of Magento with CGI has been fixed where it duplicates headers causing a 500 error:
… aborted: error parsing headers: duplicate header ‘Content-Type’

Let's use the Nexcess rpm to do the installation, execute the commands below:

yum -y install httpd-devel rpm-build -y
mkdir -p /~/fastcgi
cd /~/fastcgi
rpmbuild --rebuild mod_fastcgi-2.4.6-3.el6.src.rpm
rpm -ivh /~/rpmbuild/RPMS/x86_64/mod_fastcgi-2.4.6-3.el6.x86_64.rpm
rm -f /etc/httpd/conf.d/mod_fastcgi.conf

Configuring mod_fastcgi:
Create the file/etc/httpd/conf.d/mod_fastcgi.conf with the content below. Change where user is typed to the user you configured to run the code. For multiple pools, add more FastCGIExternalServer directives.

LoadModule fastcgi_module modules/
<IfModule mod_fastcgi.c>
Alias /php5.fcgi /var/www/php5.fcgi

FastCGIExternalServer /var/www/php5.fcgi -socket /dev/shm/someuser-php.sock -flush -idle-timeout 1800

AddType application/x-httpd-fastphp5 .php
Action application/x-httpd-fastphp5 /php5.fcgi

Disable mod_php:
Run the following command to disable mod_php:

mv /etc/httpd/conf.d/php.conf /etc/httpd/conf.d/php.disabled
echo "# mod_php disabled, using mod_fastcgi with PHP-FPM instead" >> /etc/httpd/conf.d/php.conf

PHP-FPM is very good with the use of memory. When your site has multiple visits to the site, run the following command:

for pid in $(ps aux | grep fpm | grep "pool www" | awk '{print $2}'); do pmap -d $pid | tail -1 ; done | sed 's/K//' | awk '{sum+=$4} END {print sum/NR/1024}'

The command will show the average usage in MB of each FPM process for the www pool. Change to the pool with the name that you created to have the correct answer. This way you can predict the memory usage of your PHP.