decorative image for blog that shows how to use apache with phpfpm and modphp
December 20, 2023

How to Use Apache HTTPD With php-fpm and mod_php

PHP Development

PHP and web servers go hand in hand, and luckily there are several options for integrating PHP into your web server of choice. Today, we'll be looking at two popular options for integrating PHP into Apache HTTPD — mod_php and PHP-FPM — and walk through the actual integration process for both options.

Back to top

Integrating PHP Within Web Servers 

While you can use PHP from the command line, PHP was developed with the web in mind, and is generally expected to integrate with a web server. The most commonly used web server when using PHP is Apache HTTPD; together, the two make up the "A" and "P" in the LAMP stack, which largely popularized and democratized serving dynamic websites in the early days of the internet.

Originally, you had two choices for integrating PHP with Apache HTTPD: via Common Gateway Interface (CGI) or mod_php (the PHP module for Apache HTTPD). CGI was the original mechanism for providing dynamic content to a web server, and it defines how a web server passes on request information to the binary that will process it. CGI was a wonderful technology at first, as it essentially allowed building handlers for any language. However, web servers would then need to execute a process for every single request; this could lead to lengthy processing times, high CPU usage, and increased memory usage, particularly if the server received a lot of requests.

Apache HTTPD's module system allowed language to provide a mechanism for running a worker pool that the web server would then pass requests to. This solution meant there was less time spent spinning up the runtime, as it would already be in memory, and having multiple workers meant that there was better CPU and memory management. However, such modules were specific to Apache HTTPD, and you could generally only load one version of a runtime at any given time. This meant that if you wanted to run multiple versions of PHP, you would actually need to spin up multiple Apache HTTPD instances.

Later, a third option came along: FastCGI. FastCGI builds on CGI by allowing for parallel, persistent processes. Unlike Apache HTTPD modules, however, the processes are not part of the web server, but external; it is up to the language runtime to provide a way to manage worker pools. This approach means that you can start and stop your worker pool without stopping the web server (which means that static content can still be served), provides the CPU and memory benefits of having a persistent process (like mod_php provided), and, further, allows you to run multiple pools side-by-side, providing the ability to have different versions of a runtime running on the same web server.

Back to top

What Is PHP-FPM?

php-fpm is the PHP FastCGI Process Manager; it provides FastCGI worker pools for PHP.

Like CGI and mod_php, it is delivered in the PHP project as a Server API; it is one of the ways to integrate PHP with other servers, such as Apache HTTPD. You can configure multiple pools for a given PHP version, run pools from different PHP versions side-by-side, and configure pools with their own settings and environment variables, which allows for application-specific pools.

Back to top

Comparing mod_php to php-fpm

There are some key differences between mod_php and php-fpm that you should note when you choose between the two (more on that later). In the charts below, we detail the features/benefits of each option.

mod_php Features and Benefits

mod_php Features/BenefitsDescription
Tight IntegrationEmbeds the PHP interpreter directly into the Apache web server process, providing tight integration and potentially reducing overhead.
Simplified ConfigurationGenerally easier to set up and configure compared to external FastCGI processes like PHP-FPM.
Ease of DeploymentRequires less configuration and setup, making it easier to deploy for simple PHP applications or in environments where simplicity is prioritized.
Shared MemoryShares memory space between Apache and PHP, which can lead to faster communication and data exchange compared to separate processes.
Simplicity for Small SitesWell-suited for small websites or development environments where ease of setup and simplicity are more critical than advanced features.
Resource EfficiencyCan be more resource-efficient for certain workloads and setups, especially when running on a server with limited resources.

php-fpm Features and Benefits

Features and BenefitsDescription
Improved PerformanceFastCGI interface enhances PHP performance. Manages a pool of PHP processes for simultaneous request handling.
Resource ManagementEfficiently manages server resources to prevent exhaustion. Allows control over process count, priority, and recycling.
Isolation and SecurityProvides process isolation for enhanced security. Supports user and group permissions for each PHP process pool.
ScalabilityHandles a large number of simultaneous connections and requests. Allows administrators to configure the number of child processes dynamically.
Dynamic Process ManagementAdjusts the number of PHP processes based on server load. Optimizes resource usage and adapts to changing traffic patterns.
Health Monitoring and Status PageProvides a status page for monitoring PHP process health. Includes information on active processes, requests, and resource usage.
Graceful Process RestartAllows the graceful restart of PHP processes without interrupting active requests. Ensures a smooth transition during updates or configuration changes.
Customization and ConfigurationOffers a wide range of configuration options for fine-tuning settings. Enables optimal performance in diverse server environments.
Back to top

Using Apache HTTPD with mod_php

The following steps will enable mod_php with your Apache HTTPD server. They assume that (a) you have installed Apache HTTPD already, (b) that you installed it using your system package manager, and (c) you are using a PHP build packaged for your operating system (whether that's the one bundled with the OS, or ZendPHP).

Step 1: Install mod_php

Installing mod_php will vary based on the OS and the source of the PHP package.

On Debian-based systems:

  • The system mod_php package is generally called libapache2-mod-php
  • ZendPHP versions are named libapache2-mod-php{PHP_VERSION}-zend

On RPM-based systems:

  • mod_php is installed by default when installing the system "php" package.
  • When using ZendPHP, you will install php{PHP_VERSION}zend (e.g. yum install php74zend)

Tip: on ZendPHP, use zendphpctl to install mod_php:

zendphpctl apache mod_php install 7.4

This usage is the same regardless of the operating system.

Step 2: Add PHP Files to Your Document Root

At this point, everything is ready to go. The packages for installing mod_php automatically enable the module for Apache HTTPD, and it's configured to work with .php and .phtml files. Dropping PHP files with these extensions into the document root of your server (or a configured virtual host) will recognize them and execute them using mod_php.

Back to top

Using Apache HTTPD with PHP-FPM

Configuring php-fpm and setting up Apache HTTPD to use it requires a bit more effort than mod_php, so there are more steps for this option. Just as with using Apache HTTPD with mod_php, these steps assume: (a) you have installed Apache HTTPD already, (b) that you installed it using your system package manager, and (c) you are using a PHP build packaged for your operating system (whether that's the one bundled with the OS, or ZendPHP).

Note: you do not actually need to have Apache HTTPD on the same machine as the one where you run your php-fpm pool! Because php-fpm can expose itself via a TCP socket, it's possible to do that on one machine, and then have Apache HTTPD consume php-fpm from another. This is a great way to isolate your PHP servers from the web server!

Step 1: Install php-fpm

Installing php-fpm varies based on the OS and the source of the PHP package.

On Debian-based systems:

  • The system php-fpm pacakge is generally called php-fpm
  • The ZendPHP repo names them php{PHP_VERSION}-zend-fpm (e.g. php8.2-zend-fpm)

On RPM-based systems:

  • The system php-fpm package is generally called php-fpm
  • The ZendPHP repo names it php{PHP_VERSION}zend-php-fpm (e.g. php82zend-php-fpm)

On ZendPHP, use zendphpctl to install php-fpm:

zendphpctl fpm install 7.4

This usage is the same regardless of the operating system.

 

Tip: You can install more than one php-fpm version at a time!

Step 2: Configure Your php-fpm Pool(s)

php-fpm provides the ability to configure behavior for all pools, as well as individual pools. Generally speaking, each OS provides a php-fpm.conf configuration file that defines system-wide settings for the php-fpm daemon, and this in turn includes files under a subdirectory, where settings for individual pools are defined.

On Debian-based systems, you'll find this configuration under /etc/php/{PHP_VERSION}/fpm/ (e.g. /etc/php/7.4/fpm). The only difference for ZendPHP is that the PHP version will have a "-zend" suffix: /etc/php/7.4-zend/fpm/. In all cases, the pool settings are found in a pool.d/ subdirectory: e.g., /etc/php/7.4/fpm/pool.d/www.conf

On RPM-based systems, the locations vary a bit more. For the system php-fpm, you will find the main php-fpm configuration at /etc/php-fpm.conf, with pool configuration in /etc/php-fpm.d/. For ZendPHP, this configuration goes into /etc/opt/zend/php{PHP_VERSION}zend/ (e.g. /etc/opt/zend/php74zend/).

The configuration files are well-documented, and the sample pool configuration file provided is generally sufficient to get started. The primary setting you will want to take note of is the listen directive, which will be found in a pool configuration file. This can be either a path to a Unix socket (e.g. listen = /var/run/php/7.4-fpm.sock) or a TCP port (e.g., listen = 127.0.0.1:9000, listen = 0.0.0.0:9000, or listen = 9000). You will need to make note of this setting, as it will be used when configuring Apache HTTPD to use it.

When using a Unix socket, the web server must be on the same machine in order to communicate with php-fpm. When using a TCP port, the web server must be able to reach the IP address, and the port must be exposed to the server running the web server instance; make sure your firewalls are set up correctly.

Step 3: Start the php-fpm Service

At this point, it's time to start your php-fpm service.

On Debian-based systems, how you start will vary based on whether you are using systemd or not. If you are using systemd, you will start the php-fpm service. This can be done using sudo systemctl start php{PHP_VERSION}-fpm. If you are not using systemd, or want to manually start it, run sudo /usr/sbin/php-fpm{PHP_VERSION}. (Omit the version when not using the ZendPHP repo.)

On RPM-based systems, you also have a choice between using systemd or not. Run sudo systemctl start php-fpm or sudo php-fpm.

Step 4: Configure Apache to Use Event Workers

By default, Apache HTTPD uses a "prefork" process for handling requests. As a request comes in to the server, it spawns a new process, up to a configured limit. This works well for mod_php and for other languages, but can be consume a lot of resources in other scenarios.

The recommendation when using FastCGI is to switch to using the event process manager. This allows for parallel processing of requests, and ensures a process is always available. It is not recommended for mod_php, as it keeps the process in memory, and requires thread-safe versions of runtimes in order to deal with concurrency issues. Since PHP does not play well with concurrency, it doesn't work well; however, with FastCGI, the FastCGI pool determines how to handle incoming requests, and php-fpm spawns new workers, resolving those concurrency issues.

On Debian-based systems, you can run sudo a2dismod mpm_prefork, followed by sudo a2enmod mpm_event.

On RPM, to switch from the prefork to the event process manager, you will need to edit the file /etc/httpd/conf.modules.d/00-mpm.conf. Comment out the line reading LoadModule mpm_prefork_module modules/mod_mpm_prefork.so, and uncomment the line LoadModule mpm_prefork_module modules/mod_mpm_event.so. When done, restart httpd.

Step 5: Configure Apache HTTPD to Talk to php-fpm

At this point, it's time to configure the web server to talk to php-fpm.

In a virtual host definition, you will add the following:

# Enable http authorization headers
# This is required due to differences between how CGI and PHP expect to receive these headers
SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1

<FilesMatch \.php$>
# If you are using a TCP port, use the following format
# replacing the IP and port as needed:
SetHandler "proxy:fcgi://127.0.0.1:9000"

# If you are using a Unix socket, use the following format,
# rewriting the path to the socket to match your php-fpm configuration
SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost"
</FilesMatch>

Once done, restart your web server.

Step 6: Add PHP Files to Your Document Root

At this point, everything is ready to go. The packages for installing mod_php automatically enable the module for Apache HTTPD, and it's configured to work with .php and .phtml files. Dropping PHP files with these extensions into the document root of your server (or a configured virtual host) will recognize them and execute them using mod_php.

Back to top

How to Choose Between mod_php and php-fpm

When would you use mod_php, and when would you use php-fpm?

Clearly, mod_php is easier to setup than php-fpm. Additionally, most benchmarks show that mod_php has a performance edge over php-fpm, though it's not a large one, and the benchmarks vary based on how each is configured.

So why would you want to use php-fpm?

First, if you want to have multiple PHP versions side-by-side, php-fpm is the only way to accomplish this. While this is relatively rare, it can be useful when you are migrating from one PHP version to the next; you can gradually move parts of the application from one vhost to the other as you get them successfully migrated, or you can do A/B testing to randomly use different configurations and see what breaks. Additionally, if you are serving multiple websites from the same web server, and each application has different PHP version needs, this is a solution that will get you there.

Second, there are security benefits to using php-fpm. Since each pool can have its own configuration, you can run each application using a different system user, and these can in turn be different than what Apache HTTPD uses as well. This can help prevent privilege escalation or access to restricted areas of the filesystem, which could reduce information disclosure.

Third, and extending on the previous point, because php-fpm can listen on TCP sockets, you can have your php-fpm pools on entirely different servers! This means that even if there is a breach in your PHP application, the attacker cannot gain access to the web server at all, and may not even be able to get beyond the network to which the PHP application is attached. You also get another benefit: you can have each application on its own server, but behind the same Apache HTTPD instance. This means if one application is receiving heavier traffic, you can continue to serve other applications quickly, improving overall performance. The other benefit is when you are using containers: you can serve the web server and PHP applications in separate containers, allowing you to bring services up and down without affecting one another.

Back to top

Final Thoughts

Today we've taken a look at how to integrate PHP into your Apache HTTPD server using both mod_php and php-fpm, and detailed the key features and benefits for both options. As detailed above, the biggest considerations for choosing between the two boil down to usability, performance, configurability, and security, with mod_php being the clear choice for overall usability and performance, and php-fpm having an edge in configurability and security. 

Ultimately, your choice in using mod_PHP vs php-fpm should match your application needs for performance and security. Both mod_PHP and php-fpm can, and do, work well when used correctly.

Deploying EOL PHP?

Keep it secure with PHP LTS (or PHP migration services) from Zend. Explore what we offer today via the links below.

Explore PHP LTS See Service Options

Additional Resources

Back to top