Speeding up Apache with php-fpm

Apache ships using a load-handling model that is not recommended for production servers. This also uses the mod_php method of running PHP, and can be heavy on memory use.

Speeding up Apache involves 2 changes:

  1. Changing the process model
  2. Using php-fpm instead of mod_php
Notes:
  • These changes will affect all websites powered by your server or VM, not only your ZendTo site.
  • I have not written any steps for how to revert the change.
    So snapshot or backup your server/VM before you start.


Step by Step Guides

Ubuntu / Debian based systems

First, you need to find your PHP version. Run the command
php --version
to find out the first 2 numbers of the PHP version number. We're not interested in the 3rd one. It should be something like "7.4".

In these commands, remember to replace 7.4 with the appropriate PHP version number for your system:

a2dismod php7.4
a2dismod mpm_prefork
a2enmod mpm_event
a2enmod proxy_fcgi
apt install php-fpm
a2enconf php7.4-fpm
apt purge libapache2-mod-php7.4

Sadly this will have destroyed the ZendTo PHP settings in php.ini, so you need to re-apply those changes. The most accurate way of doing this is to use a single part of the ZendTo Installer.

  1. Fetch and unpack the ZendTo Installer:
    curl -O https://zend.to/files/install.ZendTo.tgz
    tar xzf install.ZendTo.tgz
  2. Run one part of it:
    cd install.ZendTo/Ubuntu-Debian
    ./5-httpd-php.sh

    That won't overwrite your Apache configuration at all, it will just fix the PHP settings.
  3. Restart Apache and the php-fpm server:
    systemctl restart php7.4-fpm
    systemctl restart apache2

Important Notes:

  • This will change where PHP errors are logged. They are no longer logged in /var/log/apache2 but now in /var/log/php-fpm.
  • If you change your PHP configuration, you need to "systemctl restart php7.4-fpm", and not restart Apache. Restarting Apache will change nothing.

CentOS / RedHat based systems

First, you need to find your PHP version. Run the command
rpm -qa | grep 'php.*-common'
That will output a line something like
php72u-common-7.2.31-2.el7.ius.x86_64
It is just the "php72u" that you need to remember. The "72" may well be a different number for your system.

In the following steps, remember to replace php72u with the appropriate value for your system.

  1. Install php-fpm and remove mod_php:
    yum install php72u-fpm
    systemctl enable php-fpm
    yum remove mod_php72u
  2. Edit /etc/php-fpm.d/www.conf:
    1. Change "user" setting to "user = apache"
    2. Change "group" setting to "group = apache"
    3. Comment out "listen = 127.0.0.1:9000"
    4. Uncomment "listen = /run/php-fpm/www.sock"
    5. Uncomment "listen.acl_users = apache"
  3. Start php-fpm:
    systemctl start php-fpm
  4. Create the file /etc/httpd/conf.d/php-fpm.conf and put this into it:
    #
    # The following lines prevent .user.ini files from being viewed by Web clients.
    #
    <Files ".user.ini">
        Require all denied
    </Files>
    #
    # Allow php to handle Multiviews
    #
    AddType text/html .php
    #
    # Add index.php to the list of files that will be served as directory
    # indexes.
    #
    DirectoryIndex index.php
    #
    # Cause the PHP interpreter to handle files with a .php extension.
    #
    <Files "*.php">
      <If "-f %{SCRIPT_FILENAME}">
        SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://127.0.0.1:9000"
      </If>
    </Files>
  5. Edit /etc/httpd/conf.modules.d/00-mpm.conf:
    1. Comment out the line "LoadModule mpm_prefork_module modules/mod_mpm_prefork.so"
    2. Uncomment the line "LoadModule mpm_event_module modules/mod_mpm_event.so"
  6. Restart Apache:
    systemctl restart httpd

Important Notes:

  • This will change where PHP errors are logged. They are no longer logged in /var/log/apache2 but now in /var/log/php-fpm.
  • If you change your PHP configuration, you need to "systemctl restart php-fpm", and not restart Apache. Restarting Apache will change nothing.