Switch from mod_php to php-fpm on Apache
Table of Contents
Before you start using PHP-FPM, let me briefly explain what CGI(Common Gateway Interface), mod_php, and FastCGI are:
-
CGI - Back in the day, CGI enabled a Web Server to execute programs like binaries or scripts(e.g bash, php, python). Upon each client request the server would have to spawned a new CGI process to execute a particular program, or script by calling its interpreter, then the CGI process will capture the result, send it to the server, and then the server will deliver the response. Creating a new process upon each request can be expensive. CGI could also be the entry point of a remote code execution, if you don’t know what you’re doing. A very popular one is the Shellshock bug.
-
mod_php - To overcome the drawbacks of CGI,
mod_php
was created for Apache. Withmod_php
enabled, PHP is embedded in Apache. The communication between Apache and PHP is much faster but still, there are some disadvantages.mod_php
is called on each client request, even if the content is static or just plain HTML. Much more memory is being used without processing PHP. And it forces you to use MPM Pre-Fork. Even with a cache proxy, it’s not the ideal solution. -
FastCGI: FastCGI is not a newer version of CGI, but a whole new protocol rewritten from scratch to address the limitations of CGI. It’s not embedded in the server anymore. It’s a standalone handler that can process multiple requests simultaneously. Since it’s a listener or handler of requests, you have to give your web server instruction where to locate it. These days, each Web Server(like Apache, Nginx) have their own version of FastCGI. The original one is not available anymore.
What is PHP-FPM and Event MPM #
PHP-FPM or PHP FastCGI Process Manager is an implementation of the old FastCGI, designed specifically for PHP. And with the combination of MPM Event, high traffic endpoints are easier to handle while using less resources.
Apache will need mpm_event
,mod_proxy
, and mod_proxy_fcgi
enabled in order to communicate with PHP-FPM.
Seting up the Environment #
mpm_event
, and mod_proxy
is available by default. You’ll need to install php-fpm, and libapache2-mod-fcgid.
First, stop apache2
, and disable php
, and, mpm_prefork
:
$ systemctl stop apache2
$ a2dismod php7.4 mpm_prefork
Enable mpm_event
:
$ a2enmod mpm_event
Install both php-fpm
, and libapache2-mod-fcgid
:
$ apt install php-fpm libapache2-mod-fcgid
Enable mod_proxy
, and proxy_fcgi
:
$ a2enmod proxy proxy_fcgi
php-fpm
is not a module but a service or handler on its own. To make it available, we need to enable its configuration:
$ a2enconf php7.4-fpm
Upon the activation of the configuration file, you can see that php-fpm
is already running:
root@debian:~# ls -l /var/run/php/php*
lrwxrwxrwx 1 root root 30 Aug 31 15:57 /var/run/php/php-fpm.sock -> /etc/alternatives/php-fpm.sock
-rw-r--r-- 1 root root 5 Aug 31 15:57 /var/run/php/php7.4-fpm.pid
srw-rw---- 1 www-data www-data 0 Aug 31 15:57 /var/run/php/php7.4-fpm.sock
root@debian:~# ps aux | grep www-data
www-data 10088 0.0 0.3 7696 3780 ? S 15:57 0:00 /usr/sbin/apache2 -k start
www-data 10090 0.0 0.6 753920 6420 ? Sl 15:57 0:00 /usr/sbin/apache2 -k start
www-data 10091 0.0 0.6 753920 6420 ? Sl 15:57 0:00 /usr/sbin/apache2 -k start
www-data 11162 0.0 0.8 196804 8572 ? S 15:57 0:00 php-fpm: pool www
www-data 11163 0.0 0.8 196804 8572 ? S 15:57 0:00 php-fpm: pool www
The handler is set automatically in /etc/apache2/conf-enabled/php7.4-fpm.conf
:
SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost"
Now start apache2
and run a configtest
:
root@debian:~# systemctl start apache2
root@debian:~#
root@debian:~#
root@debian:~# apache2ctl configtest
Syntax OK
root@debian:~#
Verify if the required modules are indeed enabled:
root@debian:~# apache2ctl -M | egrep -i "mpm|proxy"
mpm_event_module (shared)
proxy_module (shared)
proxy_fcgi_module (shared)
Then restart apache2
:
$ systemctl restart apache2
A simple start is not enough. A restart is required for the changes to take effect.
Verify with php_info() #
Let’s call php_info()
, and confirm if the Server API
, and Loaded Configuration File
is using FPM. Run the following:
root@debian:~# echo "<?php phpinfo(); ?>" > /var/www/html/info.php
Browse to yourIP/info.php
or use curl
:
$ curl -s localhost/info.php | egrep "Server API|Loaded" | grep -i fpm | sed 's/<[^>]*>//g'
Server API FPM/FastCGI
Loaded Configuration File /etc/php/7.4/fpm/php.ini
or lynx
:
$ lynx localhost/info.php
PHP logo
PHP Version 7.4.21
System Linux debian 5.10.0-8-amd64 #1 SMP Debian 5.10.46-4 (2021-08-03) x86_64
Build Date Jul 2 2021 03:59:48
Server API FPM/FastCGI
Virtual Directory Support disabled
Configuration File (php.ini) Path /etc/php/7.4/fpm
Loaded Configuration File /etc/php/7.4/fpm/php.ini
Don’t forget to remove info.php
once you’re done.
Act as if what you do makes a difference. It does.
- William James