Candid photograph of a Linux server terminal with a soft olive-green glow against a dark slate background, conveying a calm technical atmosphere.

Step-by-step guides for system administrators — covering command-line basics, web server setup, and preparation material for technical interviews.

Browse Tutorials

Install PHP-FPM with Apache on RHEL

PHP-FPM provides a fast, process-managed way to run PHP applications behind Apache on Red Hat Enterprise Linux. Apache handles HTTP requests, while PHP-FPM processes dynamic PHP files through FastCGI. This arrangement suits WordPress, Laravel, custom PHP sites, and internal applications hosted on RHEL servers.

The procedure applies to RHEL 8 and RHEL 9 with minor package-stream differences. It is suitable for a VPS in Sydney, Melbourne, Brisbane, or another Australian data centre, where predictable service restarts and clear firewall rules are important during local AEST business-hours maintenance windows.

Select And Install The PHP Packages

Confirm that the server is registered and that the required repositories are enabled. List the available PHP module streams before installing anything, because the supported version can vary between RHEL releases and subscription repositories.

sudo dnf module list php
sudo dnf module enable php:8.2 -y

Use an available, supported stream rather than copying 8.2 if it is not shown on your system. Install Apache, PHP-FPM, and commonly required extensions:

sudo dnf install -y httpd php php-fpm php-cli php-common \
  php-mysqlnd php-gd php-mbstring php-opcache

The php-fpm package supplies the service and its pool configuration. php-cli is useful for command-line checks, while php-mysqlnd, php-gd, and php-mbstring are frequently required by content management systems and frameworks.

Configure The PHP-FPM Pool

Open the default FPM pool configuration:

sudo vi /etc/php-fpm.d/www.conf

Set the pool to use a Unix socket owned by Apache:

user = apache
group = apache

listen = /run/php-fpm/www.sock
listen.owner = apache
listen.group = apache
listen.mode = 0660

A Unix socket avoids exposing PHP-FPM on a network port. Keep the default pool limits initially, then adjust pm.max_children, pm.start_servers, and related values after reviewing memory usage and application traffic. An Australian WordPress site serving visitors in several time zones may need different worker limits from a small intranet used only during Sydney office hours.

Start both services and enable them at boot:

sudo systemctl enable --now php-fpm
sudo systemctl enable --now httpd
sudo systemctl status php-fpm httpd

Connect Apache To PHP-FPM

Create a dedicated Apache configuration file:

sudo vi /etc/httpd/conf.d/php-fpm.conf

Add the following directives for the standard document root:

<FilesMatch \.php$>
    SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost"
</FilesMatch>

DirectoryIndex index.php index.html

Apache uses its FastCGI proxy support to pass PHP requests to the FPM socket. Check the configuration before reloading the service:

sudo apachectl configtest
sudo systemctl reload httpd

Create a temporary test script:

echo '<?php phpinfo();' | sudo tee /var/www/html/info.php
curl http://127.0.0.1/info.php

A PHP information page confirms that Apache and PHP-FPM are communicating. Remove it immediately afterwards because it reveals loaded modules, paths, environment values, and version details:

sudo rm -f /var/www/html/info.php

For WordPress administrators, a separate WordPress QA resource can help when checking application behaviour after changing the PHP runtime or web server stack.

Apply Permissions, SELinux, And Firewall Rules

RHEL enables SELinux by default, so preserve its protection rather than disabling it to solve a permissions problem. Restore the expected file labels on the web root:

sudo restorecon -Rv /var/www/html

For a custom document root, label static content appropriately:

sudo semanage fcontext -a -t httpd_sys_content_t '/srv/www(/.*)?'
sudo restorecon -Rv /srv/www

Writable upload or cache directories may require the httpd_sys_rw_content_t type, but grant it only to directories that genuinely need web-server write access. Keep application files owned by a deployment account where possible, with Apache receiving read access through group permissions.

Allow HTTP and HTTPS through firewalld:

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

Do not open TCP port 9000 when FPM listens on the local Unix socket. If the server is hosted with an Australian provider, also check the provider’s security group or network firewall, since cloud-level filtering can block traffic even when firewalld is correctly configured.

Verify Operation And Review Logs

Test locally and through the server’s DNS name:

curl -I http://127.0.0.1
sudo journalctl -u php-fpm -u httpd --since "10 minutes ago"
sudo tail -f /var/log/httpd/error_log

A 503 Service Unavailable response commonly indicates that PHP-FPM is stopped, the socket path differs from the Apache configuration, or the socket permissions prevent Apache from connecting. Check the socket directly:

sudo ls -l /run/php-fpm/www.sock
sudo ss -lx | grep php-fpm

After confirming normal requests, inspect PHP-FPM’s pool settings and Apache’s access logs under realistic load. Kernel and network-level tuning should be treated separately from PHP configuration; this sysctl hardening guide provides relevant background for securing the wider RHEL host.

The essential arrangement is simple: Apache serves web traffic, PHP-FPM executes PHP through a protected local socket, SELinux labels enforce access boundaries, and firewalld exposes only the services the application needs. Save the working configuration, remove diagnostic files, and remember that correct service ownership and socket permissions are as important as the package installation itself.