Apache Plus PHP-FPM

Created: 2021-11-06 Updated: 2021-11-08 (Improved organization of notes.)

These notes describe getting PHP-FPM and Apache working together for a simple example localhost installation.

Though my specific experience was on Slackware Linux, the instructions should be quite vanilla because Slackware doesn’t mess with upstream packages.

Packages

Slackware 14.2’s Apache and PHP packages (part of the default Slackware installation!) are:

$ find /var/log/packages/ -name 'http*' -o -name 'php*'
/var/log/packages/httpd-2.4.51-x86_64-1_slack14.2
/var/log/packages/php-5.6.40-x86_64-1_slack14.2

And PHP ships with PHP-FPM:

$grep php-fpm /var/log/packages/php-5.6.40-x86_64-1_slack14.2
etc/php-fpm.conf.default
etc/php-fpm.d/
etc/rc.d/rc.php-fpm.new
usr/man/man8/php-fpm.8.gz
usr/sbin/php-fpm

Run PHP-FPM on startup

# cd /etc/rc.d
# chmod +x php-fpm

# cat >> rc.local
if [ -x /etc/rc.d/rc.php-fpm ]; then
	/etc/rc.d/rc.php-fpm start
fi

# cat >> rc.local_shutdown
if [ -x /etc/rc.d/rc.php-fpm ]; then
	/etc/rc.d/rc.php-fpm stop
fi

# ./php-fpm start   # start it now
Starting php-fpm  done

Note: Documentation on PHP-FPM on php.net seems pretty threadbare, but since it seems to "just work", I guess that’s okay.

Apache configuration for PHP-FPM

Apache ships with the mod_proxy and mod_proxy_fcgi modules (the base module is required by the fastCGI module).

$ grep 'mod_proxy.so\|mod_proxy_fcgi.so' httpd-2.4.51-x86_64-1_slack14.2
usr/lib64/httpd/modules/mod_proxy.so
usr/lib64/httpd/modules/mod_proxy_fcgi.so

Apache documentation (excellent):

There are a ton of ways to setup the fCGI proxy, but this one suited a simple test on my local computer:

# /etc/httpd/httpd.conf

LoadModule proxy_module lib64/httpd/modules/mod_proxy.so
LoadModule proxy_fcgi_module lib64/httpd/modules/mod_proxy_fcgi.so

<VirtualHost localhost:80>
	ProxyPassMatch "" "fcgi://127.0.0.1:9000/home/dave/mytest/router.php
</VirtualHost>

The ProxyPassMatch <uri regex> <remote proxy> directive is set above to pass everything to a router.php script.

I later fine-tuned it to my (again, simple) needs. Specifically by having static file requests filtered out in the URI regex and adding a DocumentRoot directive so the static files could be served directly by Apache:

# PHP-FPM
LoadModule proxy_module ${modpath}/mod_proxy.so
LoadModule proxy_fcgi_module ${modpath}/mod_proxy_fcgi.so

<VirtualHost localhost:80>
	DocumentRoot /home/dave/mytest
	<LocationMatch "^/">
		ProxyPassMatch "fcgi://127.0.0.1:9000/home/dave/mytest/router.php"
	</LocationMatch>
	<LocationMatch "^/static">
		ProxyPassMatch "!"
	</LocationMatch>
</VirtualHost>